2015-02-24 1 views
7

ho i seguenti metodi di azione in un controller in un progetto Web API ASP.NET:ASP.NET Web API restituisce 200 OK quando deve restituire 404

[Route("api/v2/project/{projectId}/stuff"), HttpGet] 
public IHttpActionResult Get(int projectId) 

[Route("api/v2/project/{projectId}/stuff/{id:guid}"), HttpGet] 
public IHttpActionResult Get(int projectId, [FromUri] Guid id) 

[Route("api/v2/project/{projectId}/stuff"), HttpPost] 
public IHttpActionResult Post(int projectId, [Required] Stuff stuff) 

[Route("api/v2/project/{projectId}/stuff/{id:guid}"), HttpPut] 
public IHttpActionResult Put(int projectId, [FromUri] Guid blastId, Stuff stuff) 

[Route("api/v2/project/{projectId}/stuff/{id:guid}"), HttpDelete] 
public IHttpActionResult Delete(int projectId, [FromUri] Guid id) 

A causa di un errore di javascript, ho fatto un DELETE richiesta di

api/v2/project/1234/stuff/undefined 

cioè invece di un GUID per l'id, ho avuto la stringa "undefined". Per quanto posso dire, questo non dovrebbe corrispondere a nessuno dei miei percorsi, ma invece di uno 404 Not found (o anche 405 Method not allowed), ho ricevuto un 200 OK come risposta.

Ho impostato un punto di interruzione in ciascuno di questi metodi di azione e ho ripetuto la richiesta utilizzando Fiddler, ma nessuno dei punti di interruzione è stato raggiunto. Ho anche provato a installare il pacchetto WebApiRouteDebugger da nuget, ma stiamo usando una factory controller personalizzata che collega le cose attraverso il nostro contenitore DI, quindi non ho potuto farlo funzionare affatto. Ho anche provato a lanciare la seguente eccezione da uno dei miei filtri registrati a livello globale:

throw new Exception(actionContext.ControllerContext.ControllerDescriptor.ControllerName + 
" " + actionContext.ActionDescriptor.ActionName); 

ma la richiesta DELETEancora passa attraverso al 200 OK (nessuna richiesta di URL validi sembrano farlo).

In quale altro modo è possibile risolvere il problema? Quale potrebbe essere la causa principale?

+1

Ho creato un nuovo progetto Web APi e aggiunto controller con i metodi e il routing per i test. Purtroppo funziona bene. Per url 'api/v2/project/{ID progetto}/stuff/{id: guid}' Ho 404 errori. Penso che sia un problema con il routing scorretto in altri controller o url con corrispondenze 'indefinite' ad altre route. –

+0

@BartoszCzerwonka: Grazie mille per aver trovato il tempo per farlo. Il progetto è di grandi dimensioni, motivo per cui non ho incluso tutti i percorsi nell'intero progetto - tuttavia, ho controllato attentamente, e non ci sono percorsi nel progetto che corrispondono a api/v2/project/{ projectId}/stuff/ 'tranne che in questo controller. –

+0

Inoltre, ce n'è solo uno che dovrebbe accettare le richieste DELETE - ed è quello in cui non viene colpito alcun punto di interruzione. –

risposta

3

Nei tuoi Global.asax.cs file in cui il vostro protected void Application_Start(object sender, EventArgs e) è, aggiungere il seguente:

protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
    } 

Tutte le richieste al server dovrebbero passare di qui.

Aggiungere questi utilizzando se non ci.

using System.Web.Compilation; 
using System.Reflection; 

Quindi nella richiesta di inizio chiamata aggiungere questo codice per elencare tutti i percorsi attivi.

 string Items = ""; 
     IEnumerable<Assembly> Assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>(); 

     foreach (Assembly FoundAssembly in Assemblies) 
     { 
      string AssemblyName = FoundAssembly.FullName; 
      IEnumerable<TypeInfo> Types = FoundAssembly.DefinedTypes.Where(type => type != null && type.IsPublic && type.IsClass && !type.IsAbstract && typeof(ApiController).IsAssignableFrom(type)); 
      foreach (TypeInfo ControllerType in Types) 
      { 
       System.Web.Http.Controllers.ApiControllerActionSelector ApiControllerSelection = new System.Web.Http.Controllers.ApiControllerActionSelector(); 
       System.Web.Http.Controllers.HttpControllerDescriptor ApiDescriptor = new System.Web.Http.Controllers.HttpControllerDescriptor(new System.Web.Http.HttpConfiguration(), ControllerType.Name, ControllerType); 
       ILookup<string, System.Web.Http.Controllers.HttpActionDescriptor> ApiMappings = ApiControllerSelection.GetActionMapping(ApiDescriptor); 

       foreach (var Maps in ApiMappings) 
       { 
        foreach (System.Web.Http.Controllers.HttpActionDescriptor Actions in Maps) 
        { 
         Items += "[ controller=" + ControllerType.Name + " action=" + ((System.Web.Http.Controllers.ReflectedHttpActionDescriptor)(Actions)).MethodInfo + "]"; 
        } 
       } 
      } 
     } 

Questo elencherà tutti i controller e le loro firme. Se il tuo URL non rientra in nessuno di questi, potresti dover espandere l'elenco per includere rotte non controller.

+0

Alcuni altri cambiamenti nel nostro progetto mi hanno reso incapace di riprodurre il problema da quando si è verificato; tuttavia, questo suggerimento per la risoluzione dei problemi è abbastanza buono che sarò sicuro di usarlo nel caso in cui il problema riemerga. Grazie mille per il suggerimento - Sono felice di premiarvi un aumento del ripetitore del 1000% :) –

0

io non sono sicuro del vostro percorso, ma penso di avere un percorso che non include le azioni in mappatura:

api/v2/project/1234/stuff/undefined 

di controllo Web API di configurazione per questo: api/{controller}[/{action}]/{id}. Penso che potresti colpire un'altra azione di rotta con la tua azione (come un GET).

P.S. pubblica la configurazione del percorso per aggiornare la risposta.

1

Ho avuto lo stesso problema. Nei miei startup.cs ho avuto il metodo

app.Run(async context => 
     { 
      context.Response.ContentType = "text/plain"; 
      await context.Response.WriteAsync("My Api"); 
     }); 

Questo stava causando tutte le rotte di ricevere una risposta 200 insieme con la stringa. Volevo solo mostrare questa risposta all'avvio. Questa era la soluzione.

app.MapWhen(ctx => ctx.Request.Path.Value == "/", StartupPage); 

Insieme a un metodo nella stessa classe di avvio

private void StartupPage(IAppBuilder app) 
    { 
     app.Run(async (context) => 
     { 
      context.Response.ContentType = "text/plain"; 
      await context.Response.WriteAsync("My Api"); 
     }); 
    } 

torno solo il 200 messaggio OK quando viene effettuata una richiesta sulla URL di base.