Pregunta

¿Alguien tiene alguna sugerencia (o una expresión regular) para analizar el encabezado HTTP Accept?

Estoy tratando de hacer una negociación de tipo de contenido en ASP.NET MVC. No parece haber una forma integrada (lo cual está bien, porque hay muchas escuelas de pensamiento aquí), pero el análisis no es del todo trivial y preferiría no reinventar la rueda si alguien ya lo ha hecho. bien y está dispuesto a compartir.

¿Fue útil?

Solución

¿Has visto este artículo ? Proporciona una implementación bastante completa para analizar el encabezado Aceptar y, posteriormente, hacer algo útil con él.

Otros consejos

A partir de .NET 4.5 (creo que & # 8212; Microsoft ha hecho información sobre las versiones de framework < 4.5 bastante oscuro en estos días), puede usar uno de los analizadores integrados de System.Net.Http.Headers :

public IOrderedEnumerable<MediaTypeWithQualityHeaderValue> GetMediaTypes(string headerValue) =>
    headerValue?.Split(',')
        .Select(MediaTypeWithQualityHeaderValue.Parse)
        .OrderByDescending(mt => mt.Quality.GetValueOrDefault(1));

Entonces puedes hacer algo como esto:

var headerValue = "application/json, text/javascript, */*; q=0.01";
var mediaTypes = GetMediaTypes(headerValue);

Dándole una buena lista de todos los tipos de medios, donde la opción preferida es el primer elemento. Aquí hay un LINQPad Dump del resultado mediaTypes del ejemplo:

 LINQPad volcado de resultados

Sugerencia para esta respuesta , por ponerme en el camino correcto.

He ha escrito un analizador en PHP. No es complejo, pero le dará una variedad de tipos MIME en orden de preferencia.

Encontramos otra implementación en php aquí

Después de leer el artículo xml.com decidí no escribir una función para el encabezado Aceptar;)

Afortunadamente, el artículo apunta a una buena biblioteca: https://code.google.com/p/ mimeparse / : en mi caso, lo necesito como un módulo Node.js: https://github.com / kriskowal / mimeparse

El RFC es bastante complejo. Si la expresión regular dónde seguir estas reglas al pie de la letra, se convertiría en varias líneas de largo.

Si ya tiene el encabezado Accept, e ignora las comillas y los parámetros, podría hacer algo como esto para que coincida con cada par:

/([^()<>@,;:\\"\/[\]?={} \t]+)\/([^()<>@,;:\\"\/[\]?={} \t]+)/

* está incluido en la clase de caracteres, por lo que no necesita ningún caso especial en la expresión regular.

Basándose en https://stackoverflow.com/a/49011308/275501 de https://stackoverflow.com/users/43140/mark-bell arriba:

public class MyController : Controller
{

    [HttpGet]
    [Route("/test")]
    public ActionResult Index() {

        // does this request accept HTML?
        var acceptsHTML = IsAcceptable("text/html");
        var model = FetchViewModel();
        return acceptsHTML ? (ActionResult) View(model) : Ok(model);

    }

    private bool IsAcceptable(string mediaType) =>
        Request.Headers["Accept"].Any(headerValue =>
            !string.IsNullOrWhiteSpace(headerValue) &&
            headerValue.Split(",").Any(segment => MediaTypeHeaderValue.Parse(segment).MediaType == mediaType));

    private object FetchViewModel() {

        return new { Description = "To be completed" };

    }

}    
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top