安全地使用带有HttpContent.ReadAsStreamAsync()的StreamReader而不关闭基础流

问题描述 投票:0回答:1

我有多个属性类,它们需要访问HttpContent(位于HttpActionContextHttpRequstMessage中)中的数据,但是我在确定最佳处理方式时遇到了问题。我考虑过在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
}

这对每个属性都适用,但可能效率较低

所以,有没有一种最佳的方式来做到这一点而又不会泄漏内存?

我有多个Attribute类,它们需要访问HttpContent(位于HttpActionContext的HttpRequstMessage中)中的数据,但是在确定最佳方法时遇到了问题。我...

streamreader httpcontent
1个回答
0
投票

使用使流保持开放状态的流读取器-因为您不拥有流的所有权,所以它仍属于HTTP操作内容的范围。

public StreamReader (System.IO.Stream stream, System.Text.Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen);
© www.soinside.com 2019 - 2024. All rights reserved.