192

I want the example controller below to return a status code 418 with no contents. Setting the status code is easy enough but then it seems like there is something that needs to be done to signal the end of the request. In MVC prior to ASP.NET Core or in WebForms that might be a call to Response.End() but how does it work in ASP.NET Core where Response.End does not exist?

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();   
    }
}
Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
RonC
  • 31,330
  • 19
  • 94
  • 139

6 Answers6

362

this.HttpContext.Response.StatusCode = 418; // I'm a teapot

How to end the request?

Try other solution, just:

return StatusCode(418);


You could use StatusCode(???) to return any HTTP status code.


Also, you can use dedicated results:

Success:

  • return Ok() ← Http status code 200
  • return Created() ← Http status code 201
  • return NoContent(); ← Http status code 204

Client Error:

  • return BadRequest(); ← Http status code 400
  • return Unauthorized(); ← Http status code 401
  • return NotFound(); ← Http status code 404


More details:

Gabriel
  • 1,922
  • 2
  • 19
  • 37
Lukasz Mk
  • 7,000
  • 2
  • 27
  • 41
  • 2
    The simplicity and virtue of this approach can't be overstated! I had a need to map an HttpResponseMessage and return it from my own endpoint and this was the only comment that was actually helpful. – GeorgiG Jan 26 '22 at 00:49
  • Sorry, in ASP.NET Core SOAP service this has no HttpContext. – Paul Feb 16 '22 at 18:40
  • But returning `StatusCode(418)` _does_ return content. It returns a JSON object containing the status code and a few other properties, so I don't see how this is even a valid answer to the question. – Neutrino Jun 23 '22 at 09:32
  • @Neutrino what's returned depends really on your app settings. In some cases (for Api controllers and when not custom data/object returned) .NET Core returns `ProblemDetails` object - this is a machine-readable format for specifying errors in HTTP API responses based on https://tools.ietf.org/html/rfc7807 – Lukasz Mk Nov 06 '22 at 21:14
22

The best way to do it is:

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

StatusCodes has every kind of return status and you can see all of them here.

Once you choose your StatusCode, return it with a message.

derHugo
  • 83,094
  • 9
  • 75
  • 115
Gabriel Arruda
  • 487
  • 5
  • 10
8

Look at how the current Object Results are created. Here is the BadRequestObjectResult. Just an extension of the ObjectResult with a value and StatusCode.

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

I created a TimeoutExceptionObjectResult just the same way for 408.

/// <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;
    }
}

Client:

if (ex is TimeoutException)
{
    return new TimeoutExceptionObjectResult("The request timed out.");
}
sac80644
  • 103
  • 1
  • 5
6

This code might work for non-.NET Core MVC controllers:

this.HttpContext.Response.StatusCode = 418; // I'm a teapot
return Json(new { status = "mer" }, JsonRequestBehavior.AllowGet);
PTD
  • 1,028
  • 1
  • 16
  • 23
sobelito
  • 1,525
  • 17
  • 13
6

For .Net 5 or .Net 6 based API (Could work in .Net Core 3x as well, didn't checked)

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); 
}
KushalSeth
  • 3,265
  • 1
  • 26
  • 29
4

If anyone wants to do this with a IHttpActionResult may be in a Web API project, Below might be helpful.

// 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();
}
PAVITRA
  • 761
  • 2
  • 12
  • 24