当前位置: 首页 > 知识库问答 >
问题:

ASP. NET Core返回带有状态代码的JSON

屠钊
2023-03-14

我正在寻找在我的. NET Core Web API控制器中返回带有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控制器返回JSON和HTTP状态代码,就像我在Web API 2中所做的那样。

共有3个答案

颛孙航
2023-03-14

使用ASP. NET Core 2.0,从Web API(与MVC统一并使用相同的基类Controller)返回对象的理想方式是

public IActionResult Get()
{
    return new OkObjectResult(new Item { Id = 123, Name = "Hero" });
}

请注意

  1. 它返回200 OK(正常)状态代码(它是ObjectResult的类型

如果它需要发送特定的状态代码,请改用ObjectResultStatusCode。两者都做同样的事情,并支持内容协商。

return new ObjectResult(new Item { Id = 123, Name = "Hero" }) { StatusCode = 200 };
return StatusCode( 200, new Item { Id = 123, Name = "Hero" });

或者更细粒度的ObjectResult:

 Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection myContentTypes = new Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection { System.Net.Mime.MediaTypeNames.Application.Json };
 String hardCodedJson = "{\"Id\":\"123\",\"DateOfRegistration\":\"2012-10-21T00:00:00+05:30\",\"Status\":0}";
 return new ObjectResult(hardCodedJson) { StatusCode = 200, ContentTypes = myContentTypes };

如果您特别希望以JSON的形式返回,有几种方法

//GET http://example.com/api/test/asjson
[HttpGet("AsJson")]
public JsonResult GetAsJson()
{
    return Json(new Item { Id = 123, Name = "Hero" });
}

//GET http://example.com/api/test/withproduces
[HttpGet("WithProduces")]
[Produces("application/json")]
public Item GetWithProduces()
{
    return new Item { Id = 123, Name = "Hero" };
}

请注意

  1. 两者都以两种不同的方式强制执行JSON

在官方文档中阅读有关它们的更多信息。在此处了解过滤器。

示例中使用的简单模型类

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
}
华献
2023-03-14

对于大多数常见的状态代码,您都有预定义的方法。

  • <代码>确定(结果)返回带有响应的<代码>200
  • CreatedAtRoute返回新资源URL
  • NotFound返回404
  • BadRequest返回400

有关所有方法的列表,请参阅BaseController.csController.cs

但是,如果您确实坚持要使用状态码来设置自定义代码,但您确实不应该这样做,因为这会降低代码的可读性,并且您必须重复代码来设置标题(如用于创建数据路由)。

public ActionResult IsAuthenticated()
{
    return StatusCode(200, "123");
}
郑俊彦
2023-03-14

响应JsonResult的最基本版本是:

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

然而,这无助于解决您的问题,因为您无法显式处理自己的响应代码。

控制状态结果的方法是,您需要返回一个ActionResult,在这里您可以利用StatusCodeResult类型。

例如:

// 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文档中的一个很好的指南:格式化响应数据

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

让我们确保你有一些基础知识...

为了得到你的ASP。NET核心WebAPI要使用JSON序列化对象以及状态代码的完全控制来响应,您应该首先确保在启动中通常找到的配置服务方法中包含了AddMvc()服务。cs。

需要注意的是,AddMvc()将自动包含JSON的输入/输出格式以及对其他请求类型的响应。

如果您的项目需要完全控制并且您想严格定义您的服务,例如您的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()方法的重复。但是,我们正在通过定义每个服务来自行实现每个“默认”服务,而不是使用模板预装的服务。我已经在代码块中添加了存储库链接,或者您可以从GitHub存储库中签出AddMvc().

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

我要给你看一个非常直接的问题,只是为了解决你的问题。

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();
    }
}

您需要确保请求中的内容类型和接受标题设置正确。在您的示例(JSON)中,您需要将其设置为应用程序/JSON

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

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

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

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

[Produces]过滤器将强制AuthorsController中的所有操作返回JSON格式的响应,即使为应用程序配置了其他格式化程序并且客户端提供了接受标头请求不同的可用格式。

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

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

options.RespectBrowserAcceptHeader = true; // false by default

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

更多信息可在此找到。NET Web开发和工具博客条目

 类似资料:
  • 问题内容: 我试图按照此链接中的建议将错误返回到对控制器的调用,以便客户端可以采取适当的措施。javascript通过jqueryAJAX调用控制器。仅在不将状态设置为error的情况下,我才可以重新获得Json对象。这是示例代码 如果没有设置状态码,我会得到Json。如果设置状态代码,则会返回状态代码,但不会返回Json错误对象。 更新 我想将Error对象作为JSON发送,以便可以处理ajax

  • 当我使用MVC控制器时,我使用“返回OK(对象)”或“返回BadRequest(ErrorMessage)”等。 我怎样才能实现这是剃刀页? 我尝试返回新的JSON result(object);这在状态代码为200时有效。但是如果我想返回带有JSON错误消息的状态代码400呢?

  • 我正在尝试使用BitBucket GIT存储库设置Jenkins,但Jenkins控制台总是给我以下错误代码: 我尝试过很多不同的方法,但总是失败。我的服务器上允许9418端口上的通信量。服务器处于1 Gbps连接上。

  • 本文向大家介绍HTTP 返回状态码有哪些?相关面试题,主要包含被问及HTTP 返回状态码有哪些?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 100 Continue 继续。客户端应继续其请求 101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 200 OK 请求成功。一般用于GET与POST

  • 我在路径“/test”中有一个无用的endpoint: 我这样测试: 但我得到一个断言错误: 预期状态代码 这发生在更多的代码中:400,500...除了200。 我用的是Spring靴。如果在运行测试时在endpoint方法中放置断点,则执行将停止,因此测试中的请求将正确完成。如果我将状态代码(在资源和测试中也是)更改为200,则测试通过。 到底发生了什么?

  • 问题内容: 我们正在使用Flask作为我们的API之一,我只是想知道是否有人知道如何返回HTTP响应201? 对于诸如404之类的错误,我们可以致电: 但是对于201我得到 LookupError:201都不例外 我是否需要创建自己的例外,像这样的文档? 问题答案: 你可以在这里阅读。