【发布时间】:2014-08-06 22:32:02
【问题描述】:
我正在使用 ODataLib 6.6.0 和 Microsoft.AspNet.OData 5.2.1 Nuget 包。
我有以下代码创建自定义序列化程序以将自定义注释添加到分页 OData 提要。代码编译并被正确调用,一直到添加自定义实例注释为止。
namespace WebApiTest.App_Start
{
using Microsoft.OData.Core;
using System.Collections.Generic;
using System.Web.Http;
using System.Web.OData.Formatter;
using System.Web.OData.Formatter.Deserialization;
using System.Web.OData.Formatter.Serialization;
using WebApiTest.Controllers;
public class FormatterConfiguration
{
public static void Register(HttpConfiguration config)
{
var formatters = ODataMediaTypeFormatters.Create(
new CustomODataSerializerProvider(),
new DefaultODataDeserializerProvider());
config.Formatters.InsertRange(0, formatters);
}
}
public class CustomODataSerializerProvider : DefaultODataSerializerProvider
{
private readonly CustomODataFeedSerializer _feedSerializer;
public CustomODataSerializerProvider()
{
_feedSerializer = new CustomODataFeedSerializer(this);
}
public override ODataEdmTypeSerializer GetEdmTypeSerializer(Microsoft.OData.Edm.IEdmTypeReference edmType)
{
var serializer = base.GetEdmTypeSerializer(edmType);
var feedSerializer = serializer as ODataFeedSerializer;
if (feedSerializer != null)
{
return _feedSerializer;
}
return serializer;
}
}
public class CustomODataFeedSerializer : ODataFeedSerializer
{
public CustomODataFeedSerializer(ODataSerializerProvider serializerProvider)
: base(serializerProvider)
{
}
public override Microsoft.OData.Core.ODataFeed CreateODataFeed(System.Collections.IEnumerable feedInstance, Microsoft.OData.Edm.IEdmCollectionTypeReference feedType, ODataSerializerContext writeContext)
{
ODataFeed feed = base.CreateODataFeed(feedInstance, feedType, writeContext);
var result = feedInstance as IPageResultCustom;
if (result != null)
{
var value = new ODataComplexValue();
var properties = new List<ODataProperty>();
properties.Add(new ODataProperty() { Name = "CustomProperty", Value = result.CustomProperty });
value.Properties = properties;
feed.InstanceAnnotations.Add(new ODataInstanceAnnotation("org.CustomComplexValue", value));
}
return feed;
}
}
}
我向包含 HTTP 标头 Prefer: odata.include-annotations="*" 和 Content-Type=application/json 的提要发出请求。然而,我在响应中没有得到任何注释。
跟踪 OData 框架代码,内部属性 Func<string,bool> Microsoft.OData.Core.MessageWriterSettings.ShouldInludeAnnotations 在创建 ODataMessageWriters 时从未设置,因此,ODataJsonLightValueSerializer.ShouldSkipAnnotation(string name) 方法调用始终返回 true。
这似乎是框架中的一个错误。我的配置或请求中是否缺少某些内容?
2014 年 8 月 7 日编辑
该问题似乎与错误 https://aspnetwebstack.codeplex.com/workitem/1880 有关。
建议了一种解决方法,涉及创建自定义ODataMediaTypeFormatter。但是,ODataMediaTypeFormatters.Create 不是通用的,重新创建它涉及到太多内部范围的依赖项。这种解决方法至少是一项艰巨的任务。 ODataMediaTypeFormatter 的可扩展性的现实限制似乎仅限于实现自定义序列化器和/或反序列化器。
【问题讨论】:
-
我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
-
这是一个特定于产品的问题,而不是关于 odata 规范的问题,即它现在的读取方式。见meta.stackexchange.com/a/179969
-
嗯?它是特定于产品的事实与“ASP.NET:”实际上是您添加到其他合理标题的元数据这一事实有什么关系?元数据已经存在于标签中。也许您想将标题编辑为“如何向 ASP.NET ODataFeed (V4) 添加实例注释”?请注意,我在标题中留下了“(V4)”。它是元数据,但没有可替代的标签。
-
@RichardCollette 你能更好地解释一下 IPageResultCustom 的实现吗?我正在复制您的代码,但我不明白它是如何实现该接口的。
标签: asp.net .net asp.net-web-api odata