如何从控制器返回特定的状态码和无内容?

196
我希望下面的示例控制器返回一个状态码为418,不含任何内容。设置状态码很容易,但似乎还需要执行某些操作来表示请求结束。在ASP.NET Core之前的MVC或WebForms中,可能会调用Response.End()方法,但在ASP.NET Core中,该方法不存在,那么应该如何处理呢?
public class ExampleController : Controller
{
    [HttpGet][Route("/example/main")]
    public IActionResult Main()
    {
        this.HttpContext.Response.StatusCode = 418; // I'm a teapot
        // How to end the request?
        // I don't actually want to return a view but perhaps the next
        // line is required anyway?
        return View();   
    }
}
6个回答

367

this.HttpContext.Response.StatusCode = 418; // 我是茶壶

如何结束请求?

尝试其他解决方案,只需:

return StatusCode(418);

你可以使用 StatusCode(???) 返回任何 HTTP 状态码。
此外,您可以使用专门的结果:
成功:
- return Ok() ← Http 状态码 200 - return Created() ← Http 状态码 201 - return NoContent(); ← Http 状态码 204
客户端错误:
- return BadRequest(); ← Http 状态码 400 - return Unauthorized(); ← Http 状态码 401 - return NotFound(); ← Http 状态码 404
更多细节:

2
这种方法的简单和优点不言而喻!我需要映射一个 HttpResponseMessage 并从自己的端点返回它,这是唯一真正有用的评论。 - GeorgiG
抱歉,在ASP.NET Core SOAP服务中,没有HttpContext。 - Paul
但是返回 StatusCode(418) 确实会返回内容。它返回一个包含状态码和其他几个属性的 JSON 对象,因此我不明白这甚至是一个有效的答案。 - Neutrino
@Neutrino,返回的内容实际上取决于您的应用程序设置。在某些情况下(对于Api控制器和未返回自定义数据/对象的情况),.NET Core会返回“ProblemDetails”对象-这是一种基于https://tools.ietf.org/html/rfc7807的HTTP API响应中指定错误的机器可读格式。 - Lukasz Mk

23

最好的方法是:

return this.StatusCode(StatusCodes.Status418ImATeapot, "Error message");

StatusCodes 包含各种返回状态,您可以在此处查看所有状态信息。

选择您的StatusCode后,请使用消息返回它。


2
感谢您让我了解到这个非常有用的状态代码。 - undefined
1
谢谢你让我知道这个非常有用的状态码。 - Joe Coyle

8

看看当前对象结果是如何创建的。这里是BadRequestObjectResult。它只是一个值和状态码的ObjectResult的扩展。

https://github.com/aspnet/Mvc/blob/master/src/Microsoft.AspNetCore.Mvc.Core/BadRequestObjectResult.cs

我也按照相同的方式为408创建了TimeoutExceptionObjectResult。

/// <summary>
/// An <see cref="ObjectResult"/> that when executed will produce a Request Timeout (408) response.
/// </summary>
[DefaultStatusCode(DefaultStatusCode)]
public class TimeoutExceptionObjectResult : ObjectResult
{
    private const int DefaultStatusCode = StatusCodes.Status408RequestTimeout;

    /// <summary>
    /// Creates a new <see cref="TimeoutExceptionObjectResult"/> instance.
    /// </summary>
    /// <param name="error">Contains the errors to be returned to the client.</param>
    public TimeoutExceptionObjectResult(object error)
        : base(error)
    {
        StatusCode = DefaultStatusCode;
    }
}

客户端:

if (ex is TimeoutException)
{
    return new TimeoutExceptionObjectResult("The request timed out.");
}

6

这段代码可能适用于非.NET Core MVC控制器:

this.HttpContext.Response.StatusCode = 418; // I'm a teapot
return Json(new { status = "mer" }, JsonRequestBehavior.AllowGet);

6

.Net 5或.Net 6基于的API(.Net Core 3x也可以运行,但未进行验证)

public async Task<ActionResult<List<DocumentsResponseDto>>> SaveDocumentDetails([FromBody] List<DocumentDetailsRequestDto> documentDetailsRequestDto)
{

 var response = await _documentService.SaveDocumentDetails(documentDetailsRequestDto);

 return StatusCode(Microsoft.AspNetCore.Http.StatusCodes.Status207MultiStatus, response); 
}

5

如果有人想在Web API项目中使用IHttpActionResult,以下内容可能会很有帮助。

// GET: api/Default/
public IHttpActionResult Get()
{
    //return Ok();//200
    //return StatusCode(HttpStatusCode.Accepted);//202
    //return BadRequest();//400
    //return InternalServerError();//500
    //return Unauthorized();//401
    return Ok();
}

InternalServerError作为IHttpActionResult存在吗? - Jim G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接