tutorial net example consumir asp c# asp.net-web-api httprequest

c# - net - ¿Cómo extraer el valor del encabezado personalizado en el controlador de mensajes Web API?



web api rest c# (8)

Cree un nuevo método: '' Devuelve un valor de encabezado HTTP individual '' y llame a este método con valor de clave cada vez que necesite acceder a múltiples valores clave desde HttpRequestMessage.

public static string GetHeader(this HttpRequestMessage request, string key) { IEnumerable<string> keys = null; if (!request.Headers.TryGetValues(key, out keys)) return null; return keys.First(); }

Actualmente tengo un controlador de mensajes en mi servicio Web API que reemplaza a ''SendAsync'' de la siguiente manera:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { //implementation }

Dentro de este código, debo inspeccionar un valor de encabezado de solicitud personalizado agregado llamado MyCustomID . El problema es cuando hago lo siguiente:

if (request.Headers.Contains("MyCustomID")) //OK var id = request.Headers["MyCustomID"]; //build error - not OK

... Recibo el siguiente mensaje de error:

No se puede aplicar la indexación con [] a una expresión de tipo ''System.Net.Http.Headers.HttpRequestHeaders''

¿Cómo puedo acceder a un único encabezado de solicitud personalizado a través de la instancia HttpRequestMessage ( Documentación MSDN ) pasada a este método reemplazado?


La siguiente línea throws exception si la clave no existe.

IEnumerable<string> headerValues = request.Headers.GetValues("MyCustomID");

Trabaja alrededor:

Incluir System.Linq;

IEnumerable<string> headerValues; var userId = string.Empty; if (request.Headers.TryGetValues("MyCustomID", out headerValues)) { userId = headerValues.FirstOrDefault(); }


Para ASP.NET, puede obtener el encabezado directamente del parámetro en el método del controlador usando esta biblioteca / paquete simple . Proporciona un atributo [FromHeader] como el que tiene en ASP.NET Core :). Por ejemplo:

... using RazHeaderAttribute.Attributes; [Route("api/{controller}")] public class RandomController : ApiController { ... // GET api/random [HttpGet] public IEnumerable<string> Get([FromHeader("pages")] int page, [FromHeader] string rows) { // Print in the debug window to be sure our bound stuff are passed :) Debug.WriteLine($"Rows {rows}, Page {page}"); ... } }


Para ASP.Net Core existe una solución fácil si desea usar el parámetro directamente en el método del controlador: Use la anotación [FromHeader].

public JsonResult SendAsync([FromHeader] string myParam) { if(myParam == null) //Param not set in request header { return null; } return doSomething(); }

Información adicional: en mi caso, el "myParam" tenía que ser una cadena, int siempre era 0.


Para ampliar aún más la solución de @neontapir, aquí hay una solución más genérica que se puede aplicar a HttpRequestMessage o HttpResponseMessage por igual y no requiere expresiones codificadas a mano o funciones.

using System.Net.Http; using System.Collections.Generic; using System.Linq; public static class HttpResponseMessageExtensions { public static T GetFirstHeaderValueOrDefault<T>( this HttpResponseMessage response, string headerKey) { var toReturn = default(T); IEnumerable<string> headerValues; if (response.Content.Headers.TryGetValues(headerKey, out headerValues)) { var valueString = headerValues.FirstOrDefault(); if (valueString != null) { return (T)Convert.ChangeType(valueString, typeof(T)); } } return toReturn; } }

Uso de muestra:

var myValue = response.GetFirstHeaderValueOrDefault<int>("MyValue");


Para ampliar la respuesta de Youssef, escribí este método basado en las preocupaciones de Drew sobre el encabezado inexistente, porque me encontré con esta situación durante la prueba unitaria.

private T GetFirstHeaderValueOrDefault<T>(string headerKey, Func<HttpRequestMessage, string> defaultValue, Func<string,T> valueTransform) { IEnumerable<string> headerValues; HttpRequestMessage message = Request ?? new HttpRequestMessage(); if (!message.Headers.TryGetValues(headerKey, out headerValues)) return valueTransform(defaultValue(message)); string firstHeaderValue = headerValues.FirstOrDefault() ?? defaultValue(message); return valueTransform(firstHeaderValue); }

Aquí hay un ejemplo de uso:

GetFirstHeaderValueOrDefault("X-MyGuid", h => Guid.NewGuid().ToString(), Guid.Parse);

También eche un vistazo a la respuesta de @ doguhan-uluca para una solución más general.


Pruebe algo como esto:

IEnumerable<string> headerValues = request.Headers.GetValues("MyCustomID"); var id = headerValues.FirstOrDefault();

También hay un método TryGetValues ​​en los encabezados que puede usar si no siempre se garantiza el acceso al encabezado.


request.Headers.FirstOrDefault( x => x.Key == "MyCustomID" ).Value?.FirstOrDefault()

variante moderna :)