문제

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 )
{
   ...
}

내가 가진 한 가지 제안은 이와 같은 경우, 두 가지 공개 행동 방법이 복제 코드를 피하기 위해 의존하는 개인 구현이라는 것입니다.

다음은 당신이 할 수있는 일이 있습니다 ... 당신은 매개 변수를 가질 수있는 메소드를 원합니다.

이걸 시도해 보지 않겠습니까 ...

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

이것은 저에게 효과적이었습니다 ... 그리고이 방법에서, 당신은 실제로 당신이 들어오는 매개 변수가 있는지 확인하기 위해 실제로 테스트 할 수 있습니다.


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

아니요, 아니요 및 아니요. "로드 커스토머"가 과부하 된 곳에서 아래 컨트롤러 코드를 사용해보십시오.

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

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

"Loadcustomer"동작을 호출하려고하면 아래 그림과 같이 오류가 발생합니다.

enter image description here

다형성은 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");
        }
    }

따라서 이제 URL "Customer/Loadcustomer"로 호출하면 "로드 커스토머"조치가 호출되고 URL 구조 "고객/LoadCustomerByName" "LoadCustomer (String STR)"가 호출됩니다.

enter image description here

enter image description here

위의 답변은이 CodeProject 기사 -> 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를 사용하여 10 년간의 웹 개발에서 온 MVC를 처음 접했지만 다음은 저에게 효과가있었습니다. 허용 된 답변과 달리 이것은 모든 과부하 작업을 동일한보기 파일로 렌더링 할 수 있습니다.

먼저 APP_START/ROUNECONFIG.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)
{
    //.....
}

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

당신은 싱글을 사용할 수 있습니다 ActionResult 둘 다 처리합니다 Post 그리고 Get:

public ActionResult Example() {
   if (Request.HttpMethod.ToUpperInvariant() == "GET") {
    // GET
   }
   else if (Request.HttpMethod.ToUpperInvariant() == "POST") {
     // Post  
   }
}

당신의 경우 유용합니다 Get 그리고 Post 방법에는 일치하는 서명이 있습니다.

방금이 질문을 발견했는데 지금은 꽤 오래되었지만 여전히 매우 관련이 있습니다. 아이러니하게도,이 스레드의 올바른 의견은 그가 게시물을 썼을 때 MVC의 자백 초보자에 의해 게시되었습니다. ASP.NET 문서조차도 완전히 맞지 않습니다. 큰 프로젝트가 있고 액션 방법을 과부하시킵니다.

간단한 {컨트롤러}/{action}/{id} 기본 경로 패턴을 넘어서 라우팅을 이해하면 고유 한 패턴을 사용하여 컨트롤러 작업을 매핑 할 수 있음이 분명 할 수 있습니다. 여기 누군가가 다형성에 대해 이야기하고 "HTTP는 다형성을 이해하지 못한다"고 말했다. 그러나 라우팅은 HTTP와 아무런 관련이 없다. 간단히 말해서 문자열 패턴 일치 메커니즘입니다.

이 작업을 수행하는 가장 좋은 방법은 예를 들어 라우팅 속성을 사용하는 것입니다.

[RoutePrefix("cars/{country:length(3)}")]
public class CarHireController
{
    [Route("{location}/{page:int=1}", Name = "CarHireLocation")]
    public ActionResult Index(string country, string location, int page)
    {
        return Index(country, location, null, page);
    }

    [Route("{location}/{subLocation}/{page:int=1}", Name = "CarHireSubLocation")]
    public ActionResult Index(string country, string location, string subLocation, int page)
    {
        //The main work goes here
    }
}

이러한 조치는 URL과 같은 URL을 처리합니다 /cars/usa/new-york 그리고 /cars/usa/texas/dallas, 이는 각각 첫 번째 및 두 번째 색인 작업에 매핑됩니다.

이 예제 컨트롤러를 살펴보면 위에서 언급 한 기본 경로 패턴을 넘어서는 것이 분명합니다. URL 구조가 코드 명명 규칙과 정확히 일치하는 경우 기본값이 잘 작동하지만 항상 그런 것은 아닙니다. 코드는 도메인을 설명해야하지만 URL은 종종 내용이 SEO 요구 사항과 같은 다른 기준을 기반으로하기 때문에 더 나아가 야합니다.

기본 라우팅 패턴의 이점은 자동으로 고유 한 경로를 생성한다는 것입니다. URL은 고유 한 컨트롤러 유형 및 멤버와 일치하므로 컴파일러에 의해 시행됩니다. 자신의 경로 패턴을 굴리면 독창성을 보장하고 작동하는 신중한 생각이 필요합니다.

중요 사항 한 가지 단점은 라우팅을 사용하여 오버로드 된 작업에 대한 URL을 생성하는 것이 조치 이름 (예 : urlhelper.action을 사용할 때 작동하지 않는다는 것입니다. 그러나 이름이 지정된 경로 (예 : urlhelper.routeurl)를 사용하는 경우 작동합니다. 그리고 명명 된 경로를 사용하는 것은 잘 존경받는 출처에 따르면 어쨌든가는 길입니다 (http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx/).

행운을 빕니다!

ActionName ( "NewActionName")]을 사용하여 다른 이름의 동일한 메소드를 사용할 수 있습니다.

public class HomeController : Controller
{
    public ActionResult GetEmpName()
    {
        return Content("This is the test Message");
    }

    [ActionName("GetEmpWithCode")]
    public ActionResult GetEmpName(string EmpCode)
    {
        return Content("This is the test Messagewith Overloaded");
    }
}

과부하가 필요했습니다.

public ActionResult Index(string i);
public ActionResult Index(int groupId, int itemId);

내가 이것을하게 된 충분한 주장은 거의 없었다.

public ActionResult Index(string i, int? groupId, int? itemId)
{
    if (!string.IsNullOrWhitespace(i))
    {
        // parse i for the id
    }
    else if (groupId.HasValue && itemId.HasValue)
    {
        // use groupId and itemId for the id
    }
}

특히 많은 논쟁이 있다면 완벽한 해결책은 아니지만 나에게 잘 작동합니다.

응용 프로그램에서도 같은 문제에 직면했습니다. Modifiyig가없는 방법 정보가 없으면 Action Head에 [ActionName ( "Somemeaningfulname")]을 제공했습니다. 문제가 해결되었습니다

[ActionName("_EmployeeDetailsByModel")]
        public PartialViewResult _EmployeeDetails(Employee model)
        {
            // Some Operation                
                return PartialView(model);
            }
        }

[ActionName("_EmployeeDetailsByModelWithPagination")]
        public PartialViewResult _EmployeeDetails(Employee model,int Page,int PageSize)
        {

                // Some Operation
                return PartialView(model);

        }

기본 메소드를 가상으로 만듭니다

public virtual ActionResult Index()

재정의 메소드를 재정의로 만듭니다

public override ActionResult Index()

편집 : 이것은 OPERIDE 메소드가 OP의 의도가 아닌 것으로 보이는 파생 클래스에있는 경우에만 적용됩니다.

다른 스레드에 게시 된이 답변이 마음에 듭니다

다른 컨트롤러에서 상속하고 기본 컨트롤러에서 Acction을 무시하려는 경우 주로 사용됩니다.

ASP.NET MVC- 매개 변수가 다른 작업을 재정의합니다

각 컨트롤러 방법에 대해 허용되는 공개 서명은 하나뿐입니다. 과부하하려고하면 컴파일되지만 경험 한 런타임 오류가 발생합니다.

다른 동사를 기꺼이 사용하지 않는다면 ( [HttpGet] 그리고 [HttpPost] 속성) 오버로드 된 메소드를 구별하거나 라우팅을 변경하려면 다른 메소드에 다른 이름을 제공하거나 기존 메소드 내부에서 발송할 수 있다는 것입니다. 내가 한 방법은 다음과 같습니다.

나는 한 번 거꾸로 호환성을 유지 해야하는 상황에 빠졌다. 원래 방법은 두 개의 매개 변수를 예상했지만 새 방법에는 하나만있었습니다. MVC가 더 이상 진입 지점을 찾지 못했기 때문에 예상되는 방식을 과부하시키는 것은 작동하지 않았습니다.

그것을 해결하기 위해 다음을 수행했습니다.

  1. 2 개의 과부하 작업 방법을 공개에서 개인으로 변경했습니다.
  2. "단지"2 문자열 매개 변수를 포함하는 하나의 새로운 공개 방법을 만들었습니다. 그 사람은 파견자 역할을했습니다.

    public ActionResult DoSomething(string param1, string param2)
    {
        if (string.IsNullOrEmpty(param2))
        {
            return DoSomething(ProductName: param1);
        }
        else
        {
            int oldId = int.Parse(param1);
            return DoSomething(OldParam: param1, OldId: oldId);
        }
    }
    
    
    private ActionResult DoSomething(string OldParam, int OldId)
    {
        // some code here
        return Json(result);
    }
    
    
    private ActionResult DoSomething(string ProductName)
    {
        // some code here
        return Json(result);
    }
    

물론 이것은 해킹이며 나중에 리팩토링되어야합니다. 그러나 당분간은 나를 위해 일했습니다.

다음과 같은 디스패처를 만들 수도 있습니다.

public ActionResult DoSomething(string action, string param1, string param2)
{
    switch (action)
    {
        case "update":
            return UpdateAction(param1, param2);
        case "remove":
            return DeleteAction(param1);
    }
}

UpdateAction에는 2 개의 매개 변수가 필요하지만 deleteection은 하나만 필요합니다.

이것이 다른 모델을 가진 여러 동작에 게시하는 여러 뷰에 대해 하나의 GET 조치를 사용하려는 시도라면, 첫 번째 Get Get Get 404로 리디렉션되는 각 게시물 조치에 대해 GET 조치를 추가하십시오.

긴 샷이지만 일반적인 시나리오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top