Como suportar verbos HTTP OPTIONS no aplicativo ASP.NET MVC / WebAPI
Eu configurei um aplicativo da Web ASP.NET começando com um modelo MVC 4 / Web API. Parece que as coisas estão funcionando muito bem - sem problemas que eu conheço. Eu usei o Chrome e o Firefox para percorrer o site. Eu testei usando o Fiddler e todas as respostas parecem estar no dinheiro.
Então, agora vou escrever um Test.aspx simples para consumir essa nova API da Web. As partes relevantes do script:
<script type="text/javascript">
$(function () {
$.ajax({
url: "http://mywebapidomain.com/api/user",
type: "GET",
contentType: "json",
success: function (data) {
$.each(data, function (index, item) {
....
});
}
);
},
failure: function (result) {
alert(result.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("An error occurred, please try again. " + textStatus);
}
});
});
</script>
Isso gera um cabeçalho REQUEST:
OPTIONS http://host.mywebapidomain.com/api/user HTTP/1.1
Host: host.mywebapidomain.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://mywebapidomain.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive
Como é, a API da Web retorna um 405 Method Not Allowed.
HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 13:28:12 GMT
Content-Length: 96
<Error><Message>The requested resource does not support http method 'OPTIONS'.</Message></Error>
Eu entendo que o verbo OPTIONS não está conectado em controladores de API da Web por padrão ... Então, coloquei o seguinte código no meu UserController.cs:
// OPTIONS http-verb handler
public HttpResponseMessage OptionsUser()
{
var response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
return response;
}
... e isso eliminou o erro 405 Method Not Allowed, mas a resposta está completamente vazia - nenhum dado é retornado:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 12:56:21 GMT
Content-Length: 0
Deve haver lógica adicional ... Não sei como codificar adequadamente o método Options ou se o controlador é o local adequado para colocar o código. Estranho (para mim) que o site da API da Web responda adequadamente quando visualizado a partir do Firefox ou do Chrome, mas a chamada .ajax está acima dos erros. Como manejo a verificação "preflight" no código .ajax? Talvez eu devesse estar abordando esse problema na lógica .ajax do lado do cliente? Ou, se isso é um problema no lado do servidor devido a não lidar com o verbo OPTIONS.
Alguém pode ajudar? Este deve ser um problema muito comum e peço desculpas se ele foi respondido aqui. Eu procurei, mas não encontrei nenhuma resposta que ajudasse.
ATUALIZAR IMHO, este é um problema do lado do cliente e tem a ver com o código Ajax JQuery acima. Digo isso porque o Fiddler não mostra nenhum cabeçalho de erro 405 quando acesso o mywebapidomain / api / user a partir de um navegador da web. O único local onde posso duplicar esse problema é a chamada .jajax () do JQuery. Além disso, a chamada Ajax idêntica acima funciona bem quando executada no servidor (mesmo domínio).
Eu encontrei outro post:Solicitação de protótipo AJAX sendo enviada como OPTIONS em vez de GET; resulta em erro 501 que parece estar relacionado, mas eu mexi com as sugestões deles sem sucesso. Aparentemente, o JQuery é codificado de forma que, se uma requisição Ajax for cross domain (qual é a minha), ela adiciona alguns headers que acionam o header OPTIONS de alguma forma.
'X-Requested-With': 'XMLHttpRequest',
'X-Prototype-Version': Prototype.Version,
Parece que deveria haver uma solução melhor disponível do que modificar o código principal no JQuery ...
A resposta fornecida abaixo assume que isso é um problema do lado do servidor. Talvez, eu acho, mas eu me inclino para o cliente e chamar um provedor de hospedagem não vai ajudar.