programing

웹 API 라우팅 - api/{controller}/{action}/{id} "dysfunctions" api/{controller}/{id}

batch 2023. 4. 26. 23:08
반응형

웹 API 라우팅 - api/{controller}/{action}/{id} "dysfunctions" api/{controller}/{id}

Global.asax에 기본 Route가 있습니다.

 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)경기api/{controller}/{id}그것이 틀을 혼란스럽게 하는 입니다.

기본 API 경로가 다시 작동하고 다음 경로를 유지하려면 어떻게 해야 합니까?{action}다른 컨트롤러를 만들까 생각했습니다.RecordByCategoryIdController기본 API 경로와 일치하도록 요청합니다..../api/recordbycategoryid/5하지만 저는 그것이 "더러운" 해결책(따라서 불만족스러운)이라는 것을 알게 되었습니다.나는 이에 대한 답을 찾았지만 경로 사용에 대한 튜토리얼은 없습니다.{action}심지어 이 문제를 언급합니다.

경로 엔진은 규칙을 추가할 때와 동일한 시퀀스를 사용합니다.첫 번째 일치 규칙을 가져오면 다른 규칙 검사를 중지하고 컨트롤러 및 작업을 검색합니다.

따라서 다음을 수행해야 합니다.

  1. 사용을 의미하는 일반 규칙(기본값)보다 특정 규칙을 우선합니다.RouteTable.Routes.MapHttpRoute먼저 "WithActionApi"를 매핑한 다음 "DefaultApi"를 매핑합니다.

  2. 제거합니다.defaults: new { id = System.Web.Http.RouteParameter.Optional }일단 id가 선택 사항이므로 "WithActionApi" 규칙의 매개 변수입니다. "/api/{part1}/{part2}"과 같은 URL은 "DefaultApi"에 들어가지 않습니다.

  3. "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 }
        );
    }
}

속성 라우팅 및 컨벤션 기반 라우팅에 대한 자세한 내용은 여기 및 이 문서를 참조하십시오.

이거 먹어봐요.

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 }
         );  

언급URL : https://stackoverflow.com/questions/13596391/web-api-routing-api-controller-action-id-dysfunctions-api-controller

반응형