Analisar Aceitar cabeçalho
-
05-07-2019 - |
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.
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:
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" };
}
}