【发布时间】:2019-11-04 17:10:22
【问题描述】:
我有多个属性类需要访问HttpContent(位于HttpActionContext 的HttpRequstMessage 中)中的数据,但我在决定最佳方法时遇到问题。我考虑在HttpContent 上使用ReadAsStringAsync 方法,但似乎我需要访问Stream 才能首先将位置设置为0。
天真的方法似乎只是用using 语句将StreamReader 包裹在基本流周围,如下所示:
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
}
这适用于每个属性,但可能效率较低。
那么,有没有一种不泄漏内存的最佳方法呢?
【问题讨论】: