ASP.NET Core 返回带有状态代码的 JSON [英] ASP.NET Core return JSON with status code

查看:32
本文介绍了ASP.NET Core 返回带有状态代码的 JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找在我的 .NET Core Web API 控制器中返回带有 HTTP 状态代码的 JSON 的正确方法.我曾经这样使用它:

I'm looking for the correct way to return JSON with a HTTP status code in my .NET Core Web API controller. I use to use it like this:

public IHttpActionResult GetResourceData()
{
    return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}

这是在 4.6 MVC 应用程序中,但现在使用 .NET Core 我似乎没有这个 IHttpActionResult 我有 ActionResult 并像这样使用:

This was in a 4.6 MVC application but now with .NET Core I don't seem to have this IHttpActionResult I have ActionResult and using like this:

public ActionResult IsAuthenticated()
{
    return Ok(Json("123"));
}

但是服务器的响应很奇怪,如下图:

But the response from the server is weird, as in the image below:

我只希望 Web API 控制器像我在 Web API 2 中所做的那样返回带有 HTTP 状态代码的 JSON.

I just want the Web API controller to return JSON with a HTTP status code like I did in Web API 2.

推荐答案

使用 JsonResult 响应的最基本版本是:

The most basic version responding with a JsonResult is:

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

但是,这对您的问题没有帮助,因为您无法明确处理自己的响应代码.

However, this isn't going to help with your issue because you can't explicitly deal with your own response code.

控制状态结果的方法是,您需要返回一个 ActionResult,然后您可以在其中利用 StatusCodeResult 类型.

The way to get control over the status results, is you need to return a ActionResult which is where you can then take advantage of the StatusCodeResult type.

例如:

// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
    var result = _authorRepository.GetByNameSubstring(namelike);
    if (!result.Any())
    {
        return NotFound(namelike);
    }
    return Ok(result);
}

请注意,以上两个示例均来自 Microsoft 文档中提供的出色指南:格式化响应数据

Note both of these above examples came from a great guide available from Microsoft Documentation: Formatting Response Data

我经常遇到的问题是,我希望对我的 WebAPI 进行更精细的控制,而不仅仅是使用 VS 中新项目"模板中的默认配置.

The issue I come across quite often is that I wanted more granular control over my WebAPI rather than just go with the defaults configuration from the "New Project" template in VS.

让我们确保您掌握了一些基础知识...

Let's make sure you have some of the basics down...

为了让您的 ASP.NET Core WebAPI 响应 JSON 序列化对象并完全控制状态代码,您应该首先确保已包含 AddMvc()您的 ConfigureServices 方法中的服务通常可以在 Startup.cs 中找到.

In order to get your ASP.NET Core WebAPI to respond with a JSON Serialized Object along full control of the status code, you should start off by making sure that you have included the AddMvc() service in your ConfigureServices method usually found in Startup.cs.

请务必注意,AddMvc() 将自动包含 JSON 的输入/输出格式化程序以及响应其他请求类型.

It's important to note thatAddMvc() will automatically include the Input/Output Formatter for JSON along with responding to other request types.

如果您的项目需要完全控制并且您想严格定义您的服务,例如您的 WebAPI 将如何处理各种请求类型,包括 application/json 并且不响应对于其他请求类型(例如标准浏览器请求),您可以使用以下代码手动定义:

If your project requires full control and you want to strictly define your services, such as how your WebAPI will behave to various request types including application/json and not respond to other request types (such as a standard browser request), you can define it manually with the following code:

public void ConfigureServices(IServiceCollection services)
{
    // Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
    // https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs

    services
        .AddMvcCore(options =>
        {
            options.RequireHttpsPermanent = true; // does not affect api requests
            options.RespectBrowserAcceptHeader = true; // false by default
            //options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();

            //remove these two below, but added so you know where to place them...
            options.OutputFormatters.Add(new YourCustomOutputFormatter()); 
            options.InputFormatters.Add(new YourCustomInputFormatter());
        })
        //.AddApiExplorer()
        //.AddAuthorization()
        .AddFormatterMappings()
        //.AddCacheTagHelper()
        //.AddDataAnnotations()
        //.AddCors()
        .AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}

您会注意到,我还提供了一种方法,供您添加自己的自定义输入/输出格式化程序,以防您想响应其他序列化格式(protobuf、thrift 等).

You will notice that I have also included a way for you to add your own custom Input/Output formatters, in the event you may want to respond to another serialization format (protobuf, thrift, etc).

上面的代码块大部分是 AddMvc() 方法的副本.但是,我们通过定义每个服务而不是使用带有模板的预装服务来实现我们自己的每个默认"服务.我已经在代码块中添加了存储库链接,或者您可以查看 AddMvc() 来自 GitHub 存储库..

The chunk of code above is mostly a duplicate of the AddMvc() method. However, we are implementing each "default" service on our own by defining each and every service instead of going with the pre-shipped one with the template. I have added the repository link in the code block, or you can check out AddMvc() from the GitHub repository..

请注意,有一些指南会尝试通过撤消"默认值来解决此问题,而不是一开始就不实施它……如果您考虑到我们现在正在使用 Open来源,这是多余的工作,糟糕的代码,坦率地说,这是一个很快就会消失的旧习惯.

我将向您展示一个非常简单的方法,只是为了解决您的问题.

I'm going to show you a really straight-forward one just to get your question sorted.

public class FooController
{
    [HttpPost]
    public async Task<IActionResult> Create([FromBody] Object item)
    {
        if (item == null) return BadRequest();

        var newItem = new Object(); // create the object to return
        if (newItem != null) return Ok(newItem);

        else return NotFound();
    }
}

<小时>

第 3 步:检查您的 Content-TypeAccept

您需要确保请求中的Content-TypeAccept 标头设置正确.在您的情况 (JSON) 中,您需要将其设置为 application/json.


Step 3: Check your Content-Type and Accept

You need to make sure that your Content-Type and Accept headers in your request are set properly. In your case (JSON), you will want to set it up to be application/json.

如果您希望您的 WebAPI 默认以 JSON 响应,无论请求标头指定什么,您都可以通过几种方式做到这一点.

If you want your WebAPI to respond as JSON as default, regardless of what the request header is specifying you can do that in a couple ways.

方式 1如我之前推荐的文章(Formatting Response Data) 您可以在控制器/操作级别强制使用特定格式.我个人不喜欢这种方法......但这里是为了完整性:

Way 1 As shown in the article I recommended earlier (Formatting Response Data) you could force a particular format at the Controller/Action level. I personally don't like this approach... but here it is for completeness:

强制使用特定格式如果您想限制特定操作的响应格式,您可以应用[产生] 过滤器.[Produces] 过滤器指定响应特定操作(或控制器)的格式.像大多数过滤器一样,这可以应用于操作、控制器或全局范围.

Forcing a Particular Format If you would like to restrict the response formats for a specific action you can, you can apply the [Produces] filter. The [Produces] filter specifies the response formats for a specific action (or controller). Like most Filters, this can be applied at the action, controller, or global scope.

[Produces("application/json")]
public class AuthorsController

[Produces] 过滤器将强制执行AuthorsController 返回 JSON 格式的响应,即使其他为应用程序和客户端配置了格式化程序请求不同的可用格式的 Accept 标头.

The [Produces] filter will force all actions within the AuthorsController to return JSON-formatted responses, even if other formatters were configured for the application and the client provided an Accept header requesting a different, available format.

方式 2我的首选方法是让 WebAPI 以请求的格式响应所有请求.但是,如果它不接受请求的格式,则回退到默认格式(即 JSON)

Way 2 My preferred method is for the WebAPI to respond to all requests with the format requested. However, in the event that it doesn't accept the requested format, then fall-back to a default (ie. JSON)

首先,您需要在选项中注册(我们需要重新设计默认行为,如前所述)

First, you'll need to register that in your options (we need to rework the default behavior, as noted earlier)

options.RespectBrowserAcceptHeader = true; // false by default

最后,通过简单地重新排列在服务构建器中定义的格式化程序列表,Web 主机将默认使用您位于列表顶部的格式化程序(即位置 0).

Finally, by simply re-ordering the list of the formatters that were defined in the services builder, the web host will default to the formatter you position at the top of the list (ie position 0).

更多信息可以在这个.NET Web 开发和工具博客条目

这篇关于ASP.NET Core 返回带有状态代码的 JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆