Какая дополнительная польза от использования OutputFormatterWriteContext.WriterFactory вместо обычного StreamWriter, который в этом случае прекрасно работает?
На самом деле, вы можете написать HttpResponse.Body
напрямую, если хотите. Дело в том, что, как описано в документе, не используйте WriterFactory
, когда вы хотите записать двоичные данные.
Ядро ASP.NET использует HttpResponseStreamWriter
для записи потока за сценой (см. MemoryPoolHttpResponseStreamWriterFactory )
, Эта реализация предоставляет несколько методов, которые очень похожи на StreamWriter
. Но HttpResponseStreamWriter
использует ArrayPool<>
за капотом. Согласно этому документу , он должен улучшать производительность при частом создании и уничтожении массивов.
Мои основные вопросы: почему не выводится спецификация при использовании OutputFormatterWriteContext.WriterFactory?
Это потому, что HttpResponseStreamWriter
вообще не пишет BOM
:
/// <summary<
/// Writes to the using the supplied .
/// <b>It does not write the BOM and also does not close the stream.</b>
/// </summary<
public class HttpResponseStreamWriter : TextWriter
{
private const int MinBufferSize = 128;
internal const int DefaultBufferSize = 16 * 1024;
...
}
Есть ли способ избежать явной записи спецификации, например, есть писатель, вызывающий Encoding.GetPreamble () автоматически?
Если вы используете встроенный OutputFormatterWriteContext.WriterFactory
, я думаю, что ответ будет ДА . Вы должны написать заголовок спецификации самостоятельно, если хотите.
Наконец, вы не должны записывать заголовки в методе WriteResponseBodyAsync()
. Это обязанность WriteResponseHeaders(ctx)
. Эти коды лучше перенести на WriteResponseHeaders(OutputFormatterWriteContext ctx )
:
public override void WriteResponseHeaders(OutputFormatterWriteContext ctx )
{
var response = ctx.HttpContext.Response;
response.Headers.Add("Content-Disposition", $"attachment; filename=test.csv");
response.ContentType = "text/csv";
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var response = context.HttpContext.Response;
var preamble = _encoding.GetPreamble();
response.Body.Write(preamble, 0, preamble.Length);
using (var writer = context.WriterFactory(response.Body, _encoding))
{
var csv = new CsvWriter(writer);
csv.Configuration.HasHeaderRecord = true;
csv.Configuration.QuoteAllFields = true;
csv.WriteRecords((IEnumerable<object>)context.Object);
await writer.FlushAsync();
}
}