如何通过 Asp.Net Core 中间件的 JsonResult 响应?
Posted
技术标签:
【中文标题】如何通过 Asp.Net Core 中间件的 JsonResult 响应?【英文标题】:How to respond via an JsonResult from Asp.Net Core middleware? 【发布时间】:2017-08-23 15:27:40 【问题描述】:我想通过一个 Asp.Net Core 中间件的JsonResult
回复,但如何实现这一点并不明显。我用谷歌搜索了很多,但收效甚微。我可以通过将ActionExecutedContext.Result
设置为JsonResult
来通过来自全球IActionFilter
的JsonResult
进行响应,这很酷。但在这种情况下,我想从我的中间件有效地返回一个JsonResult
。怎么实现?
我针对JsonResult
IActionResult
提出了问题,但理想情况下,该解决方案适用于使用任何IActionResult
来编写来自中间件的响应。
【问题讨论】:
【参考方案1】:正如@Henk Mollema 所解释的,我还利用Newtonsoft.Json JsonConvert 类通过SerializeObject 方法将对象序列化为JSON。对于 ASP.NET Core 3.1,我在 Run 方法中使用了 JsonConvert。以下解决方案对我有用:
Startup.cs
using Newtonsoft.Json;
// ...
public class Startup
public void Configure(IApplicationBuilder app)
app.Run(async context =>
context.Response.StatusCode = 200;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(new
message = "Yay! I am a middleware"
));
);
【讨论】:
【参考方案2】:对于其他可能对如何从中间件返回 JsonResult
的输出感兴趣的人,这是我想出的:
public async Task Invoke(HttpContext context, IHostingEnvironment env)
JsonResult result = new JsonResult(new msg = "Some example message." );
RouteData routeData = context.GetRouteData();
ActionDescriptor actionDescriptor = new ActionDescriptor();
ActionContext actionContext = new ActionContext(context, routeData, actionDescriptor);
await result.ExecuteResultAsync(actionContext);
这种方法允许一个中间件从 JsonResult
返回输出,并且该方法接近于使中间件能够从任何 IActionResult.
返回输出 要处理更通用的情况,创建 @ 的代码987654325@ 需要改进。但是到此为止,对于我返回 JsonResult
的输出的需要已经足够了。
【讨论】:
这是一个很好的答案,对我有用。这里的巫术是 ExecuteResultAsync 正在为您写入响应流。 @BinaryPatrick 这是软件开发而不是令人讨厌的东西。事实证明,即使在典型的控制器中,当return View(this);
被执行时,它也会返回一个ViewResult
,它不会立即输出任何东西。然后在管道的后期,.NET 框架调用ExecuteResultAsync
将Result
呈现给响应流。所以这个答案的方法只是使用我从挖掘 .NET Core 源代码中发现的内容。很高兴它有帮助。【参考方案3】:
中间件是 ASP.NET Core 的一个非常低级的组件。写出 JSON(高效)是在 MVC 存储库中实现的。具体来说,在JSON formatters 组件中。
基本上归结为在响应流上写入 JSON。在最简单的形式中,它可以像这样在中间件中实现:
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
// ...
public async Task Invoke(HttpContext context)
var result = new SomeResultObject();
var json = JsonConvert.SerializeObject(result);
await context.Response.WriteAsync(json);
【讨论】:
@Hank,感谢您的回复。我知道我可以使用 Response.WriteAsync 发送原始 json,但这种方法容易忽略诸如忘记将content-type
repsonse 标头设置为“application/json; charset=utf-8”之类的事情。 :-) 这就是为什么我专门询问如何通过 JsonResult 进行响应,而不是简单地询问如何发送 json 响应。另外,我提出了关于JsonResult
IActionResult
的问题,但理想情况下,该解决方案适用于使用任何IActionResult
来编写来自中间件的响应。我会更新我的问题以表明这一点。
@RonC IActionResult
和 JsonResult
是 MVC 原语。中间件在 ASP.NET Core 的分层中要低得多。
@Hank,我知道。所以问题有点归结为我们如何到达更高的堆栈以利用 MVC 的功能并从堆栈中远的位置进行操作,即。中间件。
不幸的是,它不能那样工作。我认为让某些东西工作起来会非常麻烦。也许在你的中间件中包装一个 TestServer 并返回它给你的东西(通过 TestServer 中的 MVC - 就像我说的,hacky。)以上是关于如何通过 Asp.Net Core 中间件的 JsonResult 响应?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core管道深度剖析:管道是如何建立起来的?