【问题标题】:How to Add an Instance Annotation to an Asp.Net ODataFeed (V4)如何向 Asp.Net ODataFeed (V4) 添加实例注释
【发布时间】: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&lt;string,bool&gt; 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


【解决方案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);
   }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-05-27
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多