Web API (1.x-2.x) non supporta più percorsi di attributo con lo stesso percorso su diversi controllori. Il risultato è una 404, perché tutti il percorso corrisponde a più di un controller ea quel API punto Web prenderà in considerazione il risultato ambiguo.
Nota che MVC Core supporta questa nota di scenario: MVC Core funge da API Web MVC &.
Se si sceglie di utilizzare Web API 2.11 (o più recente) è possibile creare un vincolo di route per il metodo http per controller e utilizzarlo al posto dell'attributo Route in uso. L'esempio seguente mostra che è possibile utilizzare RoutePrefix o direttamente Routes (come la risposta di kmacdonald).
using System.Collections.Generic;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Routing;
public class BooksWriteController : ApiController
{
[PostRoute("api/Books")]
public void Post() { }
}
[RoutePrefix("api/books")]
public class BooksReadController : ApiController
{
[GetRoute]
public void Get() { }
[GetRoute("{id:int}")]
public void Get(int id) { }
}
Queste due classi semplificare l'uso dell'attributo percorso vincolo
class GetRouteAttribute : MethodConstraintedRouteAttribute
{
public GetRouteAttribute(string template) : base(template ?? "", HttpMethod.Get) { }
}
class PostRouteAttribute : MethodConstraintedRouteAttribute
{
public PostRouteAttribute(string template) : base(template ?? "", HttpMethod.Post) { }
}
Questa classe permette di aggiungere vincoli al percorso generato
class MethodConstraintedRouteAttribute : RouteFactoryAttribute
{
public MethodConstraintedRouteAttribute(string template, HttpMethod method)
: base(template)
{
Method = method;
}
public HttpMethod Method
{
get;
private set;
}
public override IDictionary<string, object> Constraints
{
get
{
var constraints = new HttpRouteValueDictionary();
constraints.Add("method", new MethodConstraint(Method));
return constraints;
}
}
}
Questo è solo uno standard vincolo percorso, nit : è possibile che si desideri memorizzare nella cache l'oggetto constraint per ridurre le allocazioni.
class MethodConstraint : IHttpRouteConstraint
{
public HttpMethod Method { get; private set; }
public MethodConstraint(HttpMethod method)
{
Method = method;
}
public bool Match(HttpRequestMessage request,
IHttpRoute route,
string parameterName,
IDictionary<string, object> values,
HttpRouteDirection routeDirection)
{
return request.Method == Method;
}
}
Questo funziona perfettamente. – user1145404
@YishaiGalatzer: qualsiasi motivo specifico per cui è necessario il 'MethodConstraint' personalizzato qui invece di riutilizzare [System.Web.Http.Routing.HttpMethodConstraint] (https://msdn.microsoft.com/en-us/library/system.web. http.routing.httpmethodconstraint (v = vs.118) .aspx)? – Serguei
Il punto sta vincolando la rotta stessa. La proprietà built-in agisce solo nella selezione dell'azione che viene eseguita troppo tardi. –