2016-04-06 4 views
3

У меня есть Web Api 2 бэкэнд на Azure и AngularJs forntend. Я понимаю, что некоторые из HTTP request используют предварительную проверку с OPTIONS request. Мой вопрос заключается в том, как реализовать backend таким образом, чтобы все OPTIONS requests вернули 200, если в контроллере есть какое-то действие, которое будет обрабатывать следующие GET/POST/PUT/DELETE/....Web Api 2 Ручка ОПЦИИ Запросы

ответ

8

Номера элегантный способ решения этой задачи является добавление в каждом контроллере вручную

[AcceptVerbs("OPTIONS")] 
public HttpResponseMessage Options() 
{ 
    var resp = new HttpResponseMessage(HttpStatusCode.OK); 
    resp.Headers.Add("Access-Control-Allow-Origin", "*"); 
    resp.Headers.Add("Access-Control-Allow-Methods", "GET,DELETE"); 

    return resp; 
} 

или переопределить MessageHandlers

public class OptionsHttpMessageHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
    if (request.Method == HttpMethod.Options) 
     { 
     var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer(); 

      var controllerRequested = request.GetRouteData().Values["controller"] as string;    
      var supportedMethods = apiExplorer.ApiDescriptions.Where(d => 
      { 
       var controller = d.ActionDescriptor.ControllerDescriptor.ControllerName; 
       return string.Equals(
        controller, controllerRequested, StringComparison.OrdinalIgnoreCase); 
      }) 
      .Select(d => d.HttpMethod.Method) 
      .Distinct(); 

     if (!supportedMethods.Any()) 
     return Task.Factory.StartNew(
      () => request.CreateResponse(HttpStatusCode.NotFound)); 

     return Task.Factory.StartNew(() => 
     { 
      var resp = new HttpResponseMessage(HttpStatusCode.OK); 
      resp.Headers.Add("Access-Control-Allow-Origin", "*"); 
      resp.Headers.Add(
       "Access-Control-Allow-Methods", string.Join(",", supportedMethods)); 

      return resp; 
     }); 
} 

return base.SendAsync(request, cancellationToken); 

    } 
} 

, а затем в конфигурации

GlobalConfiguration.Configuration.MessageHandlers.Add(new OptionsHttpMessageHandler()); 

даже второй вариант не идеален, хотя ... нет встроенного встроенного носителя

+1

Спасибо, работает :) –

+0

вы радушны) – Vladimir

+1

или наследовать от собственного базового класса, который содержит ваши варианты общественного HttpResponseMessage() метод: общественный класс BaseApiController абстрактного: ApiController –

0

У меня была такая же проблема, как и вы, так называемый запрос предпросмотра, и я понял, что это может быть связано с неправильной конфигурацией в Интернете. Conf file. Прокомментируйте или удалите, если имеется, строку, содержащую «удалить» OPTIONSVerbHandler.

<system.webServer> 
<handlers> 
     <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
     <!--<remove name="OPTIONSVerbHandler" /> --> 
     <remove name="TRACEVerbHandler" /> 
     <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 
</system.webServer>