Pergunta

Alguém tem alguma sugestão (ou uma expressão regular) para analisar o cabeçalho HTTP Accept?

Eu estou tentando fazer algum tipo de conteúdo negociação no ASP.NET MVC. Não parece ser construído em um caminho (o que é bom, porque há um monte de escolas de pensamento aqui), mas a análise não é inteiramente trivial e eu preferia não re-inventar a roda se alguém já fez -lo bem e está disposto a compartilhar.

Foi útil?

Solução

Você viu este artigo ? Dá uma implementação bastante abrangente para analisar o cabeçalho Accept e, posteriormente, fazer algo útil com ele.

Outras dicas

A partir do .NET 4.5 (acho-Microsoft fizeram informações sobre versões quadro <4,5 vez obscurecer estes dias), você pode usar um dos construído em analisadores de System.Net.Http.Headers:

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

Em seguida, você pode fazer algo como isto:

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

Dar-lhe uma boa lista de todos os tipos de mídia, onde o preferido opção é o primeiro item. Aqui está uma Dump LINQPad do resultado mediaTypes do exemplo:

LINQPad despejo de resultados

Hat dica para esta resposta , por me no caminho certo.

Eu escrito uma analisador em PHP. Não é complexo, mas ele vai te dar uma matriz de tipos mime em ordem de preferência.

Encontrado outra implementação em php aqui

Depois de ler o artigo xml.com eu decidi não escrever uma função para o cabeçalho Accept-me;)

Felizmente os artigo aponta para uma biblioteca boa: https://code.google.com/p/ mimeparse / - no meu caso eu precisar dele como um módulo Node.js: https://github.com / kriskowal / mimeparse

O RFC é bastante complexa. Se a regex onde seguir estas regras ao pé da letra, que se tornaria várias linhas.

Se você já tem o cabeçalho Accept, e ignorar as cotações e os parâmetros, você poderia fazer algo assim para combinar cada par:

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

* está incluído na classe de personagem, por isso não precisa de nenhum caso especial na expressão regular.

Com base na https://stackoverflow.com/a/49011308/275501 de https://stackoverflow.com/users/43140/mark-bell acima:

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top