У меня есть несколько классов Attribute, которым требуется доступ к данным в HttpContent
(в HttpActionContext
HttpRequstMessage
), но у меня возникают проблемы с выбором наилучшего способа сделать это.Я подумал об использовании метода ReadAsStringAsync
на HttpContent
, но, похоже, мне нужен доступ к Stream
, чтобы сначала установить позицию на 0.
Наивный способ, похоже, просто обернуть StreamReader
вокруг базового потока с помощью оператора using
, например, так:
public override void OnActionExecuting(HttpActionContext actionContext)
{
string rawJson;
using (StreamReader streamReader = new StreamReader(actionContext.Request.Content.ReadAsStreamAsync().Result))
{
streamReader.BaseStream.Position = 0;
rawJson = streamReader.ReadToEnd();
}
// etc
}
Это хорошо работает для первого исполняемого атрибута, но каждый последующий исполняющий атрибут создает исключение на actionContext.Request.Content.ReadAsStreamAsync()
, поскольку он был удален.
Вот альтернативные методы, которые работают, но я действительно хотел бы знать оптимальный способ сделать это.
1: Оберните StreamReader
вокруг основного потока и никогда не располагайте его.
public override void OnActionExecuting(HttpActionContext actionContext)
{
StreamReader streamReader = new StreamReader(actionContext.Request.Content.ReadAsStreamAsync().Result);
streamReader.BaseStream.Position = 0;
string rawJson = streamReader.ReadToEnd();
// etc
}
Это хорошо работает для каждого атрибута, но Я беспокоюсь, что у меня может быть утечка памяти , если я не утилизирую StreamReader
.
2: Скопировать базовый потокв MemoryStream
и оберните это StreamReader
.
public override void OnActionExecuting(HttpActionContext actionContext)
{
MemoryStream memoryStream = new MemoryStream();
Stream s = actionContext.Request.Content.ReadAsStreamAsync().Result;
s.Position = 0;
s.CopyTo(memoryStream);
string rawJson;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
streamReader.BaseStream.Position = 0;
rawJson = streamReader.ReadToEnd();
}
// etc
}
Это хорошо работает для каждого атрибута, но много кода и может быть неэффективным .
3: установите позицию базового потока на 0, затем вызовите ReadAsStringAsync
.
public override void OnActionExecuting(HttpActionContext actionContext)
{
actionContext.Request.Content.ReadAsStreamAsync().Result.Position = 0;
string rawJson = actionContext.Request.Content.ReadAsStringAsync().Result;
// etc
}
Это хорошо работает для каждого атрибута, но может быть менее эффективным .
Итак, есть ли оптимальный способ сделать это без утечки памяти?