c# - ASP.NET Core 返回带有状态码的 JSON

我正在寻找在我的 .NET Core Web API Controller 中返回带有 HTTP 状态代码的 JSON 的正确方法。我以前是这样使用的:

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

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

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

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

我只希望 Web API Controller 返回带有 HTTP 状态代码的 JSON,就像我在 Web API 2 中所做的那样。

最佳答案

JsonResult 响应的最基本版本是:

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

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

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 文档中的一个很好的指南:Formatting Response Data


额外的东西

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

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

第 1 步:配置您的服务

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

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 并且不响应对于其他请求类型(例如标准浏览器请求),您可以使用以下代码手动定义:

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 等)时使用。

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

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


第 2 步:创建 Controller

我将向您展示一个非常直截了当的问题,只是为了解决您的问题。

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

您需要确保您的 request 中的 Content-TypeAccept header 设置正确。在您的情况下(JSON),您需要将其设置为 application/json

如果您希望 WebAPI 默认以 JSON 响应,无论请求 header 指定什么,您都可以通过几种方式来实现。

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

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

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)

首先,您需要在选项中注册它(我们需要修改默认行为,如前所述)

options.RespectBrowserAcceptHeader = true; // false by default

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

更多信息可以在这里找到.NET Web Development and Tools Blog entry

https://stackoverflow.com/questions/42360139/

相关文章:

sql-server - 在 SQL 中解析 JSON

android - 将 ArrayList 转换为 JSONArray

json - 如何使用标准 Scala 类在 Scala 中解析 JSON?

python - UnicodeDecodeError : 'utf8' codec can't d

json - curl json 通过终端向 Rails 应用程序发布请求

javascript - 无法使用 "-"破折号访问 JSON 属性

python - pickle 还是json?

javascript - 如何使用 html 表单数据发送 JSON 对象

javascript - 是否有任何可公开访问的 JSON 数据源来测试真实世界的数据?

asp.net-mvc - 将 JsonRequestBehavior 设置为 AllowGet 时