繁体   English   中英

具有OData和实体框架的Web API-序列化问题

[英]Web API with OData and Entity Framework - Serialization Issue

在我的Web API应用程序中,如果我在Get方法中使用OData来过滤结果,则会得到不一致的结果。 没有OData过滤器,结果很好。 使用OData时,序列化处理是否有所不同? 我这样做正确吗?

使用OData:

在此处输入图片说明

我不明白什么是$ ref条目,为什么它们是随机的,为什么在不使用OData时不得到它们?

这是Web API方法:

public HttpResponseMessage Get(System.Web.Http.OData.Query.ODataQueryOptions<Employee> options)
        {
            HttpResponseMessage response;

            var employees = options.ApplyTo(_unitOfWork.EmployeeRepository.Get());

            if (employees == null)
            {
                response = new HttpResponseMessage(HttpStatusCode.NotFound);
            }
            else
            {
                response = Request.CreateResponse(HttpStatusCode.OK, employees);
                response.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(300));
            }
            return response;
        }

这是要序列化的类:

 public class Employee
    {
        [Key]
        public string WinId { get; set; }
        public string XML { get; set; }
        public int EffectiveYear { get; set; }
        public int FileKeeperGroupId { get; set; }
    }

编辑8/15

这是我的WebApiConfig

 var json = config.Formatters.JsonFormatter;
            config.Formatters.Clear();
            config.Formatters.Add(json);
            config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = 
                Newtonsoft.Json.PreserveReferencesHandling.None;

不推荐使用的答案:
如本主题中所讨论的, odata-v4中的实体关系请查看以下部分:

在实体之间建立关系

OData支持在两个现有实体之间创建或删除关系。 在OData v4术语中,该关系是“引用”。 (在OData v3中,该关系称为链接。协议差异对本教程而言无关紧要。)

引用具有自己的URI,格式为/ Entity / NavigationProperty / $ ref。 例如,以下是用于解决产品及其供应商之间的引用的URI:

http:/ host / Products(1)/ Supplier / $ ref

因此,实质上,这是odata知道哪个实体具有另一个实体的导航属性的方式。 WebApi根本不知道什么是什么,它所做的只是对数据进行服务。 但是,使用OData,您可以在URL本身内创建客户端查询,而不是在c#中在后端使用linq(就像针对Web api一样)。 为了使odata正确查询后端,需要知道数据库上下文中的所有实体和关系。 这是通过首先检出ODataController提供的$ metadata来完成的。 您可以通过查看

http://localhost/api/User/$metadata

注意:假设您的控制器名为UserController

请阅读有关odata的更多信息,并习惯于odata需要这些围绕您的数据的额外信息,以便正确理解数据库。 如果您不完全满意,则始终可以使用C#编写linq查询,并坚持使用webapi(尽管您确实失去了odata的一些优势,可以自己进行研究)。

新答案(8/15)
编辑:基于以下评论,绝对是造成问题的json序列化,而不是OData序列化。 很好的发现设置的方法,如以下站点: PreserveReferenceHandling ,讨论了在JSON响应中保留引用的配置。

我们意识到$ ref用于OData中的导航属性,并且还发现$ ref用于在序列化和反序列化json时跟踪对象引用。

就个人而言,我宁愿将$ ref保留在那里,因为JSON.NET足够聪明,可以发现循环引用。 如果您不相信我,请查看这篇文章: 序列化循环引用 但这都是个人喜好。

从描述中看来,您不熟悉OData概念(如果我做错了观察,请纠正我)。 OData是用于编写RESTful服务和客户端的开放标准( OASIS标准 ),并且某些约定和规则在OData中定义,并且它们与其他类型的RESTful服务不同。 ASP.NET Web API支持OData 1-3版和OData 4.0版。 如果要在Web API服务中启用此类支持,则应注意,您正在编写OData服务,并且只有OData特定的客户端才能与您的服务进行通信。

在OData中,序列化的处理方式与处理普通Web API服务的方式非常不同。 原因是OData具有非常特殊的有效负载类型,需要特殊处理。 让我们以OData V4 JSON有效负载为例。 它具有许多OData特定的JSON元素和属性,而普通的JSON有效负载处理程序并不具备这些知识。

您附加的有效负载不是OData有效负载,您附加的控制器动作也不是OData控制器动作。 要编写OData服务,可以参考ASP.NET学习站点

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM