我试图使用
JSON.NET作为WebAPI 2堆栈中的默认序列化程序.我已经实现了JsonMediaTypeFormatter,其中我已经使用JSON.NET serializer进行序列化/反序列化数据,并创建了JsonContentNegotiator来使用此媒体类型格式化程序.除了OData查询之外,所有功能都正常工作 – 如果我添加[Queryable]元数据操作方法,则响应对象不包含任何元数据信息,仅包含实体列表.
小例子我的行动方法:
[Queryable] public async Task<PageResult<RuleType>> GetRuleType(ODataQueryOptions<RuleType> options) { var ret = await _service.ListRuleTypesAsync(options); return new PageResult<RuleType>( ret,Request.GetNextPageLink(),Request.GetInlineCount()); }
如果我使用默认OData序列化,并按规则类型(例如 – … / odata / RuleType?$inlinecount = allpages& $skip = 0& $top = 1)调用某些查询,我将收到带有元数据信息的经典OData响应,计数属性:
odata.Metadata ".../odata/$Metadata#RuleType" odata.count "2" value 0 { Id: 1 Name: "General" Code: "General" Notes: null }
(有些字段被跳过,但是我的Notes属性为null值)
但是,如果我添加JsonContentNegotiator与JsonMediaTypeFormatter作为一个序列化程序 – 我只收到实体列表:
[ { "Id": 1,"Name": "General","Code": "General" } ]
(没有Notes字段,因为NullValueHandling.Ignore)
更.如果我删除动作方法中的[Queryable]属性 – 我收到另一个结果:
{ "Items": [ { "Id": 1,"Code": "General" } ],"Count": 2 }
在这种情况下,我收到了Count,但是在这里仍然没有元数据. odata响应属性名称与默认值完全不同.
我的头脑正在吹起来我只想使用JSON.NET作为我的Web应用程序的任何部分的序列化程序(由于一些强大的限制).我该怎么做?
我已经弄清楚了我的问题,找到了解决方案. OData使用独立的媒体类型格式化器,从ODataMediaTypeFormatter继承. OData也使用不同的格式化器进行序列化和反序列化.为了替换这个行为,我们必须实现ODataDeserializerProvider和/或ODataSerializerProvider类的后代,并将这些类添加到HttpConfiguration.Formatters集合中
原文链接:https://www.f2er.com/json/288516.htmlvar odataFormatters = ODataMediaTypeFormatters .Create(new MyODataSerializerProvider(),new MuODataDeserializerProvider()); config.Formatters.AddRange(odataFormatters);
小反序列化提供商示例:
public class JsonODataDeserializerProvider : ODataDeserializerProvider { public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType) { var kind = GetODataPayloadKind(edmType); return new JsonODataEdmTypeDeserializer(kind,this); } private static ODataPayloadKind GetODataPayloadKind(IEdmTypeReference edmType) { switch (edmType.TypeKind()) { case EdmTypeKind.Entity: return ODataPayloadKind.Entry; case EdmTypeKind.Primitive: case EdmTypeKind.Complex: return ODataPayloadKind.Property; case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); return collectionType.ElementType().IsEntity() ? ODataPayloadKind.Feed : ODataPayloadKind.Collection; default: return ODataPayloadKind.Entry; } } public override ODataDeserializer GetODataDeserializer(IEdmModel model,Type type,HttpRequestMessage request) { var edmType = model.GetEdmTypeReference(type); return edmType == null ? null : GetEdmTypeDeserializer(edmType); } }
ODataDeserializer:
public class JsonODataEdmTypeDeserializer : ODataEdmTypeDeserializer { public JsonODataEdmTypeDeserializer(ODataPayloadKind payloadKind) : base(payloadKind) { } public JsonODataEdmTypeDeserializer(ODataPayloadKind payloadKind,ODataDeserializerProvider deserializerProvider) : base(payloadKind,deserializerProvider) { } public override object Read(ODataMessageReader messageReader,ODataDeserializerContext readContext) { var data = readContext.Request.Content.ReadAsStringAsync().Result; return JsonConvert.DeserializeObject(data,type); } }
而且我也从WebAPI OData源代码添加了EdmLibsHelper类,在GetEdmTypeReference()和GetEdmtype()方法的项目中,因为这个类是内部的.