it-swarm.com.de

Alle Anforderungen an die ASP.NET-Web-API geben den Fehler 404 zurück

Ich habe eine ASP.NET MVC 4-Website, die eine Web-API enthält. Die Site wurde mit Visual Studio 2012 und .NET 4.5 unter Windows 8 mit IIS Express als Webserver entwickelt und getestet. In dieser Entwicklungsumgebung funktioniert alles.

Jetzt wird es auf einem Windows 2008 R2 (SP1) -Server mit IIS 7.5 bereitgestellt. .NET 4.0 und 4.5 sind installiert. Der Anwendungspool wird mit .NET 4.0 im integrierten Pipeline-Modus ausgeführt.

In dieser Produktionsumgebung funktioniert die MVC-Website, die Web-API nicht. Für jede Anforderung, egal ob GET oder POST, erhalte ich eine 404 Fehler. Wenn ich nur eine Web-API-URL in den Browser eingebe (IE 9 wurde lokal auf dem Server geöffnet), um eine GET-Anforderung auszuführen, wird eine 404-Seite angezeigt. Wenn ich eine POST -Anforderung von einer Web-API-Clientanwendung ausstelle, erhalte ich auch eine 404 und die Meldung:

Es wurde keine HTTP-Ressource gefunden, die mit dem Anforderungs-URI übereinstimmt

Ich habe eine Testwebsite mit MVC 4 und Web-API erstellt und auf demselben Server bereitgestellt, und die Web-API funktioniert. Web-API und MVC Baugruppen haben in beiden Projekten die gleiche Versionsnummer.

Außerdem habe ich der Anwendung den Web API Route Debugger hinzugefügt. Wenn ich eine gültige Route wie http://myserver/api/order/12 Verwende, erhalte ich folgendes Ergebnis:

Route Debugger

Für mich bedeutet dies, dass die richtige Routenvorlage Api/{Controller}/{Id} Gefunden und korrekt in einen Controller Order und Id=12 Geparst wurde. Der Controller (abgeleitet von ApiController) ist in der Web-Assembly vorhanden, in der sich auch alle MVC-Controller befinden.

Ich weiß jedoch nicht, was der Status 000 Bedeuten könnte und warum kein Abschnitt "Routenauswahl" angezeigt wird (was normalerweise der Fall ist, auch wenn die Assembly kein einziges ApiController, siehe Screenshots auf der oben verlinkten Seite). Irgendwie sieht es so aus, als ob kein ApiController gefunden oder gar nicht gesucht wurde oder die Suche im Hintergrund fehlschlägt.

Die IIS - Protokolldateien enthalten keine nützlichen Informationen. Das Ändern verschiedener Anwendungspooleinstellungen und das Verwenden desselben Anwendungspools für den Test und die reale Anwendung hat nicht geholfen.

Ich bin gerade dabei, "Features", Konfigurationseinstellungen, Baugruppen von Drittanbietern usw. aus der Anwendung zu entfernen, um sie am Ende auf die geringe Größe der Testanwendung zu reduzieren, und hoffe, dass sie irgendwann zu funktionieren beginnt.

Hat jemand eine Ahnung, woran das liegen könnte? Auch jede Debugging- oder Logging-Idee, um möglicherweise den Grund zu finden, ist sehr willkommen.

Bearbeiten

Dank Darrel Millers Tipp in den Kommentaren unten habe ich Tracing für ASP.NET Web Api integriert.

Für die (GET) -Anforderungs-URL http://myserver/api/order/12 Erhalte ich Folgendes:

  • In der Entwicklungsumgebung erfolgreich (in Kurzform):

Nachricht: http://localhost:50020/api/order/12; Kategorie: System.Web.Http.Request

Controller Auswahl und Instanziierung ...

Operator: DefaultHttpControllerSelector; Bedienung: SelectController; Meldung: Route = "Controller: Auftrag, ID: 12"; Kategorie: System.Web.Http.Controllers

Operator: DefaultHttpControllerSelector; Bedienung: SelectController; Nachricht: Bestellung; Kategorie: System.Web.Http.Controllers

Betreiber: HttpControllerDescriptor; Bedienung: CreateController; Botschaft: ; Kategorie: System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; Vorgang: Erstellen; Botschaft: ; Kategorie: System.Web.Http.Controllers

Operator: DefaultHttpControllerActivator; Vorgang: Erstellen; Nachricht: MyApplication.ApiControllers.OrderController; Kategorie: System.Web.Http.Controllers

Aktionsauswahl, Parameterbindung und Aktionsaufruf folgen ...

Inhaltsverhandlung und Formatierung für das Ergebnis ...

Betreiber: DefaultContentNegotiator; Betrieb: verhandeln; Meldung: Typ = "String" ... mehr

Controller entsorgen ...

Betreiber: OrderController; Bedienung: Entsorgen; Botschaft: ; Kategorie: System.Web.Http.Controllers

  • In der Produktionsumgebung nicht erfolgreich (in Kurzform):

Nachricht: http://myserver/api/order/12; Kategorie: System.Web.Http.Request

Operator: DefaultHttpControllerSelector; Bedienung: SelectController; Meldung: Route = "Controller: Auftrag, ID: 12"; Kategorie: System.Web.Http.Controllers

Der gesamte Teil der Aktivierung des Controllers, der Aktionsauswahl, der Parameterbindung und des Aktionsaufrufs fehlt, und es folgt die sofortige Aushandlung und Formatierung des Inhalts für die Fehlermeldung :

Betreiber: DefaultContentNegotiator; Betrieb: verhandeln; Meldung: Geben Sie = "HttpError" ein ... mehr

29
Slauma

Dank Kiran Challas Kommentar und Quellcode von dieser Antwort konnte ich herausfinden, dass eine Versammlung (die ReportViewer 11 Assembly für SQL Server Reporting Services) fehlte auf dem Produktionsserver.

Obwohl sich in dieser Assembly kein ApiController befindet, scheint dies zu bewirken, dass Controller in Assemblys - in diesem Fall die Assembly meines Webprojekts -, die auf die fehlende Assembly verweisen, nicht gefunden werden.

Anscheinend hängt dieses Verhalten mit diesem Codeteil aus der Quelle DefaultHttpControllerTypeResolver der Web-API zusammen:

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)));
    }
}

Ich weiß nicht, ob es so sein muss, und der Kommentar im Code überzeugt mich nicht ganz, aber dieser catch ... continue block ist ziemlich still über ein mögliches Problem und es hat sehr viel Zeit und Frustration gekostet, es zu finden. Ich wusste sogar, dass das ReportViewer noch nicht installiert war. Ich habe versucht, es und abhängige Assemblys zu installieren, aber es wurde von einem anderen ausgeführten Prozess auf dem Server blockiert. Daher habe ich beschlossen, die Installation zu verschieben, bis ich mich mit dem Administrator in Verbindung setzen und mich zuerst auf die MVC- und WebAPI-Tests konzentrieren konnte - ein großer Fehler! Ohne Kirans Debugging-Code-Snippet hätte ich nie gedacht, dass die Existenz eines ReportViewer.dll könnte irgendetwas mit der Auflösung des Controllertyps zu tun haben.

Meiner Meinung nach gibt es Raum für Verbesserungen für einen durchschnittlichen Entwickler wie mich, der keine tieferen Kenntnisse über die Funktionsweise der Web-API besitzt.

Nach der Installation des fehlenden ReportViewer.dll das Problem ist verschwunden.

Hier sind Fragen zu demselben Symptom, die möglicherweise haben denselben Grund haben:

Bearbeiten

Ich habe einen Verbesserungswunsch zu CodePlex gestellt:

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

Edit 2 (11. August 13)

Das Problem wurde für WebAPI v5.0 RC behoben. Weitere Informationen finden Sie im obigen Link zum Arbeitselement und seinem Kommentarbereich.

23
Slauma

In dieser Antwort gab es großartige Ressourcen, aber ich bekam eine 404, was sich als ziemlich dummer Grund herausstellte:

  1. Ich habe ein WiX-Installationsprogramm für mein API-Projekt erstellt
  2. Installierte es auf einem Test VM (virtuelle Maschine)
  3. Angefordert für einen URI, den die API bereitstellen soll
  4. KNALL! 404 :(

Es stellte sich heraus, dass ich das Packen und Bereitstellen von Global.asax im Stammverzeichnis des virtuellen Verzeichnisses in meiner Bereitstellung verpasst hatte. Füge dies hier zum Nutzen von Goofies wie mir hinzu :)

5

Ich hatte das gleiche Problem in einem Remote-Server, aber wenn ich auf einem localhost ausführen, funktioniert gut.

Meine Lösung war:

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

Ich hoffe, dass das bei dir funktioniert.

0
framled