我一直在努力寻找一个自定义序列化过去2个月从OData控制器返回的实体的解决方案!请帮忙!!!

用例非常简单,我已经简化了它以解决问题点.我有一些虚拟字段附加到我的模型中的某些实体,例如:

public class Customer
{
    public int CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string VirtualField1 { get; set; }
    public string VirtualField2 { get; set; }
    public string VirtualField3 { get; set; }
}

现在,假设客户端已将VirtualField1配置为“CompanyName”.
我想要做的就是创建一个自定义JSON序列化器和反序列化器:

>对客户的任何GET请求(当然还有客户 – 即IQueryable<>)将通过此序列化程序,如果每个客户都有一个集合,它将用“CompanyName”替换字段“VirtualField1”的名称.
>任何POST请求都将通过相反的替换 – 即 – 将“CompanyName”替换为“VirtualField1”.
**实际的替换逻辑有点复杂,但想法是一样的.

我已经阅读了谷歌本可以找到的所有内容,但找不到任何有效的例子.
以下是一些链接:
https://aspnetwebstack.codeplex.com/wikipage?title=OData%20formatter%20extensibility
**现在的OData API有点不同,但我认为原理是一样的.
customizing odata output from asp.net web api
Using OData in webapi for properties known only at runtime

所有链接的常见(以及我发现的任何信息)是我必须从DefaultODataSerializerProvider继承并将其添加到我的格式化程序:

在WebApiConfig.cs上:

var customFormatters = ODataMediaTypeFormatters.Create(new CustomODataSerilizerProvider(),new CustomODataDeSerilizerProvider());
       config.Formatters.InsertRange(0,customFormatters);

和实际的提供者和序列化器:

public class CustomODataSerilizerProvider : DefaultODataSerializerProvider
 {
    public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
    {
        if (edmType.IsEntity())
        {
            return new CustomODataEntityTypeSerializer(edmType.AsEntity(),this);
        }

        return base.GetEdmTypeSerializer(edmType);
    }
 }

**对于IQueryable结果,edmType.IsEntity()永远不会为true,因此它永远不会创建具体的序列化程序.如果我强制创建它仍然不会在CreateEntity(或任何其他创建方法)上中断.

public class CustomODataEntityTypeSerializer : ODataEntityTypeSerializer
  {
    public CustomODataEntityTypeSerializer(IEdmEntityTypeReference entityType,ODataSerializerProvider serializerProvider)
        : base(serializerProvider)
    {
    }

    public override ODataEntry CreateEntry(SelectExpandNode selectExpandNode,EntityInstanceContext entityInstanceContext)
    {
        var oDataEntry = base.CreateEntry(selectExpandNode,entityInstanceContext);
        return oDataEntry;
    }
 }

如果我将具体的序列化程序更改为从ODataCollectionSerializer继承:

public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
    {

        if (edmType.IsCollection())
        {
            return new CollectionSerilizer(this);
        }

        return base.GetEdmTypeSerializer(edmType);
    }

public class CollectionSerilizer : ODataCollectionSerializer
{
    public CollectionSerilizer(ODataSerializerProvider serializerProvider) : base(serializerProvider)
    {
    }

    public override ODataCollectionValue CreateODataCollectionValue(IEnumerable enumerable,IEdmTypeReference elementType,ODataSerializerContext writeContext)
    {
        var oDataCollectionValue = base.CreateODataCollectionValue(enumerable,elementType,writeContext);
        return oDataCollectionValue;
    }

    public override void WriteObject(object graph,Type type,ODataMessageWriter messageWriter,ODataSerializerContext writeContext)
    {
        base.WriteObject(graph,type,messageWriter,writeContext);
    }
}

它确实在WriteObject上的断点处停止但是不起作用并且基础正在抛出:
“指定为集合的项类型的类型’Models.Customer’不是原始的或复杂的.ODataCollectionWriter只能写出原始值或复数值的集合.”

另一个有趣的事情是,即使我插入所谓的默认提供商:

var customFormatters = ODataMediaTypeFormatters.Create(new DefaultODataSerializerProvider(),new DefaultODataDeserializerProvider());
        config.Formatters.InsertRange(0,customFormatters);

无论他们的立场如何,也就是在开头:

config.Formatters.InsertRange(0,customFormatters);

或者最后:

config.Formatters.AddRange(customFormatters);

OData功能 – 例如:$exapnd,如/ odata / Customers?$expand =图像完全消失,根本不起作用(这里是响应):

[{"Images":[],"CustomerId":1,"FirstName":"Bla","LastName":"Bla","VirtualField1":null]

尽管没有添加自定义格式化程序,但此实例中的图像未展开.

任何想法,想法,方向???

解决方法

回答可能为时已晚,但我注意到,当涉及到OData V1-3和OData V4时微软OData工具包之间的序列化时,可用性存在显着差异.

我认为你正在使用V4,因为我也试图获得DefaultODataSerializerProvider的挂起,并且没有成功.

然后我开始了一个新的Web Api项目,为OData V1-3添加了所有NuGet包,添加了一个Web Api OData控制器,并立即成功进行任何形式的序列化定制.

这是因为OData V1-3与自定义MediaTypeFormatters一起工作,就像WebApi一样.在那之后它变得像饼一样容易.

我不会插入关于此的代码,因为使用MediaTypeFormatter的示例很多,如下所示:
http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

好吧,你会失去一些V4功能:
http://www.asp.net/web-api/overview/releases/whats-new-in-aspnet-web-api-22#OData

但是我确信你可以在没有严格的V4 oasis实施的麻烦的情况下生活,微软以一种比你更圣洁的方式遵循. (可能因为这是他们开始的东西).

V4中最重要的功能:
支持OData模型中的别名属性

>谁在乎.

支持ODataConventionModelBuilder中的ComplexTypeAttribute,AssociationAttribute,TimesTampAttribute和ConcurrencyCheckAttribute

>你不需要它们.

提供为行动提供友好标题的能力

>谁在乎.

与ODL UriParser集成

>我不明白.

支持枚举,遏制和单身

>你不需要那个.

支持原始类型的转换

>你不需要那个.

添加了OData功能支持

>这是不幸的,但通过在OData旁边使用普通的ApiController可以轻松解决.

支持函数调用的参数别名

>你不需要它,无论如何都很麻烦.

支持模型中的驼峰案例命名约定

>很高兴它有支持,但我建议不要这样做.

支持$filter中的cast()

>不需要它.

支持开放复杂类型

>是啊?您有自定义序列化.您可以序列化您想要的任何类型.

删除了EntitySetController和AsyncEntitySetController

>好摆脱.

将$link更改为$ref

>好的

添加了属性路由支持

>不幸的是,您仍然坚持使用您在WebApiConfig中定义的路线.很重要.

问问自己,你在使用OData是为了什么?
我显然不能代表您的情况,但我会对您的用例进行分析:
– 您试图允许通过http向数据源发出复杂问题,因为您不希望每次客户端N想出新问题时都更改界面.
– 您正在尝试允许客户端请求他/她获取的数据的实际格式. CSV? XML? JSON?电子名片?哎呀,奥特? PDF?

如果这两个目标是你真正想要实现的目标,那就坚持使用V3.你将为自己省去一大堆痛苦,实现你的领域模式.

虽然我0.02美元.

json – OData序列化的更多相关文章

  1. ios – CGPath和UIBezierPath()有什么区别?

    目前,我正在努力制作一个自定义按钮,我有一个图像,并具有坐标,但我发现您可以通过使用CGPath类或UIBezierPath创建一个按钮/对象类.有人可以告诉我两者有什么区别?解决方法CGPath是CoreGraphics库的不透明类型,而UIBezierPath是UIKit中的Obj-C类.UIBezierPath是一个围绕CGPath的包装,具有更加面向对象的界面和一些方便的方法.使用CGPath可能会略微更快,因为它不必经过Obj-C,并且它具有更高级的功能,如CGPathApply.重要的是,UI

  2. swift 快速奔跑的兔几 本节的内容是:序列化与反序列化

    在cocoa中,我们经常需要向磁盘保存数据块,cocoa将这些数据块表示为NSData对象例如,有一个字符串,将其转换为NSData,可以使用如下方法:我们还可以将对象转化为数据。遵守协议NSCoding的对象可以转换为NSData对象,也可以从NSData对象中加载,方法如下:

  3. Swift中一个类中的枚举enum类型的数据该如何实现序列化NSCoder

    简述昨天在开发中遇到了这样一个问题,需要用NSUserDefaults持久化一些数据,其中需要保存一个自己定义的类对象。结束其实枚举本来就是一个Int,因此我们将其声明为Int型就可以根据Int值初始化了,以此实现序列化和反序列化。

  4. swift json的序列化和反序列化

    还有一点东西没写完,权作笔记参考:http://www.hangge.com/blog/cache/detail_983.html

  5. Swift中对象序列化的实现

    Swift中对象序列化的实现在swift中要使某个类可以序列化,只需要类实现NSCoding协议,并实现协议中的一个必要的构造函数和一个方法,分别对应序列化和反序列化的二个过程。

  6. Alamofire 4.0 迁移指南

    原文:Alamofire4.0MigrationGuide作者:cnoon译者:kemchenj译者注:最近打算把公司项目迁移到Swift3.0,顺手把Alamofire4.0的迁移指南翻译了,之前虽然读过一部分源码,但还是看到了很多新东西,新的Adapter和Retrier我都打算用到项目里,希望大家看完也能够有收获.Alamofire4.0是Alamofire最新的一个大版本更新,一个基于Sw

  7. [HandyJSON] 在Swift语言中处理JSON - 转换JSON和Model

    而HandyJSON是其中使用最舒服的一个库,本文将介绍用HandyJSON来进行Model和JSON间的互相转换。而HandyJSON另辟蹊径,采用Swift反射+内存赋值的方式来构造Model实例,规避了上述两个方案遇到的问题。所以我们要定义一个Mapping函数来做这两个支持:就这样,HandyJSON完美地帮我们进行了JSON到Model类的转换。把Model转换为JSON文本HandyJSON还提供了把Model类序列化为JSON文本的能力,简直无情。

  8. 数组 – 在swift中存储对数组的引用

    我错过了一些允许我这样做的Swift构造吗?你必须使用NSArray或NSMutableArray,因为SwiftArrays是值类型,所以任何赋值都会复制.

  9. android – 如何在Realm for Java中将RealmObject序列化为JSON?

    也就是说,使用RealmObject并将其序列化为JSON?它还应该序列化该对象内的任何RealmList.解决方法来自英国的基督徒在这里.RealmforAndroid目前没有任何此类方法,虽然核心数据库实际上支持JSON序列化,所以现在你要么必须手动操作,要么使用像GSON这样的第三方工具然而).

  10. android – GSON反序列化自定义对象数组

    我正在尝试使用GSON在Android中序列化/反序列化JSON.我有两个类看起来像这样:和:我正在使用GSON来序列化/反序列化数据.我像这样序列化:这将生成如下所示的JSON:我这样反序列化:我打电话的时候收到错误.我不知道这个错误意味着什么.我不认为自己做了任何严重的错误.有帮助吗?解决方法将您的代码更改为:使用Interfaces是一个很好的做法,GSON要求.Gson将javascript中的数组“[]”转换为LinkedList对象.在您的代码中,GSON尝试在_users字段中注入一个Lin

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部