2013-05-29 22 views
28

Mam witrynę sieci Web ASP.NET MVC 4, która zawiera Web API. Witryna została opracowana i przetestowana z Visual Studio 2012 i .NET 4.5 na Windows 8 z IIS Express jako serwer WWW. W tym środowisku programistycznym wszystko działa.Wszystkie żądania do interfejsu ASP.NET Web API zwracają błąd 404

Teraz jest wdrażany na serwerze Windows 2008 R2 (SP1) z usługami IIS 7.5. .NET 4.0 i 4.5 są zainstalowane. Pula aplikacji działa z .NET 4.0 w zintegrowanym trybie potokowym.

W tym środowisku produkcyjnym działa strona internetowa MVC, interfejs Web API nie działa. Dla każdego żądania, bez względu na to, czy jest to GET czy POST, pojawia się błąd 404. Jeśli po prostu wprowadzę adres URL interfejsu Web API w przeglądarce (IE 9 otworzył się lokalnie na serwerze), aby uruchomić żądanie GET, otrzymuję stronę 404. Jeśli mam wydać żądanie POST z aplikacji klienckiej Web API dostaję 404, jak również i komunikat:

Nie zasobów HTTP Stwierdzono, że pasuje do żądania URI

Utworzyłem przetestuj witrynę za pomocą MVC 4 i Web API, a następnie zainstaluj ją na tym samym serwerze i działa Web API. Zestawy Web API i MVC mają ten sam numer wersji w obu projektach.

Ponadto dodałem do aplikacji Web API Route Debugger. Jeśli używam ważnej trasy jak http://myserver/api/order/12 uzyskać następujący wynik:

Route Debugger

Dla mnie oznacza to, że prawidłowa droga Api/{Controller}/{Id} szablon został znaleziony i prawidłowo przetwarzane w kontrolerze Order i Id=12. Sterownik (pochodzący z ApiController) istnieje w zespole internetowym, w którym znajdują się również wszystkie kontrolery MVC.

Jednak nie wiem, co może oznaczać status 000 i dlaczego nie jest wyświetlana sekcja "Wybór trasy" (co zwykle ma miejsce, nawet jeśli zespół nie zawiera pojedynczego ApiController, zobacz zrzuty ekranu połączona strona powyżej). W jakiś sposób wygląda na to, że nie znaleziono ani nie szukano, lub wyszukiwanie nie powiedzie się po cichu.

Pliki dzienników IIS nie pokazują niczego użytecznego. Zmienianie różnych ustawień pul aplikacji i używanie tej samej puli aplikacji do testu i rzeczywistej aplikacji nie pomogło.

Obecnie jestem w trakcie usuwania "funkcji", ustawień konfiguracyjnych, złożeń innych producentów itp. Z aplikacji, aby w końcu obniżyć ją do małego rozmiaru aplikacji testowej i mieć nadzieję, że w pewnym momencie zaczyna działać.

Czy ktoś ma pojęcia, jaki może być problem? Również jakikolwiek pomysł na debugowanie lub rejestrowanie w celu znalezienia przyczyny jest bardzo mile widziany.

Edit

Dzięki końcówce Darrel Millera w komentarzach poniżej mam zintegrowany Tracing for ASP.NET Web Api.

Dla (GET) żądania URL http://myserver/api/order/12 uzyskać następujące:

  • W środowisku programistycznym, sukces (w skróconej formie):

Wiadomość: http://localhost:50020/api/order/12; Kategoria: System.Web.Http.Request

wybór kontrolera i instancji ...

Operator: DefaultHttpControllerSelector; Działanie: SelectController; Wiadomość: Route = "controller: order, id: 12"; Kategoria: System.Web.Http.Controllers

Operator: DefaultHttpControllerSelector; Działanie: SelectController; Wiadomość: Zamówienie; Kategoria: System.Web.Http.Controllers

Operator: HttpControllerDescriptor; Operacja: CreateController; Wiadomość:; Kategoria: System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; Operacja: Utwórz; Wiadomość: ; Kategoria: System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; Operacja: Utwórz; Wiadomość: MyApplication.ApiControllers.OrderController; Kategoria: System.Web.Http.Controllers

wybór Akcja, akcja i wiążąca parametr wywołania następująco ...

Content negocjacje i formatowanie wyniku ...

Operator: DefaultContentNegotiator ; Operacja: Negocjuj; Wiadomość: Typ = "string" ... więcej

Utylizacja kontroler ...

Operator: OrderController; Działanie: Usuń; Wiadomość:; Kategoria: System.Web.Http.Controllers

  • W środowisku produkcyjnym, a nie sukces (w skróconej formie):

Wiadomość: http://myserver/api/order/12; Kategoria: System.Web.Http.Request

Operator: DefaultHttpControllerSelector; Działanie: SelectController; Wiadomość: Route = "controller: order, id: 12"; Kategoria: System.Web.Http.Kontrolery

Cała część aktywacji regulatora, dobór parametrów działania, wiązania, akcja inwokacja brakuje i wynika zawartości negocjacji i natychmiast formatowania komunikatu o błędzie:

Operator: DefaultContentNegotiator; Operacja: Negocjuj; Wiadomość: Type = "httpError" ... więcej

+0

Może być konieczne aktywowanie niektórych funkcji IIS w roli Role serwera> Usługi internetowe Informacje> Usługi World Wide Web. Nie wiem dokładnie, co musisz aktywować, ale myślę, że twój problem może być tutaj! –

+1

Spróbuj włączyć śledzenie interfejsu API sieci Web http://www.asp.net/web-api/overview/testing-and-debugging/tracing-in-aspnet-web-api –

+0

Wygląda na to, że Twój interfejs WebAPI nie jest zarejestrowany. co się dzieje z 'Global.asax' i' WebApiConfig'? Czy mają w sobie jakieś warunkowe konfigurowanie? – Liel

Odpowiedz

23

Dzięki Kiran Challa's komentarza i kod źródłowy z this answer udało mi się dowiedzieć, że zespół (the ReportViewer 11 assembly dla SQL Server Reporting Services) zaginął na serwer produkcyjny.

Chociaż w tym zestawie nie ma elementu ApiController, wydaje się, że kontrolery w złożeniach - w tym przypadku w zespole projektu WWW - które odnoszą się do brakującego zespołu, nie zostały znalezione.

Widocznie to zachowanie jest podobne do tego kawałka kodu od źródła Web API's DefaultHttpControllerTypeResolver:

List<Type> result = new List<Type>(); 

// Go through all assemblies referenced by the application 
// and search for types matching a predicate 
ICollection<Assembly> assemblies = assembliesResolver.GetAssemblies(); 
foreach (Assembly assembly in assemblies) 
{ 
    Type[] exportedTypes = null; 
    if (assembly == null || assembly.IsDynamic) 
    { 
     // can't call GetExportedTypes on a dynamic assembly 
     continue; 
    } 

    try 
    { 
     exportedTypes = assembly.GetExportedTypes(); 
    } 
    catch (ReflectionTypeLoadException ex) 
    { 
     exportedTypes = ex.Types; 
    } 
    catch 
    { 
     // We deliberately ignore all exceptions when building the cache. If 
     // a controller type is not found then we will respond later with a 404. 
     // However, until then we don't know whether an exception at all will 
     // have an impact on finding a controller. 
     continue; 
    } 

    if (exportedTypes != null) 
    { 
     result.AddRange(exportedTypes.Where(x => IsControllerTypePredicate(x))); 
    } 
} 

ja nie wiem, czy to ma być w ten sposób i nie jestem całkiem przekonany o komentarz w kodzie ale ten blok catch ... continue milczy na temat możliwego problemu i zajęło mi mnóstwo czasu i frustracji, aby go znaleźć. Wiedziałem nawet, że ReportViewer nie został jeszcze zainstalowany. Próbowałem zainstalować to i zależne złożenia, ale został zablokowany przez inny działający proces na serwerze, więc postanowiłem odłożyć instalację, dopóki nie skontaktuję się z administratorem i najpierw skupię się na testach MVC i WebAPI - wielki błąd! Bez fragmentu kodu debugującego Kirana nigdy nie wpadłem na pomysł, że istnienie ReportViewer.dll może mieć coś wspólnego z rozdzielczością typu kontrolera.

Moim zdaniem istnieje pole do poprawy dla przeciętnego programisty takiego jak ja, który nie ma głębszej wiedzy na temat wewnętrznego działania Web API.

Po zainstalowaniu brakującego ReportViewer.dll problem zniknął.

Oto pytania o tym samym objawem, który może miećten sam powód:

Edycja

I wydały wniosek o poprawie na CodePlex:

http://aspnetwebstack.codeplex.com/workitem/1075

Edycja 2 (11 sierpnia '13)

Problem został rozwiązany przez WebAPI v5.0 RC. Zobacz link powyżej do workitem i jego sekcji komentarzy, aby uzyskać szczegółowe informacje.

+1

Gdzie znajdujesz to Zgromadzenie? Widzę tylko rzeczy na formularze internetowe. –

+1

@ RaySülzer: To część * mojego * projektu. Jeśli nie korzystasz z usługi SSRS, nie będziesz mieć tego zestawu w swoim projekcie. – Slauma

+0

dzięki, człowieku, uratowałeś mój dzień – Benny

5

wielkie zasoby w tej odpowiedzi, jednak ja dostaję 404 za to, co okazało się być całkiem głupi powód:

  1. stworzyłem instalator WiX dla mojego projektu API
  2. Zainstalowane go na test VM (maszyna wirtualna)
  3. Żądany identyfikator URI, którym API ma służyć
  4. BANG! 404 :(

Okazało się, że ominęło opakowania i wdrażania Global.asax do głównego katalogu wirtualnego w moim wdrożenia. Dodanie tego tutaj na korzyść goofies jak ja :)

+0

Ostatnie zdanie było dla mnie wskazówką, a ja zrobiłem to, sprawdzając "Wstępną kompilację przed ...", kiedy publikuję i działa jak mój lokalny serwer. –

0

Miałem ten sam problem na zdalnym serwerze, ale kiedy wykonuję na localhost działa dobrze.

Moje rozwiązanie było:

<system.webServer> 
    <modules> 
     <remove name="UrlRoutingModule-4.0" /> 
     <add name="UrlRoutingModule-4.0" 
      type="System.Web.Routing.UrlRoutingModule" preCondition="" /> 
    </modules> 
</system.webServer> 

Mam nadzieję, że to działa dla Ciebie.

Powiązane problemy