ASP.NET Core – Come restituire una risposta 500

ASP.NET Core – Come restituire una risposta 500

Il modo più semplice per restituire una risposta 500 è utilizzare il metodo helper Problem(), in questo modo:

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Save(Movie movie)
	{
		return Problem();
	}
}
Code language: C# (cs)

Questo produce la seguente risposta:

500 - Internal Server Error

Content-Type: application/problem+json

Body:
{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
    "title": "An error occured while processing your request.",
    "status": 500,
    "traceId": "0HMDLK1UAAP5O:00000002"
}Code language: plaintext (plaintext)

La classe ControllerBase ha molti metodi di supporto come Problem() che semplificano la restituzione delle risposte. Questi hanno diversi parametri facoltativi che puoi usare per personalizzare la risposta. Internamente, questi metodi di supporto restituiscono oggetti risultato. Puoi creare e restituire questi oggetti risultato tu stesso, se lo desideri. A volte potrebbe anche essere necessario, ad esempio se non esiste un metodo di supporto per ciò che stai cercando di restituire.

In questo articolo, mostrerò come personalizzare la risposta 500, quindi mostrerò esempi di restituzione di altri codici di risposta (come 400 – Richiesta non valida).

Personalizzazione della risposta 500

Il metodo Problem() ha la seguente firma:

public ObjectResult Problem(string detail = null, 
	string instance = null, 
	int? statusCode = null, 
	string title = null, 
	string type = null);
Code language: C# (cs)

Ci sono diversi parametri opzionali. Puoi personalizzare la risposta utilizzando questi parametri, come mostrerò di seguito.

Nota:quando non trasmetti valori per questi parametri, utilizzerà i valori predefiniti. Questo può portare a valori di risposta sorprendenti. Consiglio di ricontrollare le risposte durante lo sviluppo. Puoi controllare completamente ciò che restituisce, se necessario.

Cambia il codice di stato

Per modificare il codice di stato, passare un valore per il parametro statusCode. Ad esempio, supponiamo che tu voglia restituire 501 – Non implementato :

using Microsoft.AspNetCore.Http;

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Save(Movie movie)
	{
		return Problem(statusCode: StatusCodes.Status501NotImplemented);
	}
}
Code language: C# (cs)

Questo genera la seguente risposta:

501 - Not Implemented

Content-Type: application/problem+json

Body:
{
    "status": 501,
    "traceId": "0HMDLKL0AFS4D:00000001"
}Code language: plaintext (plaintext)

Nota:puoi codificare il valore del codice di stato (501), utilizzare le costanti intere da Microsoft.AspNetCore.Http.StatusCodes o utilizzare l'enumerazione System.Net.HttpStatusCode (di cui devi eseguire il cast su un int).

Cambia il corpo della risposta

Il corpo della risposta contiene diverse proprietà che puoi controllare tramite parametri. Ad esempio, supponiamo di voler aggiungere dettagli sul problema:

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Save(Movie movie)
	{
		return Problem(detail: "Movie doesn't exist");
	}
}
Code language: C# (cs)

Questo produce la seguente risposta. Si noti che ha aggiunto la proprietà dettaglio:

500 - Internal Server Error

Content-Type: application/problem+json

Body:
{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
    "title": "An error occured while processing your request.",
    "status": 500,
    "detail": "Movie doesn't exist",
    "traceId": "0HMDLKRP86VKE:00000001"
}
Code language: plaintext (plaintext)

Personalizza completamente la risposta

Il metodo Problem() imposta il contenuto su un oggetto ProblemDetails. Diciamo che non vuoi nessuna delle proprietà ProblemDetails. Un modo per personalizzare completamente la risposta è utilizzare il metodo di supporto StatusCode():

using Microsoft.AspNetCore.Http;

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Save(Movie movie)
	{
		return StatusCode(StatusCodes.Status500InternalServerError, "Movie doesn't exist");
	}
}
Code language: C# (cs)

Questo genera la seguente risposta:

500 - Internal Server Error

Content-Type: text/plain

Body:
Movie doesn't existCode language: plaintext (plaintext)

Costruzione di un oggetto risposta

I metodi di supporto forniti dalla classe ControllerBase sono convenienti e semplificano la creazione della risposta. Internamente, questi per lo più creano e restituiscono oggetti risultato (come StatusCodeResult). Puoi costruire tu stesso gli oggetti risultato, se lo desideri.

Ecco un esempio. Supponiamo che tu voglia restituire una risposta 500 senza contenuto. In questo caso, puoi restituire un ContentResult e impostare solo StatusCode.

using Microsoft.AspNetCore.Http;

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Save(Movie movie)
	{
		return new ContentResult()
		{
			StatusCode = StatusCodes.Status500InternalServerError
		};
	}
}
Code language: C# (cs)

Questo genera la risposta:

500 - Internal Server Error

Content-Length: 0Code language: plaintext (plaintext)

Sono disponibili diversi tipi di risultati tra cui scegliere (come StatusCodeResult, ContentResult, ObjectResult, ecc...). Di solito scelgo ContentResult.

Esempi di restituzione di altri codici di risposta

ControllerBase ha molti metodi di supporto che semplificano la restituzione delle risposte. In questa sezione, mostrerò esempi di restituzione di alcuni codici di risposta diversi utilizzando i metodi di supporto.

200 – OK

Se il tuo metodo restituisce un IActionResult, puoi restituire un 200 – OK risposta utilizzando il metodo di supporto Ok():

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Get(int id)
	{
		var movie = repository.GetMovie(id);
		return Ok(movie);
	}
}
Code language: C# (cs)

Questo genera la risposta:

200 - OK

Content-Type: application/json

Body:
{
    "title": "Dune",
    "yearReleased": 2021,
    "score": 9
}Code language: plaintext (plaintext)

400 – Richiesta errata

Per restituire un 400 – Richiesta errata risposta, puoi usare il metodo di supporto BadRequest():

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Save(Movie movie)
	{
		return BadRequest();
	}
}
Code language: C# (cs)

Questo genera la risposta:

400 - Bad Request

Content-Type: application/problem+json

Body:
{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "Bad Request",
    "status": 400,
    "traceId": "0HMDLM4FOTSV3:00000001"
}Code language: plaintext (plaintext)

Con contenuto personalizzato:

return BadRequest(error: new { errorCode=12345 });
Code language: C# (cs)

Questo genera la risposta:

400 - Bad Request

Content-Type: application/json

Body:
{
    "errorCode": 12345
}Code language: plaintext (plaintext)

Restituire qualsiasi codice di risposta

Non tutti i codici di risposta hanno i propri metodi di supporto (come Problem() per 500) o oggetti risultato (come BadRequestResult per 400). In questo caso, il modo più semplice per restituire qualsiasi codice di risposta è utilizzare il metodo di supporto StatusCode(), in questo modo:

using Microsoft.AspNetCore.Http;

[Route("[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
	[HttpPost]
	public IActionResult Save(Movie movie)
	{
		return StatusCode(StatusCodes.Status429TooManyRequests);
	}
}
Code language: C# (cs)

Questo genera la risposta:

429 - Too Many Requests

Content-Type: application/problem+json

Body:
{
    "status": 429,
    "traceId": "0HMDLMAQ7DNES:00000001"
}Code language: plaintext (plaintext)

Puoi modificare il contenuto tramite il parametro value:

return StatusCode(StatusCodes.Status429TooManyRequests, 
                value: "You've reached your limit for the day");
Code language: C# (cs)

Questo genera la risposta:

429 - Too Many Requests

Content-Type: text/plain

Body:
You've reached your limit for the dayCode language: plaintext (plaintext)