我正在使用ODataLib 6.6.0和Microsoft.AspNet.OData 5.2.1 Nuget包。
我有以下代码,它创建了一个自定义序列化程序,用于向分页的OData Feed添加自定义注释。代码编译和调用正确,一直到添加自定义实例注释。
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
的Feed发出请求。然而,我在回复中没有注释。
跟踪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
的可扩展性的实际限制仅限于实现自定义序列化器和/或反序列化器。
答案 0 :(得分:1)
我可以通过覆盖DelegatingHandler.SendAsync来在响应头中设置Preference-Applied来解决这个问题:
return await base.SendAsync(request, cancellationToken).ContinueWith(t =>
{
var response = t.Result;
IEnumerable<string> headers;
if (request.Headers.TryGetValues("Prefer", out headers))
{
response.Content.Headers.Add("Preference-Applied", headers);
}
}