Ответ 1
Web API (1.x-2.x) не поддерживает несколько маршрутов атрибутов с одним и тем же путем на разных контроллерах. Результатом является 404, потому что весь маршрут соответствует более чем одному контроллеру, и в этот момент Web API будет рассматривать результат неоднозначно.
Обратите внимание, что MVC Core поддерживает это примечание к сценарию: MVC Core служит как MVC, так и Web API.
Если вы решите использовать Web API 2.11 (или новее), вы можете создать ограничение маршрута для метода http для каждого контроллера и использовать его вместо встроенного атрибута маршрута. В приведенном ниже примере показано, что вы можете использовать RoutePrefix или direct Routes (например, 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) { }
}
Эти два класса упрощают использование атрибута маршрута ограничения
class GetRouteAttribute : MethodConstraintedRouteAttribute
{
public GetRouteAttribute(string template) : base(template ?? "", HttpMethod.Get) { }
}
class PostRouteAttribute : MethodConstraintedRouteAttribute
{
public PostRouteAttribute(string template) : base(template ?? "", HttpMethod.Post) { }
}
Этот класс позволяет добавлять ограничения к генерируемому маршруту
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;
}
}
}
Это просто стандартное ограничение маршрута, nit: вы можете захотеть кэшировать объект ограничений для сокращения распределений.
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;
}
}