2017-10-20 63 views
0

我有一个包含动态特性,简单的开放型:C#的OData v4的开放型原始值

public class Person { 
    [Key] 
    public string Uid { get; set; }  
    public IDictionary<string, object> DynamicProperties { get; set; } 
} 

在我的控制,我填的这些特性是这样的:

public IHttpActionResult Get([FromODataUri] string key) { 
    Person person; 
    // ... 
    person.DynamicProperties.Add("foo", "foo_value"); 
    person.DynamicProperties.Add("bar", "bar_value"); 
    // ... 
    return this.Ok(person); 
} 

我可以计算如何通过一个类似〜/ Person('uid')/ foo的URL来请求这些属性 - 感谢他们的密钥和此方法:

public IHttpActionResult GetDynamicProperty([FromODataUri] string key, [FromODataUri] string dynamicProperty) { 
    Person person; 
    // ... 
    // (string) for the example 
    return this.Ok((string)person.DynamicProperties[dynamicProperty]); 
} 

结果是这样的:

{ 
    "@odata.context": "http://myServer/$metadata#Person('uid')/foo", 
    "value": "foo_value" 
} 

但我想不出如何获取这些属性的原始值,与像〜/人(“UID”)/富/ $值的URL

如果我尝试一下,结果是这样的:

{ 
    "error": { 
     "code": "", 
     "message": "No HTTP resource was found that matches the request URI 'http://myServer/Person('uid')/foo/$value'.", 
     "innererror": { 
      "message": "No routing convention was found to select an action for the OData path with template '~/entityset/key/dynamicproperty/$value'.", 
      "type": "", 
      "stacktrace": "" 
     } 
    } 
} 

我该如何路由以访问这些原始值?还是有一种方法或其他方法可以处理它?

- Sam Xu的回答

感谢您的例子后编辑,它就像一个魅力。我已经按照你的点1和2点3个样品,如果它可以帮助别人,这是一个典型的Web API的注册方法的改编版:

public static void Register(HttpConfiguration config) { 
    // Custom routing for dynamic attributes raw values 
    var routings = ODataRoutingConventions.CreateDefault(); 
    routings.Insert(0, new DynamicRawValueRoutingConvention()); 
    // Our model 
    ODataModelBuilder builder = new ODataConventionModelBuilder(); 
    builder.EntitySet<Person>("Person"); 
    // ... 
    // Old way 
    //config.MapODataServiceRoute(
    // routeName: "myDefaultRouteName", 
    // routePrefix: null, 
    // model: builder.GetEdmModel() 
    //); 
    // New way with Sam's samples 
    config.MapODataServiceRoute(
     "myDefaultRouteName", 
     null, 
     configureAction => 
     configureAction.AddService(ServiceLifetime.Singleton, sp => builder.GetEdmModel()).AddService<IEnumerable<IODataRoutingConvention>>(ServiceLifetime.Singleton, sp => routings) 
    ); 
    var formatters = ODataMediaTypeFormatters.Create(); 
    foreach (var oDataMediaTypeFormatter in formatters) { 
     oDataMediaTypeFormatter.MediaTypeMappings.Insert(0, new ODataDynamicValueMediaTypeMapping()); 
    } 
    config.Formatters.InsertRange(0, formatters); 
} 
+0

会'〜/人( 'UID')?$选择= foo'是否足够呢? – GWigWam

+0

不幸的是没有,因为除非技术上不可行,否则(我无法回答这个问题),客户期望使用非经典动态属性的“经典”语法 –

回答

2

@Max XAPI

OData没有内置逻辑来支持$value动态属性。

但是,您可以自行解决方法来实现它。

很简单,只有几个步骤:

  1. 创建你自己的路由规则。
  2. 创建动态属性值映射
  3. 将路由约定和动态属性值映射插入到配置中。

我创建了一个您可以参考的示例,请参阅提交here。请让我知道任何进一步的问题,并希望它可以帮助。

问候,

萨姆