MVC4 Web API 프로젝트를 사용하기 시작했으며 여러 HttpPost
방법 이있는 컨트롤러가 있습니다. 컨트롤러는 다음과 같습니다.
제어 장치
public class VTRoutingController : ApiController
{
[HttpPost]
public MyResult Route(MyRequestTemplate routingRequestTemplate)
{
return null;
}
[HttpPost]
public MyResult TSPRoute(MyRequestTemplate routingRequestTemplate)
{
return null;
}
}
다음 MyRequestTemplate
은 요청을 통해 오는 Json을 처리하는 템플릿 클래스를 나타냅니다.
오류:
Fiddler를 사용하여 요청 http://localhost:52370/api/VTRouting/TSPRoute
하거나 http://localhost:52370/api/VTRouting/Route
오류가 발생하면 :
요청과 일치하는 여러 조치가 발견되었습니다.
위의 방법 중 하나를 제거하면 정상적으로 작동합니다.
Global.asax
에서 기본 라우팅 테이블을 수정하려고 시도했지만 global.asax
여전히 오류가 발생합니다. global.asax에서 경로를 정의하는 데 문제가 있다고 생각합니다. 다음은 global.asax에서하는 일입니다.
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute(
name: "MyTSPRoute",
routeTemplate: "api/VTRouting/TSPRoute",
defaults: new { }
);
routes.MapHttpRoute(
name: "MyRoute",
routeTemplate: "api/VTRouting/Route",
defaults: new { action="Route" }
);
}
POST를 사용하여 Fiddler에서 요청을하고 MyRequestTemplate의 RequestBody에서 json을 전달합니다.
답변
단일 컨트롤러에서 여러 작업을 수행 할 수 있습니다.
이를 위해서는 다음 두 가지를 수행해야합니다.
-
먼저 다음과
ActionName
같은 속성 으로 작업을 장식하십시오.[ActionName("route")] public class VTRoutingController : ApiController { [ActionName("route")] public MyResult PostRoute(MyRequestTemplate routingRequestTemplate) { return null; } [ActionName("tspRoute")] public MyResult PostTSPRoute(MyRequestTemplate routingRequestTemplate) { return null; } }
-
둘째,
WebApiConfig
파일 에서 다음 경로를 정의 하십시오.// Controller Only // To handle routes like `/api/VTRouting` config.Routes.MapHttpRoute( name: "ControllerOnly", routeTemplate: "api/{controller}" ); // Controller with ID // To handle routes like `/api/VTRouting/1` config.Routes.MapHttpRoute( name: "ControllerAndId", routeTemplate: "api/{controller}/{id}", defaults: null, constraints: new { id = @"^\d+$" } // Only integers ); // Controllers with Actions // To handle routes like `/api/VTRouting/route` config.Routes.MapHttpRoute( name: "ControllerAndAction", routeTemplate: "api/{controller}/{action}" );
답변
문제에 대한 훨씬 더 나은 해결책 Route
은 주석으로 메소드의 경로를 지정할 수있는 사용 하는 것입니다 .
[RoutePrefix("api/VTRouting")]
public class VTRoutingController : ApiController
{
[HttpPost]
[Route("Route")]
public MyResult Route(MyRequestTemplate routingRequestTemplate)
{
return null;
}
[HttpPost]
[Route("TSPRoute")]
public MyResult TSPRoute(MyRequestTemplate routingRequestTemplate)
{
return null;
}
}
답변
사용하다:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
더 이상 RESTful 접근 방식은 아니지만 이제 웹 API가 동사를 기반으로 자동으로 결정하도록하는 대신 이름으로 작업을 호출 할 수 있습니다.
[POST] /api/VTRouting/TSPRoute
[POST] /api/VTRouting/Route
일반적인 생각과는 달리이 방법에는 아무런 문제가 없으며 웹 API를 남용하지 않습니다. Web API의 모든 멋진 기능 (델리 게이터, 콘텐츠 협상, 미디어 형식 포맷터 등)을 여전히 활용할 수 있습니다. RESTful 방식을 버릴뿐입니다.
답변
웹 API 엔드 포인트 (컨트롤러)는 get / post / put / delete 동사를 허용하는 단일 리소스입니다. 일반적인 MVC 컨트롤러 가 아닙니다 .
필요한 경우 보내는 매개 변수를 허용하는 하나의 HttpPost 메서드 /api/VTRouting
만있을 수 있습니다 . [http] 항목으로 꾸미는 한 함수 이름 은 중요하지 않습니다 . 그래도 시도한 적이 없습니다.
편집 : 작동하지 않습니다. 해결하면 유형에 모델 바인딩을 시도하지 않고 매개 변수의 수를 따르는 것 같습니다.
다른 매개 변수를 허용하도록 함수를 오버로드 할 수 있습니다. 나는 당신이하는 방식으로 선언했지만 메소드에 다른 (호환되지 않는) 매개 변수를 사용하면 괜찮을 것이라고 확신합니다. 매개 변수가 동일하면 모델 바인딩이 어떤 것을 의미하는지 알 수 없으므로 운이 좋지 않습니다.
[HttpPost]
public MyResult Route(MyRequestTemplate routingRequestTemplate) {...}
[HttpPost]
public MyResult TSPRoute(MyOtherTemplate routingRequestTemplate) {...}
이 부분은 작동합니다
새 템플릿을 만들 때 제공되는 기본 템플릿은 이것을 매우 명백하게 만듭니다.이 규칙을 고수해야한다고 말하고 싶습니다.
public class ValuesController : ApiController
{
// GET is overloaded here. one method takes a param, the other not.
// GET api/values
public IEnumerable<string> Get() { .. return new string[] ... }
// GET api/values/5
public string Get(int id) { return "hi there"; }
// POST api/values (OVERLOADED)
public void Post(string value) { ... }
public void Post(string value, string anotherValue) { ... }
// PUT api/values/5
public void Put(int id, string value) {}
// DELETE api/values/5
public void Delete(int id) {}
}
많은 작업을 수행하는 하나의 클래스를 Ajax 사용을 위해 만들고 싶다면 표준 컨트롤러 / 액션 패턴을 사용하지 않는 큰 이유가 없습니다. 유일한 차이점은 메소드 서명이 예쁘지 않다는 것이므로 Json( returnValue)
반환하기 전에 물건을 감싸 야 합니다.
편집하다:
간단한 유형을 사용할 때 표준 템플릿 (포함하도록 편집)을 사용할 때 오버로드가 제대로 작동합니다. 다른 서명을 가진 2 개의 사용자 정의 객체를 사용하여 다른 방법으로 테스트했습니다. 그것을 작동시킬 수 없었습니다.
- 복잡한 객체와의 바인딩은 “깊게”보이지 않으므로 그렇게 할 필요가 없습니다.
- 쿼리 문자열에 추가 매개 변수를 전달하여이 문제를 해결할 수 있습니다.
- 사용 가능한 옵션을 제공 할 수있는 것보다 더 나은 기록
이것은이 경우 나를 위해 일했습니다, 그것이 당신을 얻는 곳을보십시오. 테스트 만 예외입니다.
public class NerdyController : ApiController
{
public void Post(string type, Obj o) {
throw new Exception("Type=" + type + ", o.Name=" + o.Name );
}
}
public class Obj {
public string Name { get; set; }
public string Age { get; set; }
}
그리고 콘솔에서 다음과 같이 호출됩니다.
$.post("/api/Nerdy?type=white", { 'Name':'Slim', 'Age':'21' } )
답변
동일한 Web API Controller에 여러 Get 및 Post 메소드를 추가 할 수 있습니다. 여기서 기본 경로는 문제를 일으키는 것입니다. 웹 API는 위에서 아래로 일치하는 경로를 확인하므로 모든 요청에 대해 기본 경로가 일치합니다. 기본 경로에 따라 하나의 제어기에서 단 하나의 Get and Post 메소드 만 가능합니다. 다음 코드를 맨 위에 배치하거나 주석 처리 / 삭제 기본 경로
config.Routes.MapHttpRoute("API Default",
"api/{controller}/{action}/{id}",
new { id = RouteParameter.Optional });
답변
컨트롤러 수준에서 경로 접두사 [RoutePrefix ( “api / Profiles”)]를 넣고 동작 방법 [Route ( “LikeProfile”)]에 경로를 붙입니다. global.asax 파일에서 아무것도 변경할 필요가 없습니다.
namespace KhandalVipra.Controllers
{
[RoutePrefix("api/Profiles")]
public class ProfilesController : ApiController
{
// POST: api/Profiles/LikeProfile
[Authorize]
[HttpPost]
[Route("LikeProfile")]
[ResponseType(typeof(List<Like>))]
public async Task<IHttpActionResult> LikeProfile()
{
}
}
}
답변
나는 그 질문에 이미 대답했다고 생각합니다. 또한 서명 된 mehtod는 있지만 이름은 다른 webApi 컨트롤러를 찾고있었습니다. WebApi로 계산기를 구현하려고했습니다. 계산기에는 서명은 같지만 이름이 다른 4 가지 방법이 있습니다.
public class CalculatorController : ApiController
{
[HttpGet]
[ActionName("Add")]
public string Add(int num1 = 1, int num2 = 1, int timeDelay = 1)
{
Thread.Sleep(1000 * timeDelay);
return string.Format("Add = {0}", num1 + num2);
}
[HttpGet]
[ActionName("Sub")]
public string Sub(int num1 = 1, int num2 = 1, int timeDelay = 1)
{
Thread.Sleep(1000 * timeDelay);
return string.Format("Subtract result = {0}", num1 - num2);
}
[HttpGet]
[ActionName("Mul")]
public string Mul(int num1 = 1, int num2 = 1, int timeDelay = 1)
{
Thread.Sleep(1000 * timeDelay);
return string.Format("Multiplication result = {0}", num1 * num2);
}
[HttpGet]
[ActionName("Div")]
public string Div(int num1 = 1, int num2 = 1, int timeDelay = 1)
{
Thread.Sleep(1000 * timeDelay);
return string.Format("Division result = {0}", num1 / num2);
}
}
WebApiConfig 파일에는 이미
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
IIS에서 인증 / 권한을 설정하기 만하면됩니다!
도움이 되었기를 바랍니다!