C#Odata v4开放式原始值

时间:2017-10-20 06:34:25

标签: c# asp.net-web-api odata

我有一个包含动态属性的简单开放类型:

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(&#39; uid&#39;)/ foo这样的网址 - 感谢他们的密钥和这种方法:

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"
}

但我无法弄清楚如何获取这些属性的原始值,使用像〜/ Person(&#39; uid&#39;)/ foo / $ value

这样的网址

如果我尝试一下,结果就是这个:

{
    "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);
}

1 个答案:

答案 0 :(得分:2)

@Max Xapi

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

但是,您可以自己解决方法来完成它。

这很简单,只有几个步骤:

  1. 创建自己的路由约定。
  2. 创建动态属性值映射
  3. 将路由约定和动态属性值映射插入配置。
  4. 我创建了一个可以参考的示例,请参阅提交here。请让我知道任何进一步的问题,并希望它可以提供帮助。

    此致

    萨姆