Запрос предварительной проверки возвращает 404 Not Found для контроллеров в области

1

У меня есть проект WebAPI, и я включил CORS, выполнив следующие шаги:

  1. Получите пакет nuget: Install-Package Microsoft.AspNet.WebApi.Cors.
  2. Добавлен config.EnableCors(); к WebApiConfig.cs.
  3. Добавлено [EnableCors(origins: "*", headers: "*", methods: "*")] к моему контроллеру.

У меня есть контроллеры, которые находятся в папке корневых контроллеров и внутри области.

/Controllers/ValuesController
/Areas/TestArea/Controllers/OtherStuffController

Оба контроллера имеют [EnableCors(...)].

Моя проблема в том, что работает только ValuesController.

Используя Fiddler для проверки запросов для OtherStuffController я вижу, что клиент отправляет запрос предварительной OtherStuffController OPTIONS, но ответы сервера с 404 не найдены вместо 200 OK, но ValuesController отлично работает.

Что я делаю не так? Почему контроллер в области TestArea не работает с запросами CORS, но контроллер Values делает это?

Нет ничего особенного в двух контроллерах, кроме имени, и что это в области.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Маршруты:

// In WebApiConfig.cs
config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", 
    new {id = RouteParameter.Optional} );

// In Areas/TestArea/TestAreaAreaRegistration.cs
context.MapRoute("TestArea_default","TestArea/{controller}/{id}",
    new {id = UrlParameter.Optional});

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

http://localhxst:57578/values
http://localhxst:57578/testarea/otherstuff

Запрос значений (рабочий):

(REQUEST)
OPTIONS http://localhost:57578/values HTTP/1.1
Host: localhost:57578
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhxst:12345
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Connection: keep-alive

(RESPONSE)
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: authorization
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYmVuLmdvbGRlblxEb2N1bWVudHNcV29ya1xWb2ljZVNpbXBsaWZpZWRcQVBJXFZvaWNlU2ltcGxpZmllZC5QdWJsaWNBUElcdmFsdWVz?=
X-Powered-By: ASP.NET
Date: Thu, 24 Jul 2014 20:12:56 GMT
Content-Length: 0

С последующим:

(REQUEST)
GET http://localhxst:57578/values HTTP/1.1
Host: localhost:57578
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0
Accept: application/json
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Bearer HQkpyzeQ5NM1Va1Ow__6N6JzuRdMweDIJDneDQer1tL1uMhkrG4gsRYkXLQ1F4782L5vDTMOkoqvOEtO753n6TJ2BU-KNaxdXRAtf336c-r8MXMi_nWliw1vT1Xa7Wmt3eV5b9HmJR4Bnmt4gTavtoC0qwQVsoX_miV_VanJ98j_aaoNdNNZcnN5FsJ2eoLx7UebBDxXBMFmXEtOUTtWCsRp-g26mwKjbK3HeDoiUU2Ivh-VleUVImdh9ASwInbZ
Referer: http://localhxst:12345/
Origin: http://localhxst:12345
Connection: keep-alive    

(RESPONSE)
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: *
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYmVuLmdvbGRlblxEb2N1bWVudHNcV29ya1xWb2ljZVNpbXBsaWZpZWRcQVBJXFZvaWNlU2ltcGxpZmllZC5QdWJsaWNBUElcdmFsdWVz?=
X-Powered-By: ASP.NET
Date: Thu, 24 Jul 2014 20:12:56 GMT
Content-Length: 13

["ABC","DEF"]

Запрос OtherStuff (прожектор не прошел):

(REQUEST)
OPTIONS http://localhxst:57578/testarea/otherstuff HTTP/1.1
Host: localhost:57578
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:12345
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Connection: keep-alive

(RESPONSE)
HTTP/1.1 404 Not Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYmVuLmdvbGRlblxEb2N1bWVudHNcV29ya1xWb2ljZVNpbXBsaWZpZWRcQVBJXFZvaWNlU2ltcGxpZmllZC5QdWJsaWNBUElcdGVzdGFyZWFcb3RoZXJzdHVmZg==?=
X-Powered-By: ASP.NET
Date: Thu, 24 Jul 2014 20:35:08 GMT
Content-Length: 3194
<!DOCTYPE html>
<html>
    <head>
        <title>The resource cannot be found.</title>
        <meta name="viewport" content="width=device-width" />
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
         pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
         @media screen and (max-width: 639px) {
          pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
         }
         @media screen and (max-width: 479px) {
          pre { width: 280px; }
         }
        </style>
    </head>

    <body bgcolor="white">

            <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>

            <h2> <i>The resource cannot be found.</i> </h2></span>

            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Description: </b>HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. &nbsp;Please review the following URL and make sure that it is spelled correctly.
            <br><br>

            <b> Requested URL: </b>/testarea/otherstuff<br><br>

            <hr width=100% size=1 color=silver>

            <b>Version Information:</b>&nbsp;Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34009

            </font>

    </body>
</html>
<!-- 
[HttpException]: The controller for path &#39;/testarea/otherstuff&#39; was not found or does not implement IController.
   at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
   at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
   at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
-->

ValuesController.cs

namespace MyAPIApp.PublicAPI.Controllers
{

    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [Authorize]
    public class ValuesController : ApiController
    {
        private static readonly List<string> values = new List<string> { "ABC", "DEF" };

        public IEnumerable<string> Get() { return values; }
    }
}

OtherStuffController.cs

namespace MyAPIApp.PublicAPI.Areas.TestArea.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [Authorize]
    public class OtherStuffController : ApiController
    {
        private static readonly List<string> values = new List<string> { "ABC", "DEF" };

        public IEnumerable<string> Get() { return values; }
    }
}
  • 0
    Можете ли вы опубликовать URI, которые вы пытаетесь запросить, без домена?
  • 0
    И конфиг маршрутизации поможет.
Показать ещё 3 комментария
Теги:
asp.net-web-api
cors
preflight
asp.net-mvc-areas

1 ответ

4
Лучший ответ

Я нашел проблему.

Когда вы создаете область в проекте через контекстное меню "Добавить"> "Область", Visual Studio создает область с шаблоном AreaRegistration, используя следующий код:

public override void RegisterArea(AreaRegistrationContext context) {
    context.MapRoute(
        "TestArea_default",
        "TestArea/{controller}/{id}",
        new {id = UrlParameter.Optional}
        );
}

Однако этот код не подходит для ApiControllers. Правильный код регистрации маршрута:

public override void RegisterArea(AreaRegistrationContext context) {

    context.Routes.MapHttpRoute(
        "TestArea_default", 
        "TestArea/{controller}/{id}", 
        new { id = RouteParameter.Optional });
}

Оказывается, это не имеет ничего общего с CORS.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню