我需要将一些信息附加到控制器每个操作的每个 JSON 答案中。为此,我使基本控制器继承自标准 MVC
Controller
类。
我尝试这样。但我发现 ArgumentException
带有这样的消息:“流不可读。”当 ActionResult
对象将数据写入正文时,可能流已关闭。我能做些什么?
public override void OnActionExecuted(ActionExecutedContext context)
{
var respApi = new ResponseApiDTO();
respApi.Comment = "You could!!!";
JObject jRespApi = JObject.FromObject(respApi);
Stream bodyStream = context.HttpContext.Response.Body;
JObject jbody;
context.Result = Json(jbody);
using( var rd = new StreamReader(bodyStream))
{
string bodyText = rd.ReadToEnd();
jbody = (JObject)JsonConvert.DeserializeObject(bodyText);
jbody.Add(jRespApi);
context.Result = Json(jbody);
}
}
我找到了解决办法。在管道中执行 MVC 步骤时,我们需要用
MemoryStream
对象替换 Body 流。然后我们必须将原始流对象返回到Response.Body
。
// Extension method used to add the middleware to the HTTP request pipeline.
public static class BufferedResponseBodyExtensions
{
public static IApplicationBuilder UseBufferedResponseBody(this IApplicationBuilder builder)
{
return builder.Use(async (context, next) =>
{
using (var bufferStream = new MemoryStream())
{
var orgBodyStream = context.Response.Body;
context.Response.Body = bufferStream;
await next();//there is running MVC
bufferStream.Seek(0, SeekOrigin.Begin);
await bufferStream.CopyToAsync(orgBodyStream);
context.Response.Body = orgBodyStream;
}
});
}
}
然后将其包含到管道中。类启动,方法配置。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseBufferedResponseBody();
app.UseMvc();
...
}
替换响应正文流后,您可以通过结果过滤器读取和修改正文内容。
public class ResultFilterAttribute : Attribute, IResultFilter
{
public async void OnResultExecuted(ResultExecutedContext context)
{
Stream bodyStream = context.HttpContext.Response.Body;
bodyStream.Seek(0, SeekOrigin.Begin);
string bodyText = rd.ReadToEnd();
}
}
此属性必须应用于目标控制器类。