OData Web API - ODataMediaTypeFormatter MediaTypeResolver больше не существует
Веб-API OData v7. Я пишу пользовательский форматтер для CSV, Excel и т.д. У меня нет связи с тем, как я указываю свой пользовательский форматер (ODataMediaTypeFormatter
) на мои собственные классы, где я изменяю вывод.
CustomFormatter: ODataMediaTypeFormatter - имел MessageWriterSettings.MediaTypeResolver, которого больше не существует в v. 7
Когда я отлаживаюсь, я попадаю на GetPerRequestFormatterInstance
, и после этого он умирает с не найденным поддерживаемым типом 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..
}
Разъединение происходит с ODataMediaTypeFormatter
и CsvMediaTypeResolver
. Как мне связать ODataMediaTypeFormatter
с моим распознавателем?
Ответы
Ответ 1
Я решил это с помощью CsvOutputContext
и CsvWriterDemo
, описанных в примерах в Microsoft.OData.Core
Обновлен пример кода
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);
}