0

Ich habe Attribut-Routing auf meinem Controller angewendet und es führt zu falscher Aktion. Ich weiß nicht, wo ich falsch liege.ASP.NET-Web-API-Attribut-Routing zu falscher Aktion

Hier ist mein Controller:

using System.Collections.Generic; 
using System.Web.Http; 
using System.Web.Http.Description; 
using System.Linq; 
using System; 

namespace Iboo.API.Controllers 
{ 
    public class ClientsController : ApiController 
    { 
     private readonly IClientRepository _repository; 

     public ClientsController(IClientRepository repository) 
     { 
      _repository = repository; 
     } 

     // GET: api/Clients 
     [Route("api/v1/clients")] 
     public IEnumerable<Client> Get() 
     { 

      //code 
     } 


     // GET: api/Clients/5 
     [HttpGet] 
     [ResponseType(typeof(Client))] 
     [Route("api/v1/clients/get/{id}")] 
     public IHttpActionResult GetClientById(int id) 
     { 
      //code 
     } 

     // GET: api/Clients/5 
     [HttpGet] 
     [ResponseType(typeof(string))] 
     [Route("api/v1/clients/{id}/emailid")] 
     public IHttpActionResult GetClientEmailId(int id) 
     { 
      //code 
     }   
    } 
} 

Ich bin speziell interessiert an der GetClientEmailId Methode. Unten ist mein WebApiConfig

public static void Register(HttpConfiguration config) 
{ 
    // Web API configuration and services 
    var container = new UnityContainer(); 
    container.RegisterType<IClientRepository, ClientRepository>(new 
    HierarchicalLifetimeManager()); 


    // Web API routes 
    config.MapHttpAttributeRoutes(); 

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

Mein Global.asax.cs ist als

public class WebApiApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 
    } 
} 

im Browser folgt Wenn ich http://localhost:54919/api/v1/clients/?id=1/getemailid geben Sie mir http://localhost:54919/api/v1/clients es nehmen, die nicht das, was ich will.

Wenn ich versuche, http://localhost:54919/api/v1/clients/1/getemailid bekomme ich einen 404-Fehler.

Ich bin mir nicht sicher, was ich falsch mache.

+2

Wenn Sie sagen "es funktioniert nicht" ... was meinst du? erhalten Sie einen Fehler? Wenn ja, was sagt es? Ist es ein unerwarteter Ort? wenn ja, wo? – simonlchilds

+1

@Munhu Können wir den Code sehen, der die GetClientEmailId-Methode aufruft? – swatsonpicken

+1

Fragen, die Debugging-Hilfe suchen ("** Warum funktioniert dieser Code nicht?** ") muss das gewünschte Verhalten, ein spezifisches Problem oder einen Fehler und den kürzesten Code enthalten, der notwendig ist, um es ** in der Frage selbst zu reproduzieren. ** Fragen ohne ** eine klare Problemaussage ** sind für andere Leser nicht nützlich : Wie erstelle ich ein [mcve]. – Nkosi

Antwort

0

Sie die falschen URLs fordern nach Routen zu den Aktionen. Sie 404 erhalten, weil die URL, die Sie sich nicht auf eine der Route Vorlagen, die Sie auf Ihre Aktionen

[RoutePrefix("api/v1/clients")] 
public class ClientsController : ApiController { 
    //...other code removed for brevity 

    [HttpGet] 
    [Route("")] //Matches GET api/v1/Clients 
    public IHttpActionResult Get() { 
     //code 
    } 

    [HttpGet] 
    [ResponseType(typeof(Client))] 
    [Route("{id:int}")] //Matches GET api/v1/Clients/5 
    public IHttpActionResult GetClientById(int id) { 
     //code 
    } 

    [HttpGet] 
    [ResponseType(typeof(string))] 
    [Route("{id:int}/emailid")] //Matches GET api/v1/Clients/5/emailid 
    public IHttpActionResult GetClientEmailId(int id) { 
     //code 
    }   
} 

Beachten Sie die erwarteten URLs in den Kommentaren haben übereinstimmen rufen

Sie auch auf Attribute Routing in ASP.NET Web API 2 lesen, sollten ein besseres Verständnis für das Attribut-Routing erhalten.

0

Sie können versuchen, das Routenpräfix auf dem Controller zu verwenden.

[RoutePrefix("api/v1/clients")] 
public class ClientsController : ApiController 
{ 
    // GET: api/Clients/5 
    [ResponseType(typeof(string))] 
    [Route("{id:int}/emailid"),HttpGet] 
    public IHttpActionResult GetClientEmailId(int id) 
    { 
     //code 
    }  
} 
0

Sie sagte:

im Browser Wenn ich http://localhost:54919/api/v1/clients/?id=1/getemailid geben Sie mir http://localhost:54919/api/v1/clients es nehmen, die nicht das, was ich will.

Aus dem Weg, um Ihre Routen eingerichtet sind, sieht es aus wie Sie http://localhost:54919/api/v1/client/1/emailid gehen müssen, um die Route, die Sie

den Unterschied erklären

erhalten möchten, wenn Sie http://localhost:54919/api/v1/clients/?id=1/getemailid die Route aufrufen, dass passen würde etwas ähnliches:

[Route("api/v1/clients")] 
public IHttpActionResult GetClientEmailId(string id) 
{ 
    //code 
} 

, weil Sie den id Parameter als Abfragezeichenfolgeflag Parameter hinzugefügt haben. In diesem Fall hätte das Argument id einen Wert von 1/getemailid, was wenig Sinn macht.

durch die Routenparameter (durch ?id=1/getemailid mit 1/emailid ersetzen) Sie entsprechen tatsächlich die Route, die Sie wollen