Global.asax에 기본 경로가 있습니다.
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
특정 기능을 대상으로 할 수 있기를 원했기 때문에 다른 경로를 만들었습니다.
RouteTable.Routes.MapHttpRoute(
name: "WithActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
따라서 내 컨트롤러에는 다음이 있습니다.
public string Get(int id)
{
return "object of id id";
}
[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
return new string[] { "byCategory1", "byCategory2" };
}
전화 .../api/records/bycategoryid/5
하면 내가 원하는 것을 얻을 수 있습니다. 그러나 전화 .../api/records/1
하면 오류가 발생합니다.
요청과 일치하는 여러 작업이 발견되었습니다. …
그 이유를 이해합니다. 경로는 유효한 URL을 정의하지만 함수 일치에 관해서는 둘 다 Get(int id)
및 ByCategoryId(int id)
match api/{controller}/{id}
, 이것이 프레임 워크를 혼란스럽게 합니다.
기본 API 경로를 다시 작동하고 경로를 유지하려면 {action}
어떻게해야합니까? RecordByCategoryIdController
기본 API 경로와 일치 하도록 이름이 다른 컨트롤러를 만드는 것을 생각했습니다 .../api/recordbycategoryid/5
. 그러나 나는 그것이 “더러운”(따라서 불만족스러운) 해결책이라는 것을 알게되었다. 나는 이것에 대한 답변을 {action}
찾았고이 문제를 언급 하는 경로 사용에 대한 자습서가 없습니다 .
답변
경로 엔진은 규칙을 추가 할 때와 동일한 시퀀스를 사용합니다. 첫 번째로 일치하는 규칙을 가져 오면 다른 규칙 확인을 중지하고이를 수행하여 컨트롤러 및 작업을 검색합니다.
따라서 다음을 수행해야합니다.
-
특정 규칙을 일반 규칙 (예 : 기본값)보다 먼저 배치합니다. 즉,
RouteTable.Routes.MapHttpRoute
먼저 “WithActionApi”를 매핑 한 다음 “DefaultApi”를 매핑 하는 데 사용 합니다. -
defaults: new { id = System.Web.Http.RouteParameter.Optional }
id가 선택 사항이면 “/ api / {part1} / {part2}”와 같은 URL이 “DefaultApi”에 포함되지 않으므로 “WithActionApi”규칙 의 매개 변수를 제거하십시오 . -
“DefaultApi”에 명명 된 작업을 추가하여 입력 할 작업을 경로 엔진에 알립니다. 그렇지 않으면 컨트롤러에 하나 이상의 작업이 있으면 엔진은 사용할 작업을 인식하지 못하고 “요청과 일치하는 여러 작업을 찾았습니다 : …”를 발생시킵니다. 그런 다음 Get 메서드와 일치하도록하려면 ActionNameAttribute를 사용합니다 .
따라서 경로는 다음과 같아야합니다.
// Map this rule first
RouteTable.Routes.MapRoute(
"WithActionApi",
"api/{controller}/{action}/{id}"
);
RouteTable.Routes.MapRoute(
"DefaultApi",
"api/{controller}/{id}",
new { action="DefaultAction", id = System.Web.Http.RouteParameter.Optional }
);
그리고 컨트롤러 :
[ActionName("DefaultAction")] //Map Action and you can name your method with any text
public string Get(int id)
{
return "object of id id";
}
[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
return new string[] { "byCategory1", "byCategory2" };
}
답변
속성 라우팅의 도움으로 문제를 해결할 수 있습니다.
제어 장치
[Route("api/category/{categoryId}")]
public IEnumerable<Order> GetCategoryId(int categoryId) { ... }
jquery의 URI
api/category/1
경로 구성
using System.Web.Http;
namespace WebApplication
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
// Other Web API configuration not shown.
}
}
}
기본 라우팅은 기본 규칙 기반 라우팅으로 작동합니다.
제어 장치
public string Get(int id)
{
return "object of id id";
}
Jquery의 URI
/api/records/1
경로 구성
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
자세한 내용은 검토 기사 속성 라우팅 여기 라우팅 onvention 기반 및 이
답변
이 시도.
public class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var json = config.Formatters.JsonFormatter;
json.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
config.Formatters.Remove(config.Formatters.XmlFormatter);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional , Action =RouteParameter.Optional }
);
}
}
답변
가능한 이유는 ApiController에서 Controller를 상속하지 않았기 때문일 수도 있습니다. 나와 함께 일어난 일을 이해하는 데 시간이 걸렸습니다.
답변
경로를 구별하려면 ID가 숫자 여야한다는 제약 조건을 추가해보세요.
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
constraints: new { id = @"\d+" }, // Only matches if "id" is one or more digits.
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);