序列化 – JSON.NET作为WebAPI 2 OData序列化程序与ODataMediaTypeFormatter

我试图使用 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集合中
var 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()方法的项目中,因为这个类是内部的.

相关文章

AJAX是一种基于JavaScript和XML的技术,能够使网页实现异步交...
在网页开发中,我们常常需要通过Ajax从后端获取数据并在页面...
在前端开发中,经常需要循环JSON对象数组进行数据操作。使用...
AJAX(Asynchronous JavaScript and XML)是一种用于创建 We...
AJAX技术被广泛应用于现代Web开发,它可以在无需重新加载页面...
Ajax是一种通过JavaScript和HTTP请求交互的技术,可以实现无...