Web Api의 요청과 일치하는 여러 조치가 발견되었습니다.


243

2 개의 "Get"메소드를 사용하려고하면이 오류가 계속 발생합니다.

요청과 일치하는 여러 조치가 발견되었습니다. webapi

나는 이것에 대해 다른 비슷한 질문을 둘러 보았지만 얻지 못했습니다.

2 개의 다른 이름이 있고 "HttpGet"속성을 사용하고 있습니다.

[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

답변:


485

경로지도는 다음과 같습니다.

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });

그러나 동일한 http 메소드로 여러 작업을 수행하려면 다음과 같이 경로를 통해 webapi에 자세한 정보를 제공해야합니다.

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });

routeTemplate에 이제 조치가 포함되어 있습니다. 여기에 더 많은 정보가 있습니다 : http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

최신 정보:

자, 이제 나는 당신이 여기에있는 것을 이해한다고 생각합니다.

아마도 당신은 action url 매개 변수가 필요하지 않으며 다른 방법으로 당신이 따르는 내용을 설명해야합니다. 메소드가 동일한 엔티티에서 데이터를 리턴한다고 말하고 있으므로 매개 변수가 설명을 수행하게하십시오.

예를 들어 두 가지 방법으로 전환 할 수 있습니다.

public HttpResponseMessage Get()
{
    return null;
}

public HttpResponseMessage Get(MyVm vm)
{
    return null;
}

MyVm 개체에 어떤 종류의 데이터를 전달하고 있습니까? URI를 통해 변수를 전달할 수 있다면 해당 경로로 이동하는 것이 좋습니다. 그렇지 않으면 요청 본문에 객체를 보내야하며 GET을 수행 할 때 HTTP가 아닙니다 (하지만 MyVm의 [FromBody]를 사용하십시오).

바라건대 이것은 액션 이름이나 [HttpGet] 속성을 사용하지 않고 단일 컨트롤러에서 여러 GET 메소드를 가질 수 있음을 보여줍니다.


어떤 방법 으로든 다른 장점이 있습니까? 보조를 수행하면 각 메소드에 Http 조치를 넣어야합니까? 그 큰 결점입니까?
chobo2

3
하나가 다른 것보다 유리한지 여부는 실제로 프로젝트에 달려 있습니다. RESTful API를 작성하는 경우 HTTP 규칙 (GET, POST, PUT, DELETE ...)을 사용하려고합니다. 이 경우 라우팅 코드의 첫 번째 블록은가는 방법이지만 API를 통해 노출되는 모든 엔티티에 대해 다른 컨트롤러를 원할 것입니다. 메소드 이름을 기반으로, 이것이 사실이 아니라고 생각하므로보다 상세한 라우팅을 사용하십시오. 라우트에 조치가 포함 된 경우 각 메소드에 http 속성을 명시 적으로 추가하려고합니다.
Jed

1
@ chobo2 왜 컨트롤러 내에서 적절하게 명명 된 메소드를 사용하지 않습니까? GetSummary (MyVm wm) 및 GetDetails ()
Jed

1
답장을 보내 주셔서 감사합니다. 두 작업의 이름이 다름에도 불구하고 경로 확인이 작동하지 않는 이유를 알아낼 수있었습니다. 왜 기본 동작이 아닌지 (예 : webapiconfig.cs의 기본 경로 템플릿이 "{action}"을 포함하지 않는 이유)에 대해 정말 혼란스러워합니다!
Tejas Sharma

1
@bruno 영역을 사용하는 경우 AdminAreaRegistration stackoverflow.com/a/9849011/16940
Simon_Weaver

67

Web API 2부터 업데이트하십시오.

WebApiConfig.cs 파일에서이 API 구성을 사용하면 :

public static void Register(HttpConfiguration config)
{
    //// Web API routes
    config.MapHttpAttributeRoutes(); //Don't miss this

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

컨트롤러를 다음과 같이 라우팅 할 수 있습니다.

[Route("api/ControllerName/Summary")]
[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    rturn null;
}

[Route("api/ControllerName/FullDetails")]
[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

여기서 ControllerName은 컨트롤러의 이름입니다 ( "컨트롤러"제외). 이를 통해 위에서 설명한 경로로 각 작업을 수행 할 수 있습니다.

더 읽을 거리 : http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2


나는이 솔루션을 정말 좋아했다. 내 기본 경로는 여전히 동일하며 예외에 대한 "예외"경로가 있습니다
Leandro De Mello Fagundes

매개 변수를 URL EX에 매핑 할 수도 있습니다. [Route ( "api / ControllerName / Summary / {vm}")]
nulltron

15

웹 API에서 (기본적으로) 메소드는 HTTP 메소드와 라우트 값조합을 기반으로 선택 됩니다 .

MyVm본문에서 포맷터로 읽은 복잡한 객체처럼 보이므로 경로 데이터와 관련하여 두 가지 동일한 방법이 있습니다 (라우터의 매개 변수가 없기 때문에) 발송자 ( IHttpActionSelector)가 적절한 것을 일치시킬 수 없습니다. .

모호성을 해결하려면 querystring 또는 route 매개 변수로 이들을 구별해야합니다.


14

웹을 많이 검색하고 다음을 찾은 경우 라우팅 맵에 가장 적합한 양식을 찾으려고 시도한 후

config.Routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id =RouteParameter.Optional }, new { id = @"\d+" });
config.Routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");

이 맵핑은 조치 이름 맵핑과 기본 http 규칙 (GET, POST, PUT, DELETE) 모두에 적용됩니다.


9
나를 위해이 일을 있지만 경로 구성에서 경로의 순서를 변경 한 후 작업을 함께 한 첫 등장 그래서
프레드릭 Stolpe을

정확한 순서는 여기에서 중요합니다
AT


5

조치를 사용하지 않으면 옵션은 다음과 같습니다.

  1. 메소드 중 하나를 다른 컨트롤러로 이동하여 충돌하지 않도록하십시오.

  2. 매개 변수를 취하는 하나의 메서드 만 사용하고 null 인 경우 코드에서 다른 메서드를 호출하십시오.


어쨌든 해결책이 될 수도 있지만 최적의 방법은 아닙니다. 내 편에서 +1 :)
satish kumar V

4

이 솔루션은 저에게 효과적이었습니다.

WebApiConfig에서 Route2를 먼저 배치하십시오. 또한 각 메소드 앞에 HttpGet 및 HttpPost를 추가하고 URL에 컨트롤러 이름 및 메소드 이름을 포함하십시오.

WebApiConfig =>

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

컨트롤러 =>

public class ValuesController : ApiController
{

    [HttpPost]
    public string GetCustomer([FromBody] RequestModel req)
    {
        return "Customer";
    }

    [HttpPost]
    public string GetCustomerList([FromBody] RequestModel req)
    {
        return "Customer List";
    }
}

URL =>

http://localhost:7050/api/Values/GetCustomer

http://localhost:7050/api/Values/GetCustomerList

4

이것은 모든 것이 올 바르고 50 회 확인 된 모든 사람을위한 답입니다 .....

반복해서보고 있지 않은지 확인하십시오 RouteConfig.cs.

편집하려는 파일의 이름이 지정됩니다 WebApiConfig.cs

또한 다음과 같이 보일 것입니다.

using System.Web.Http;

namespace My.Epic.Website
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
          config.MapHttpAttributeRoutes();

          // api/Country/WithStates
          config.Routes.MapHttpRoute(
            name: "ControllerAndActionOnly",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { },
            constraints: new { action = @"^[a-zA-Z]+([\s][a-zA-Z]+)*$" });

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

약 3 시간을 절약 할 수있었습니다.


1
고마워, 당신은 나를 약 3 시간 절약했다
geedubb

3

두 개의 Get 메소드가있을 때 하나는 매개 변수가없고 하나는 복잡한 유형의 매개 변수로 동일한 오류가 발생한다는 것을 알았습니다. 첫 번째 매개 변수로 Id라는 int 유형의 더미 매개 변수를 추가하고 복잡한 유형 매개 변수를 추가 하여이 문제를 해결했습니다. 그런 다음 복잡한 유형 매개 변수를 경로 템플릿에 추가했습니다. 다음은 나를 위해 일했습니다.

먼저 얻을 :

public IEnumerable<SearchItem> Get()
{
...
}

두 번째 :

public IEnumerable<SearchItem> Get(int id, [FromUri] List<string> layers)
{
...
}

WebApiConfig :

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

3

웹 API 컨트롤러 대신 MVC 컨트롤러를 사용하기 때문에 가능합니다. 웹 API 컨트롤러에서 네임 스페이스를 확인하십시오.

using System.Net;
using System.Net.Http;
using System.Web.Http;

네임 스페이스가 다음과 같으면 웹 API 컨트롤러 메소드 호출에서 위의 오류가 발생합니다.

using System.Web;
using System.Web.Mvc;

2

이름과 매개 변수가 다른 두 가지 방법이 있는지 확인하십시오.

그렇다면 방법을 삭제하고 시도하십시오.


2

추가 조치로 WebAPI 컨트롤러를 보강하려고 시도 하면서이 문제가 발생했습니다.

당신이 가지고 있다고 가정

public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

[HttpGet]
public void ReSeed()
{
    // Your custom action here
}

TS에 의해 기술 된 문제를 유발하는 / api / controller 요청을 만족시키는 두 가지 방법이 있습니다.

추가 작업에 "더미"매개 변수를 추가하고 싶지 않았으므로 기본 작업을 살펴보고 다음을 수행했습니다.

[ActionName("builtin")]
public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

"이중"경로 바인딩과 결합 된 첫 번째 방법의 경우 :

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "builtin", id = RouteParameter.Optional },
    constraints: new { id = @"\d+" });

config.Routes.MapHttpRoute(
    name: "CustomActionApi",
    routeTemplate: "api/{controller}/{action}");

첫 번째 라우트 템플리트에 "action"매개 변수가 없더라도 "일반"WebAPI 호출의 라우팅과 추가 조치에 대한 호출을 분리 할 수 ​​있도록 기본 조치를 여전히 구성 할 수 있습니다.


2

내 경우에는 모든 것이 옳았다

1) Web Config가 올바르게 구성되었습니다. 2) 경로 접두사 및 경로 속성이 적절합니다.

여전히 오류가 발생했습니다. 필자의 경우 "Route"속성 (F12를 누름)이 System.Web.MVc를 가리 키지 만 System.Web.Http가 아니라 문제를 일으켰습니다.


이 답변은 많은 도움이되었습니다!
tvb108108

1

[Route("api/[controller]/[action]")]컨트롤러 클래스에 추가 할 수 있습니다 .

[Route("api/[controller]/[action]")]
[ApiController]
public class MySuperController : ControllerBase
{
 ...
}

0

나는 그것이 오래된 질문이라는 것을 알고 있지만 때로는 AngularJS와 같은 서비스 리소스를 사용하여 WebAPI에 연결할 때 올바른 경로를 사용하고 있는지 확인하십시오. 그렇지 않으면이 오류가 발생합니다.


0

[HttpPost / Put / Get / Delete] 속성을 사용하여 기본 GET | PUT | POST | DELETE 작업에 대한 컨트롤러 메소드를 장식하지 마십시오. 이 복장을 바닐라 포스트 컨트롤러 작업에 추가했으며 404가 발생했습니다.

이것이 매우 실망스럽고 중단을 일으킬 수 있으므로 누군가에게 도움이되기를 바랍니다.


0

예를 들어 => TestController

        [HttpGet]
        public string TestMethod(int arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod2(string arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod3(int arg0,string arg1)
        {
            return "";
        }

WebApiConfig.cs 파일 만 변경할 수있는 경우

 config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/",
                defaults: null
            );

그게 다야 :)

그리고 결과 : 여기에 이미지 설명을 입력하십시오


0

다음과 같이 시도해 보셨습니까?

[HttpGet("Summary")]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[HttpGet("FullDetails")]
public HttpResponseMessage FullDetails()
{
    return null;
}

1
HttpGet특성에는 문자열 인수를 허용하는 생성자가 없으므로 .NET Core 이외의 프로젝트에서는 컴파일 되지 않습니다.
Hoppeduppeanut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.