405 Метод не разрешен для WebAPI2 (OWIN)

Я настраиваю конечную точку WebAPI для своего API, но мне трудно получить мои вызовы AngularJS для моего метода PostRegister.

WebAPI и Angular находятся на отдельных сайтах.

В Startup.cs у меня есть:

    public void Configuration(IAppBuilder app)
    {
        ConfigureOAuth(app);

        var config = new HttpConfiguration();

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);

    }

    private void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString(Paths.TokenPath),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = Kernel.Get<IOAuthAuthorizationServerProvider>()
        };
        app.UseOAuthAuthorizationServer(oAuthServerOptions); 

        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    }

Затем на контроллере у меня есть мой метод, который позволяет анонимно:

    [AllowAnonymous]
    public bool PostRegister(UserSignupForm form)
    {
        ...
    }

Я также обновил web.config:

 <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>

На стороне Angular я делаю простой вызов $http.post:

    saveRegistration: function (registration) {
        return $http.post(baseUrl + '/api/signup/register', registration).then(function (response) {
            return response;
        });
    }

При выполнении вызова с использованием почтового оператора я получаю успешный ответ, но при выполнении того же вызова из Angular я получаю ошибку 405.

405 Method Not Allowed

Сайт образца BitOfTech отправляет одни и те же заголовки запросов, но может получить заголовки Access-Control-Allow-XXX

enter image description here

Я обновил свой код, чтобы выполнить Аутентификация на основе токена с использованием ASP.NET Web API 2, Owin и Identity

Ответы

Ответ 1

У меня была аналогичная проблема в последнее время. Я добавил обработчик контроллера для запроса перед полетом OPTIONS, и он решил проблему.

[AllowAnonymous]
[Route("Register")]
[AcceptVerbs("OPTIONS")]
public async Task<IHttpActionResult> Register()
{
    return Ok();
}

Ответ 2

Вам может потребоваться разрешить корс в приложении для заголовков ответов. Ниже приведен пример того, что я делаю в node.

res.header('Access-Control-Allow-Origin', '*');

res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS"); 

res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

Это может вам помочь. Спасибо.

Ответ 3

Проблема не с angular. Хотя вы получаете ответ в Postman, его проблема не в angular, что этот запрос не дает вам ответа. Проблема по умолчанию Postman не публикует Origin attribute, который необходим для тестирования CORS. Chrome по умолчанию блокирует атрибут Origin, поэтому запрос не обрабатывается, как если бы он поступал из другого домена.

Итак, как тестировать CORS в Postman

вам понадобится другое расширение chrome с тем же именем POSTMAN - клиент для отдыха (упакованное приложение) и используйте его переключатель toTouch to Interceptor ', чтобы он мог отправлять атрибут ORIGIN.

читайте здесь, раздел restricted header

ниже приведен пример экрана, когда вы не отправляете атрибуты ORIGIN

WITHOUT ORIGIN

и ответ одного и того же запроса в POSTMAN при отправке атрибута ORIGIN

WITH ORIGIN

поэтому, если вы увидите, когда вы добавляете источник, это только тогда, когда вы получите атрибуты ACCESS-CONTROL- * в ответ.

Я надеюсь, что это также ответит на ваш запрос о

Сайт образца BitOfTech отправляет те же заголовки запросов, но способный получить заголовки Access-Control-Allow-XXX "

Веб-часть Api

Возвращаясь к вашему делу, у вас нет CORS в веб-api. Сначала включите CORS в web-api. Чтобы включить CORS во всем мире, используйте

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.example.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}

- вы можете найти множество ресурсов вокруг сети о том, как добавить их на уровне контроллера и т.д.

Angular Часть

сначала вам нужно убедиться, что CORS работает в POSTMAN, а затем попытайтесь получить доступ к этому URL-адресу в angular.

чтобы включить cors в angular, вам понадобится код ниже в вашей функции app.config().

myApp.config(function($httpProvider) {
  $httpProvider.defaults.useXDomain = true;
  delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

Примечание. Для экспертов

Origin attributes is needed to test CORS. Я не очень уверен в этой части, но, похоже, это касается ответа, который я вижу в Postman. Было бы здорово, если бы кто-нибудь мог пролить свет на роль Origin attribute в Корсе.

Ответ 4

Это похоже на проблему с перекрестным происхождением. Вы должны установить Fiddler и проверить, вызван ли ответ 405 запросом перед полетом (глагол OPTIONS), который выдается браузером при вызове ресурса в другом источнике.

См. эту статью для приятного объяснения CORS: http://www.html5rocks.com/en/tutorials/cors/

Ответ 5

Я считаю, что вы не замечаете аннотации на вашем API-контроллере, вы должны добавить аннотацию к APIController как

[RoutePrefix("api/signup")]

В противном случае ваш WebApiConfig должен иметь маршрут, определяющий как ниже

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

И для установки CORS вам всегда нужно отправлять свои учетные данные при каждом вызове на сервер. Тогда есть простой способ сделать это в angular, установив опцию поставщика $http.

Вы можете сделать это на этапе конфигурации angular.

CODE

  angular.module('myApp',[])
    .config([
        '$httpProvider',
        function($httpProvider) {
            $httpProvider.defaults.withCredentials = true;
        }
    ]);

Выше настройки добавят учетные данные в каждом вызове $http.

Также отправьте сообщение this. Какая же проблема.

Это может помочь решить вашу проблему. Спасибо.