如何通过 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 来通过来自全球IActionFilterJsonResult 进行响应,这很酷。但在这种情况下,我想从我的中间件有效地返回一个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 框架调用ExecuteResultAsyncResult 呈现给响应流。所以这个答案的方法只是使用我从挖掘 .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 响应。另外,我提出了关于JsonResultIActionResult 的问题,但理想情况下,该解决方案适用于使用任何IActionResult 来编写来自中间件的响应。我会更新我的问题以表明这一点。 @RonC IActionResultJsonResult 是 MVC 原语。中间件在 ASP.NET Core 的分层中要低得多。 @Hank,我知道。所以问题有点归结为我们如何到达更高的堆栈以利用 MVC 的功能并从堆栈中的位置进行操作,即。中间件。 不幸的是,它不能那样工作。我认为让某些东西工作起来会非常麻烦。也许在你的中间件中包装一个 TestServer 并返回它给你的东西(通过 TestServer 中的 MVC - 就像我说的,hacky。)

以上是关于如何通过 Asp.Net Core 中间件的 JsonResult 响应?的主要内容,如果未能解决你的问题,请参考以下文章

写入自定义 ASP.NET Core 中间件

Asp.Net Core 通过中间件防止图片盗链

ASP.NET Core管道深度剖析:管道是如何建立起来的?

如何在 ASP.NET core rc2 中禁用浏览器缓存?

如何在 ASP.Net Core 中使用 条件中间件

对比学习koa.jsGin与asp.net core——中间件