it-roy-ru.com

ASP.NET MVC WebAPI 404 ошибка

У меня есть приложение веб-форм asp.net, работающее в интегрированном режиме v4.0.

Я попытался добавить apicontroller в папку App_Code. 

В Global.asax я добавил следующий код

 RouteTable.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "api/{controller}/{id}",
      defaults: new { id = System.Web.Http.RouteParameter.Optional }
 );

Когда я пытался перейти к контроллеру в http://localhost/api/Value, я получаю ошибку 404.

URL-адрес без расширения настраивается в разделе обработчика. У меня есть формы и анонимная аутентификация для веб-сайта. 

URL-адрес ExtensionLess настроен для «*.»

Когда я нажимаю URL для контроллера, запрос обрабатывается StaticHandler вместо ExtensionlessUrlHandler-Integrated-4.0. 

Теперь я понятия не имею, почему система выдаст ошибку, как показано на рисунке ниже .Error

59
Suneel Dixit

Я испытывал эту проблему.

Я попытался отредактировать свой WebApiConfig.cs, чтобы выполнить ряд рекомендаций здесь и примеры кода в другом месте. Некоторые работали, но это не объясняло, почему маршрут не работал, когда WebApiConfig.cs был закодирован точно в соответствии с проектом MS-шаблона WebApi.

Моя настоящая проблема заключалась в том, что при добавлении WebApi вручную в мой проект я не следовал стандартному порядку вызовов конфигурации из Global.asax

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        // This is where it "should" be
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        // The WebApi routes cannot be initialized here.
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

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

107
shannon

Проблема в вашей конфигурации маршрутизации. Маршрутизация Mvc отличается от маршрутизации WebApi.

Добавьте ссылку на System.Web.Http.dll, System.Web.Http.Webhost.dll и System.Net.Http.dll, а затем настройте маршрутизацию API следующим образом: 

   GlobalConfiguration.Configuration.Routes.MapHttpRoute(
     name: "DefaultApi",
     routeTemplate: "api/{controller}/{id}",
     defaults: new { id = System.Web.Http.RouteParameter.Optional }
   );
32
Alborz

Убедитесь, что следующие вещи

1.) Убедитесь, что ваш IIS настроен на .NET 4.5 или 4.0, если ваш веб-интерфейс API равен 4.5, установите 4.5 в IIS 

запустить эту команду в командной строке с правами администратора

C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regiis.exe -i

2.) Измените ваш маршрут на 

RouteTable.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "{controller}/{id}",
      defaults: new { id = System.Web.Http.RouteParameter.Optional }
 );

и сделайте запрос с помощью Demo/Get (где demo - имя вашего контроллера)

если 1,2 не работают, попробуйте 3

3.) Добавьте следующую конфигурацию в файл web.config

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />

</system.webServer>
16
Binson Eldhose

Кроме того, убедитесь, что ваш контроллер оканчивается именем «Контроллер», как в «PizzaPieController».

9
Eric W.

Я попробовал все вышеперечисленное, и у меня возникла та же проблема. Оказалось, что пул приложений, созданный в IIS, по умолчанию установлен на .net 2.0. Когда я поменял на 4.0 то опять заработало

7
Alan

Если вы создаете контроллер в App_Code, как таблица маршрутизации узнает, где он находится? Вы указали маршрут как «api/{controller/...», но это не то место, где расположен контроллер. Попробуйте переместить его в нужную папку.

2
crunchy

Спасибо Шеннон, отлично работает =>

Мой заказ в моем Global.asax был:

GlobalConfiguration.Configure(WebApiConfig.Register);  
RouteConfig.RegisterRoutes(RouteTable.Routes);

вместо хорошего 

RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register); 
2
ceinpap

После нескольких часов, проведенных на этом, я нашел решение этой проблемы в моем случае.

Это был порядок регистрации маршрутов в RouteConfig

Мы должны зарегистрировать HttpRoute в таблице маршрутов перед маршрутом контроллера по умолчанию. Это должно быть следующим. Конфигурация маршрута Конфигурация таблицы маршрутов

  public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapHttpRoute(
             name: "DefaultApi",
             routeTemplate: "api/{controller}/{action}/{id}",
             defaults: new { id = RouteParameter.Optional }
         );
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

    }
}
2
Shri Guru

Также попробуйте удалить все содержимое папки api bin. Мой содержал старые dll (из-за переименования большого пространства имен), обнажая конфликтующие контроллеры. Эти dll не были удалены функцией очистки Visual Studio.

(Тем не менее, я считаю, что веб-интерфейсу asp.net не хватает информации о маршрутизации и отладке на уровне отладки).

2
Simon Budin

Для URL, который вы пытаетесь (http://localhost/api/Value), убедитесь, что есть открытый тип с именем ValueController, который наследуется от ApiController и имеет открытый метод с некоторыми из этих характеристик: 

  • Имя метода начинается с Get (например, GetValues или просто Get).
  • К методу применяется атрибут HttpGet.

Если вы пытаетесь использовать код из шаблона проекта Web API по умолчанию, имя контроллера - ValuesController, а не ValueController, поэтому URL-адрес будет http://localhost/api/values.

Если ничего из вышеперечисленного не помогает, вы можете включить трассировку , которая может дать вам полезную информацию о том, где в конвейере возникает ошибка (а также почему).

Надеюсь это поможет.

1
volpav

Я скопировал dll контроллера на основе RouteAttribute в папку bin, но он не был распознан как действительный контроллер, и я получил ошибку 404 на клиенте.

После долгих отладок я нашел свою проблему. Именно потому, что версия System.Web.Http.dll, на которую ссылался контроллер, отличалась от версии System.Web.Http.dll, на которую ссылался основной проект (тот, который содержал global.asax.cs).

Asp.Net находит контроллер по отражению, используя такой код

internal static bool IsControllerType(Type t)
{
    return
        t != null &&
        t.IsClass &&
        t.IsVisible &&
        !t.IsAbstract &&
        typeof(IHttpController).IsAssignableFrom(t) &&
        HasValidControllerName(t);
}

Поскольку IHttpController отличается для каждой версии System.Web.Http.dll, контроллер и основной проект должны иметь одну и ту же ссылку.

1
tcb

У нас также было это, изменение версии .NET с 4.5 на 4.5.1 или новее решило проблему 

1
Eric Herlitz

Попробуйте просто использовать Value часть имени контроллера, например так:

http://localhost/api/Value

Примечание. По соглашению механизм маршрутизации принимает значение, переданное в качестве имени контроллера, и добавляет к нему слово Controller. Помещая ValueController в URI, вы заставляли механизм маршрутизации искать класс с именем ValueControllerController, который он не нашел.

0
Karl Anderson

Пришло время добавить мою глупую оплошность в список здесь: я набрал неверный путь к маршруту по умолчанию в webapi.

Оригинал:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/id",
            defaults: new { id = RouteParameter.Optional}
        );

Исправлено: (соблюдайте фигурные скобки вокруг "id")

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional}
        );
0
Mansfield

Ваша конфигурация маршрута выглядит хорошо. Дважды проверьте раздел обработчиков в web.config, для интегрированного режима это правильный способ использовать ExtensionLessUrlHandler:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Больше на эту тему: http://blogs.msdn.com/b/tmarq/archive/2010/05/26/how-extensionless-urls-are-handled-by-asp-net-v4. aspx

0
dbalogh

В моем случае я забыл сделать его производным от ApiController. 

Так будет выглядеть 

public class ValuesController : ApiController
0
aoakeson

Ни одно из приведенных выше решений не решило мою проблему ... Моя ошибка заключалась в том, что я скопировал файлы bin непосредственно на рабочий сервер, а затем я не работал. 404 исчез, когда я опубликовал проект на диск и скопировал «опубликованную» папку на сервер. Это немного очевидно, но может помочь кому-то.

0
Tiago Gouvêa

Я ценю, что это очень старый вопрос, но я решил добавить еще один ответ для будущих пользователей.

Я обнаружил, что это произошло только сейчас в проекте, над которым я работал, только после того, как он был развернут в CI/Staging. Решение состояло в том, чтобы переключать значение компиляции debug = "true" взад и вперед при развертывании каждой версии в каждой среде один раз, и это исправило бы меня.

0
Lari Tuomisto