Web API OData-ODataMediaTypeFormatter MediaTypeResolver不再存在

Mic*_*tes 12 c# odata asp.net-web-api asp.net-web-api-odata asp.net-web-api2

Web API OData v7。我正在为CSV,Excel等编写自定义格式器。我不知道如何将自定义格式器(ODataMediaTypeFormatter)指向自定义类,以在其中修改输出。

CustomFormatter:ODataMediaTypeFormatter-具有MessageWriterSettings.MediaTypeResolver,在7版中不再存在

调试时,进入GetPerRequestFormatterInstance,然后它死于A。找不到与响应的内容类型匹配的受支持的MIME类型。

我无法弄清楚流程-如何将其绑定到我的自定义(ODataWriter)编写器(csv或我想创建的任何内容)。

例如,从git的示例中:

public class CustomFormatter : ODataMediaTypeFormatter
{
    private readonly string csvMime = ;

    public CustomFormatter(params ODataPayloadKind[] kinds)
        : base(kinds) {
        //----no longer exists in 7
        //MessageWriterSettings.MediaTypeResolver = new MixResolver();

        SupportedEncodings.Add(Encoding.UTF8);
        SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));            
    }
}

public class MixResolver : ODataMediaTypeResolver
{
    public override IEnumerable<ODataMediaTypeFormat> GetMediaTypeFormats(ODataPayloadKind payloadKind)
    {
        if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet)
        {
            return CsvMediaTypeResolver.Instance.GetMediaTypeFormats(payloadKind);
        }
        return base.GetMediaTypeFormats(payloadKind);
    }
}

public class CsvMediaTypeResolver : ODataMediaTypeResolver
{
    private static readonly CsvMediaTypeResolver instance = new CsvMediaTypeResolver();
    private readonly ODataMediaTypeFormat[] mediaTypeFormats =
    {
    new ODataMediaTypeFormat(new ODataMediaType("text", "csv"), new CsvFormat())
};

public class CsvMediaTypeResolver : ODataMediaTypeResolver
{
    private static readonly CsvMediaTypeResolver instance = new CsvMediaTypeResolver();
    private readonly ODataMediaTypeFormat[] mediaTypeFormats = { new ODataMediaTypeFormat(new ODataMediaType("text", "csv"), new CsvFormat())};
    private CsvMediaTypeResolver() { }
    public static CsvMediaTypeResolver Instance { get { return instance; } }
    public override IEnumerable<ODataMediaTypeFormat> GetMediaTypeFormats(ODataPayloadKind payloadKind)
    {
        if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet)
        {
            return mediaTypeFormats.Concat(base.GetMediaTypeFormats(payloadKind));
        }
        return base.GetMediaTypeFormats(payloadKind);
    }
}


public class CsvWriter : ODataWriter
{
    // Etc..
}
Run Code Online (Sandbox Code Playgroud)

断开连接与ODataMediaTypeFormatter和CsvMediaTypeResolver。如何将链接ODataMediaTypeFormatter到我的解析器?

Sre*_*air 2

我已经解决了这个问题,CsvOutputContext并在Microsoft.OData.CoreCsvWriterDemo的示例中进行了解释

示例代码已更新

public CsvOutputContext(
   ODataFormat format,
   ODataMessageWriterSettings settings,
   ODataMessageInfo messageInfo,
   bool synchronous)
   : base(format, settings, messageInfo.IsResponse, synchronous, 
     messageInfo.Model, messageInfo.UrlResolver)

   {
     this.stream = messageInfo.GetMessageStream();
     this.Writer = new StreamWriter(this.stream);
   }
}

private static void CsvWriterDemo()
{
   EdmEntityType customer = new EdmEntityType("ns", "customer");
   var key = customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);
   customer.AddKeys(key);
   customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);

   ODataEntry entry1 = new ODataEntry()
   {
       Properties = new[]
       {
           new ODataProperty(){Name = "Id", Value = 51}, 
           new ODataProperty(){Name = "Name", Value = "Name_A"}, 
       }
   };

   ODataEntry entry2 = new ODataEntry()
   {
       Properties = new[]
       {
           new ODataProperty(){Name = "Id", Value = 52}, 
           new ODataProperty(){Name = "Name", Value = "Name_B"}, 
       }
   };

   var stream = new MemoryStream();
   var message = new Message { Stream = stream };
   // Set Content-Type header value
   message.SetHeader("Content-Type", "text/csv");
   var settings = new ODataMessageWriterSettings
   {
       // Set our resolver here.
       MediaTypeResolver = CsvMediaTypeResolver.Instance,
       DisableMessageStreamDisposal = true,
   };
   using (var messageWriter = new ODataMessageWriter(message, settings))
   {
       var writer = messageWriter.CreateODataFeedWriter(null, customer);
       writer.WriteStart(new ODataFeed());
       writer.WriteStart(entry1);
       writer.WriteEnd();
       writer.WriteStart(entry2);
       writer.WriteEnd();
       writer.WriteEnd();
       writer.Flush();
   }

   stream.Seek(0, SeekOrigin.Begin);
   string msg;
   using (var sr = new StreamReader(stream)) { msg = sr.ReadToEnd(); }
   Console.WriteLine(msg);
}
Run Code Online (Sandbox Code Playgroud)