使用ASP.Net MVC 5和Web API 2.0在OData中进行字典<string,object>序列化

Gus*_*dim 3 c# asp.net odata asp.net-web-api asp.net-mvc-5

我正在使用OData服务而不是新的Web API for MVC 5,我遇到了一些问题.

我已经按照本教程开始开发OData服务,几乎一切都是正确的.项目构建,路线工作,URL工作得很好.

我的一个类被调用Post并具有一个Dictionary<string, object>名为的属性Parameters,如下所示:

public partial class Post : IPost
{
    public Guid Id { get; set; }

    public string Author{ get; set; }  
    public string Content{ get; set; }  
    public DateTime PostedDate{ get; set; }  
    public List<Photo> Pictures { get; set; }  

    public Dictionary<string, object> Parameters { get; set; }  
}
Run Code Online (Sandbox Code Playgroud)

当我在浏览器中执行get请求时,列出所有Post对象(http://localhost/odata/Posts)的URL 工作正常.所有对象都已成功序列化.

但是在另一个应用程序中导入OData元数据作为服务引用,当我获得Post实体列表时,我得到以下错误:

Microsoft.Data.OData.dll中出现"System.InvalidOperationException"类型的异常,但未在用户代码中处理

附加信息:类型"WebApplication1.ServiceReference2.System.Collections.Generic.KeyValuePair_2OfString_Object"没有可设置的属性.

如何成功解决导入服务引用的此问题?

Gus*_*dim 7

几天后,我尝试了很多不同的测试.

  • Dictionary<string, object> =>抛出原始错误
  • Dictionary<string, string> =>同样的错误
  • List<KeyValuePair<string, object>> =>同样的错误
  • List<KeyValuePair<string, string>> =>同样的错误

我意识到KeyValuePair课程是问题,但我不知道为什么.

所以,我创建了一个名为Parameter如下的类:

public class Parameter
{
    public string Key { get; set; }
    public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...我将列表类型更改为List<Parameter>并且工作正常!

在更多地思考这个问题之后,我意识到错误中有一个重要的句子:

'WebApplication1.ServiceReference2.System.Collections.Generic.KeyValuePair_2OfString_Object' 没有可设置的属性

字典只不过是KeyValue对的列表,而KeyValuePair<TKey, TValue>struct有两个属性,名为"Key"和"Value",它们只有get访问器.所以,他们是只读的.

我们可以得出结论,OData服务参考不能反序列化只读属性,由于某些原因我还不知道.

我的解决方法有效,但我想知道服务引用是否有一天可能有反映方式来设置此属性.


Alf*_*ter 7

对于自 2015 年以来阅读本文的任何人:OData V4 支持开放类型:https://learn.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/ odata-v4/在 odata-v4 中使用开放类型

你的字典应该是这样的类型:

IDictionary<string, object>.

然后,Odata 将为您创建一个开放类型。