[C#] ASP.NET MVC에서 컨트롤러 메서드를 오버로드 할 수 있습니까?

ASP.NET MVC에서 컨트롤러 메서드를 오버로드 할 수 있는지 궁금합니다. 시도 할 때마다 아래 오류가 발생합니다. 두 가지 방법은 서로 다른 주장을 받아들입니다. 할 수없는 일입니까?

컨트롤러 유형 ‘MyController’에서 ‘MyMethod’조치에 대한 현재 요청은 다음 조치 메소드간에 모호합니다.



답변

코드가 오버로드되도록하려면 속성을 사용할 수 있습니다.

[ActionName("MyOverloadedName")]

그러나 동일한 http 메소드에 다른 액션 이름을 사용해야합니다 (다른 사람들이 말했듯이). 그래서 그것은 단지 의미 론적입니다. 오히려 코드 또는 속성에 이름이 있습니까?

Phil은 이와 관련된 기사를 가지고 있습니다 : http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx


답변

예. 각 컨트롤러 메소드 의 HttpGet/ HttpPost(또는 동등한 AcceptVerbs속성)을 고유 한 것으로 즉, HttpGet또는 HttpPost둘 다로 설정 하여이 작업을 수행 할 수있었습니다 . 그렇게하면 요청 유형에 따라 사용할 방법을 알 수 있습니다.

[HttpGet]
public ActionResult Show()
{
   ...
}

[HttpPost]
public ActionResult Show( string userName )
{
   ...
}

내가 가진 제안 중 하나는 이와 같은 경우 두 개의 공용 Action 메소드가 코드 중복을 피하기 위해 의존하는 개인 구현을 갖는 것입니다.


답변

여기 당신이 할 수있는 또 다른 것이 있습니다 … 당신은 매개 변수를 가질 수 있고 가질 수없는 방법을 원합니다.

이것을 시도해보십시오 …

public ActionResult Show( string username = null )
{
   ...
}

이것은 나를 위해 일했습니다 …이 방법에서는 실제로 들어오는 매개 변수가 있는지 테스트 할 수 있습니다.


문자열에서 잘못된 nullable 구문을 제거하고 기본 매개 변수 값을 사용하도록 업데이트되었습니다.


답변

아니요, 아니요 및 아니요. “LoadCustomer”가 오버로드 된 컨트롤러 코드를 아래에서 시도하십시오.

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

“LoadCustomer”조치를 호출하려고하면 아래 그림과 같이 오류가 발생합니다.

여기에 이미지 설명을 입력하십시오

다형성은 C # 프로그래밍의 일부이며 HTTP는 프로토콜입니다. HTTP는 다형성을 이해하지 못합니다. HTTP는 개념이나 URL에서 작동하며 URL은 고유 한 이름 만 가질 수 있습니다. 따라서 HTTP는 다형성을 구현하지 않습니다.

같은 것을 고치려면 “ActionName”속성을 사용해야합니다.

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }

        [ActionName("LoadCustomerbyName")]
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

따라서 “Customer / LoadCustomer”URL을 호출하면 “LoadCustomer”조치가 호출되고 URL 구조 “Customer / LoadCustomerByName”을 사용하여 “LoadCustomer (string str)”가 호출됩니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

이 코드 프로젝트 기사에서 가져온 위의 답변-> MVC 작업 오버로드


답변

이 문제를 극복하기 위해 할 수 쓰기 ActionMethodSelectorAttribute을 검사하는 MethodInfo각 작업과 게시 된 양식 값과 비교를 한 후 (물론, 버튼 이름 제외) 형태의 값이 일치하지 않은 어떤 방법을 거부합니다.

예를 들면 다음과 같습니다 .- http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/

그러나 이것은 좋은 생각이 아닙니다.


답변

내가 아는 한 다른 http 메소드를 사용할 때 동일한 메소드 만 가질 수 있습니다.

[AcceptVerbs("GET")]
public ActionResult MyAction()
{

}

[AcceptVerbs("POST")]
public ActionResult MyAction(FormResult fm)
{

}


답변

MVC5 의 속성 라우팅 을 사용하여 이것을 달성했습니다 . 분명히 WebForms를 사용하여 수십 년 동안 웹을 개발 한 MVC를 처음 접했지만 다음과 같은 결과가 나에게 도움이되었습니다. 허용되는 답변과 달리 오버로드 된 모든 작업을 동일한 뷰 파일로 렌더링 할 수 있습니다.

먼저 App_Start / RouteConfig.cs에서 속성 라우팅을 활성화하십시오.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

선택적으로 기본 경로 접두어로 컨트롤러 클래스를 장식하십시오.

[RoutePrefix("Returns")]
public class ReturnsController : BaseController
{
    //.......

그런 다음 공통 경로 및 매개 변수로 서로 과부하되는 컨트롤러 조치를 장식하십시오. 유형 제한 매개 변수를 사용하면 유형이 다른 ID와 동일한 URI 형식을 사용할 수 있습니다.

[HttpGet]
// Returns
public ActionResult Index()
{
    //.....
}

[HttpGet]
[Route("View")]
// Returns/View
public ActionResult View()
{
    // I wouldn't really do this but it proves the concept.
    int id = 7026;
    return View(id);
}

[HttpGet]
[Route("View/{id:int}")]
// Returns/View/7003
public ActionResult View(int id)
{
    //.....
}

[HttpGet]
[Route("View/{id:Guid}")]
// Returns/View/99300046-0ba4-47db-81bf-ba6e3ac3cf01
public ActionResult View(Guid id)
{
    //.....
}

이것이 도움이되고 누군가를 잘못된 길로 인도하지 않기를 바랍니다. 🙂