【问题标题】:C# Odata v4 open type raw valuesC# Odata v4 开放类型原始值
【发布时间】:2017-10-20 06:34:25
【问题描述】:

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

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

但我不知道如何使用 ~/Person('uid')/foo/$value 之类的 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);
}

【问题讨论】:

  • ~/Person('uid')?$select=foo 就足够了吗?
  • 很遗憾,没有,因为除非在技术上尚不可行(我无法回答这个问题),客户期望使用非动态属性的“经典”语法

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


【解决方案1】:

@Max Xapi

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

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

很简单,只需几个步骤:

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

我创建了一个您可以参考的示例,请参阅提交 here。如果有任何进一步的问题,请告诉我,希望对您有所帮助。

问候,

-山姆

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 2015-05-24
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多