ASP.NET Core:come ottenere le intestazioni delle richieste

ASP.NET Core:come ottenere le intestazioni delle richieste

Esistono due modi per ottenere le intestazioni delle richieste:

  • Usa il dizionario Request.Headers.
  • Usa [FromHeader].

Quando arriva una richiesta, il framework carica le intestazioni della richiesta nel dizionario Request.Headers. Puoi usarlo come qualsiasi altro dizionario. Ecco un esempio di utilizzo di TryGetValue() per verificare se esiste un'intestazione di richiesta e ottenerne il valore:

[HttpGet]
public IActionResult Get()
{
	if (Request.Headers.TryGetValue("testId", out var testId))
	{
		//use testId value
	}

	return Ok();
}
Code language: C# (cs)

Nota:per verificare se esiste un'intestazione, utilizza Request.Headers.ContainsKey(“testId”).

L'altra opzione è utilizzare l'attributo [FromHeader], che mostrerò di seguito.

Utilizzo di [FromHeader]

È possibile utilizzare l'attributo [FromHeader] per mappare automaticamente le intestazioni delle richieste ai parametri (o alle proprietà del modello). Li mappa facendo corrispondere la chiave dell'intestazione della richiesta con il nome del parametro.

Ecco un esempio di come utilizzare [FromHeader]:

[HttpGet]
public IActionResult Get([FromHeader] int? testId)
{
	//use testId
	Console.WriteLine($"Got testId={testId}");

	return Ok();
}
Code language: C# (cs)

Ora invia una richiesta con un'intestazione:

GET /movie/
TestId: 2022
..other headers...
Code language: plaintext (plaintext)

Emette quanto segue, mostrando che ha mappato il TestId intestazione a testId parametro:

Got testId=2022Code language: plaintext (plaintext)

Due cose da notare:

  • Esegue la corrispondenza dei nomi senza distinzione tra maiuscole e minuscole (es:TestId corrisponde a testId).
  • I valori dell'intestazione sono stringhe, ma puoi associarli a parametri con tipi diversi (es:int). Proverà a convertire il valore dell'intestazione in quel tipo per te.

Ciò consente di risparmiare un po' di sforzo di codifica rispetto all'utilizzo manuale di Request.Headers.

Convalida

Uno dei vantaggi dell'utilizzo di [FromHeader] è che il framework eseguirà la convalida. Se usi Request.Headers manualmente, devi eseguire tu stesso la logica di convalida.

Ad esempio, quando si utilizza [FromHeader] su un parametro non stringa, è necessario convertire il valore dell'intestazione nel tipo. In caso contrario, restituirà un errore di convalida (400 – Richiesta non valida ), in questo modo:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "0HMHV7HKJOJBG:00000002",
    "errors": {
        "": [
            "The value 'a' is not valid."
        ]
    }
}
Code language: JSON / JSON with Comments (json)

Nota:questo messaggio di errore è privo di informazioni contestuali (come il nome del parametro), ma è meglio di niente.

Puoi aggiungere attributi aggiuntivi per fare più convalida. Ad esempio, supponiamo che tu voglia richiedere un'intestazione di richiesta. Oltre a controllare se il parametro nullable è nullo o controllare Request.Headers, puoi inserire l'attributo [Required] nel parametro:

[HttpGet]
public IActionResult Get([Required][FromHeader]int testId)
Code language: C# (cs)

Quando l'intestazione richiesta non viene inviata, riceverai un errore come questo:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "0HMHV98CF5VDC:00000002",
    "errors": {
        "testId": [
            "The testId field is required."
        ]
    }
}
Code language: JSON / JSON with Comments (json)

Intestazioni con più valori

Le intestazioni possono avere più valori. Se ti aspetti più valori, usa un parametro array in modo che mapperà automaticamente i valori nell'array.

Ad esempio, supponiamo che la tua richiesta abbia un'intestazione con più valori (TestName ha due valori) :

GET /employee/
TestName: Bob
TestName: Alice
..other headers...
Code language: plaintext (plaintext)

Per mappare automaticamente questi valori, aggiungi un parametro array e usa [FromHeader]:

[HttpGet]
public IActionResult Get([FromHeader] string[] testName)
{
	//use testNames
	Console.WriteLine($"Got test names: {String.Join(" ", testName)}");

	return Ok();
}
Code language: C# (cs)

Questo produce quanto segue:

Got test names: Bob AliceCode language: plaintext (plaintext)

Avviso:se stai utilizzando un parametro stringa (non un array), mapperà i valori multipli alla stringa come valori separati da virgole (ad esempio "Bob,Alice"). Questo può essere sorprendente.

Mappatura di un'intestazione a un parametro con un nome diverso

Per impostazione predefinita, le intestazioni delle richieste sono mappate ai parametri con lo stesso nome. Se desideri mappare un'intestazione di richiesta a un parametro con un nome diverso, utilizza il Nome parametro con [FromHeader].

Ad esempio, supponiamo di voler mappare un'intestazione denominata TestId a un parametro denominato id . Ecco come farlo:

[HttpGet]
public IActionResult Get([FromHeader(Name = "TestId")] string id)
{
	//use id
	Console.WriteLine($"Got id={id}");

	return Ok();
}
Code language: C# (cs)

Ora invia una richiesta con l'intestazione:

GET /test/
TestId: Test1234
Code language: plaintext (plaintext)

Questo produce quanto segue:

Got id=Test1234Code language: plaintext (plaintext)

Mappatura alle proprietà del modello

È possibile mappare automaticamente le intestazioni delle richieste alle proprietà del modello utilizzando [FromHeader]. Devi aggiungerlo alle proprietà del modello e al parametro del modello.

Ecco un esempio. Innanzitutto, aggiungi [FromHeader] alle proprietà del modello:

using Microsoft.AspNetCore.Mvc;

public class Person
{
	[FromHeader]
	public string Name { get; set; }
}
Code language: C# (cs)

Quindi aggiungi [FromHeader] al parametro del modello:

[HttpPost]
public IActionResult Post([FromHeader]Person person)
{
	//do something with model
	Console.WriteLine($"Got name={person.Name}");

	return Ok();
}
Code language: C# (cs)

Ora invia una richiesta con le intestazioni:

POST /person/
Name: Bob
Code language: plaintext (plaintext)

Questo restituisce il valore dell'intestazione mappata:

Got name=Bob

Scorrere le intestazioni della richiesta

Ecco come scorrere tutte le intestazioni delle richieste:

[HttpGet]
public IActionResult Get()
{
	foreach(var header in Request.Headers)
	{
		Console.WriteLine($"{header.Key}={header.Value}");
	}

	return Ok();
}
Code language: C# (cs)

Questo è principalmente utile per scopi di debug o registrazione.

Ottenere le intestazioni delle richieste in un filtro di azione o in un middleware

Nei filtri del middleware e delle azioni, puoi accedere alle intestazioni delle richieste tramite HttpContext.Request.Headers. Ecco alcuni esempi di codice:

  • Verifica di un'intestazione richiesta in un filtro azione.
  • Verifica di un'intestazione di flag di debug nel middleware.