9

Sto usando asp.net mvc 5 e web api 2. Per il progetto asp.net mvc 5 ho tutto funzionante ... ma nuovo sto cercando di aggiungere web api 2 percorsi ... quando sto usando le aree.web api 2 percorsi area

ho il controller Web API 2 di lavoro alla base del progetto:

//this is working 
    namespace EtracsWeb.Controllers 
    { 
     public class TestController : ApiController 
     { 
      //localhost:port/api/test ...this is working 
      [HttpGet] 
      public HttpResponseMessage Get() 
      { 

       return new HttpResponseMessage() 
       { 
        Content = new StringContent("GET: Test message") 
       }; 
      } 

     } 
    } 

Quindi io parto dal presupposto mia Global.asax, la mia e la mia routeconfig.cswebapiconfig.cs sono corretti ... (non mostrato) ...

Ma ora sto cercando di ottenere il web API 2 nelle mie aree di lavoro ...

ho letto tutto quello che potevo trovare sul web e questo sembra che dovrebbe lavoro:

namespace EtracsWeb.Areas.WorkOrder 
{ 
    public class WorkOrderAreaRegistration : AreaRegistration 
    { 
     public override string AreaName 
     { 
      get 
      { 
       return "WorkOrder"; 
      } 
     } 

     public override void RegisterArea(AreaRegistrationContext context) 
     { 

      context.Routes.MapHttpRoute(
        name: "AuditModel_Api", 
        routeTemplate: "WorkOrder/api/AuditModelApi/{id}", 
        defaults: new { id = RouteParameter.Optional } 
       ); 

     //default 
      context.Routes.MapHttpRoute(
        name: "WorkOrder_Api", 
        routeTemplate: "WorkOrder/api/{controller}/{id}", 
        defaults: new { id = RouteParameter.Optional } 
       ); 

      context.MapRoute(
       "WorkOrder_default", 
       "WorkOrder/{controller}/{action}/{id}", 
       new { action = "Index", id = UrlParameter.Optional } 
      ); 
     } 
    } 
} 

Il mio codice di controllo è:

namespace EtracsWeb.Areas.WorkOrder.ApiControllers 
{ 
    public class AuditModelApiController : ApiController 
    { 
     IManufacturerStopOrderModelService auditModelService = new WorkOrder.Services.VWAuditModelService(UserSession.EtracsUserID, UserSession.ProgramID, UserSession.EtracsSessionID, UserSession.ConnectionString); 

     [HttpGet] 
     [Route("AuditModelApi")] 
     public HttpResponseMessage Get() 
     { 

      return new HttpResponseMessage() 
      { 
       Content = new StringContent("GET: Test message") 
      }; 
     } 

     [Route("AuditModelApi/AuditModels")] 
     public IEnumerable<VwAuditModel1> GetAuditModels() 
     { 
       return auditModelService.GetModels(); 
     } 

     public IHttpActionResult UpdateAuditMode() 
     { 
      //example of what can be returned ... NotFound, Ok ... look into uses... 

      VwAuditModel1 result = new VwAuditModel1(); 
      return Ok(result); 

      return NotFound(); 
     } 
    } 
} 

Ho provato il controller con e senza l'attributo di denominazione [Route] ... e non posso ottenere sia mettersi al lavoro ...

Sia il semplice caso

public HttpResponseMessage Get() 

e il caso "reale"

public IEnumerable<VwAuditModel1> GetAuditModels() 

restituiscono lo stesso risultato. Dal browser, utilizzando

http://localhost:64167/WorkOrder/api/AuditModelApi 

e

http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels 

ottengo il seguente:

<Error> 
<Message> 
No HTTP resource was found that matches the request URI 'http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels'. 
</Message> 
<MessageDetail> 
No route providing a controller name was found to match request URI 'http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels' 
</MessageDetail> 
</Error> 
+0

aggiungi webapiconfig.cs codeto ur post. Quello che manca per registrare le rotte degli attributi presumo. –

risposta

2

È necessario ottenere l'istanza HttpConfiguration dall'oggetto GlobalConfiguration e chiamare il metodo MapHttpAttributeRoutes() dall'interno il metodo della AreaRegistration.csRegisterArea().

public override void RegisterArea(AreaRegistrationContext context) 
    { 
     GlobalConfiguration.Configuration.MapHttpAttributeRoutes(); 

     //... omitted code 
    } 

Infine è necessario nel WebApiConfig rimuovere config.MapHttpAttributes() metodo o si otterrà un'eccezione duplicato.

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     // Web API configuration and services 
     config.EnableCors(); 

     // Configure Web API to use only bearer token authentication. 
     config.SuppressDefaultHostAuthentication(); 
     config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 


     // Web API routes 
     //config.MapHttpAttributeRoutes(); 

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

Sembra che [dovrebbe invece essere] (http://stackoverflow.com/a/19882528/712526) 'GlobalConfiguration.Configure (x => x.MapHttpAttributeRoutes())' come di Web Api v2 . – jpaugh

3

Il problema con quella chiamata API specifica è che non è stato specificato un controller da utilizzare in il tuo percorso.

 context.Routes.MapHttpRoute(
       name: "AuditModel_Api", 
       routeTemplate: "WorkOrder/api/AuditModelApi/{id}", 
       defaults: new { id = RouteParameter.Optional } 
      ); 

Dovrebbe essere

 context.Routes.MapHttpRoute(
       name: "AuditModel_Api", 
       routeTemplate: "WorkOrder/api/AuditModelApi/{id}", 
       defaults: new { controller = "AuditModelApi", id = RouteParameter.Optional } 
      ); 

segmenti costante nelle URL devono specificare quali URL per abbinare, ma è comunque necessario indicare cosa i valori del percorso sono in ordine per poter arrivare al controller e azione. Non ha modo di sapere quale segmento utilizzare come nome del controller, a meno che non si diventi un segmento {controller}.

+0

Funziona ... Grazie ... ma questo collega l'area a un singolo controller. Cosa facciamo se c'è più di un controller? – user2040850

+0

In tal caso, specificare l'argomento routeTemplate con un segnaposto del controller: 'WorkOrder/api/{controller}/{id)'. – NightOwl888

+0

Io il codice originale per la registrazione avevo già provato una variazione di questo ... NON specificando il controller e usando la rotta che hai dato ... e ha dato un errore che non riusciva a trovare la risorsa (vedi di nuovo il messaggio originale) ... Ho pensato che fosse corretto ... ho qualcosa di sbagliato nella dichiarazione di mapphttproute? – user2040850

3

In primo luogo, è necessario registrarsi il percorso con l'area di appartenenza, che ha senso solo, in modo da dentro la classe AreaNameAreaRegistration essere sicuri di aggiungere using System.Web.Http modo da ottenere il metodo di estensione MapHttpRoute, non è parte del System.Web.Mvc.

L'ordine sopra è un po 'spento, che sta causando il 404.Aggiungere il percorso seguente:

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

Se si desidera ottenere fantasia e aggiungere il nome area dalla proprietà AreaName (ovviamente vi preoccupate per le buone pratiche di codifica;)):

context.Routes.MapHttpRoute(
      name: "AreaNameWebApi", 
      routeTemplate: string.Concat("api/", AreaName, "/{controller}/{id}"), 
      defaults: new { id = RouteParameter.Optional } 
     ); 

Questo correggerà il problema 404. Nel modulo Web API, per impostazione predefinita, prima esegue la scansione di "api" per determinare dove cercare il controller (altrimenti verrà confuso, non è magico), quindi api deve essere il primo quando si aggiungono dinamicamente Nome area e Controller. Ovviamente è possibile modificare questo ordine codificando i percorsi, ma non è consigliabile, poiché è necessario fornire ogni route e ogni controller nella configurazione del percorso o utilizzando lo RouteAttribute.

Inoltre, con "api" per prima cosa creerà un URL dall'aspetto standard per te e i tuoi utenti invece di avere API in tutto il luogo. Ecco alcuni esempi:

http://site/api/members/myAccount/update 
http://site/api/members/myAccount/get/12345 
http://site/api/members/contacts/getByOwnerId/12345 

Spero che questo aiuti!

Zev