我很想知道你是否可以重载ASP.NET MVC中的控制器方法.每当我尝试时,我都会收到以下错误.这两种方法接受不同的论点.这是不能做的事吗?
控制器类型'MyController'上的当前操作请求'MyMethod'在以下操作方法之间是不明确的:
JD Conley.. 199
如果希望代码执行重载,可以使用该属性.
[ActionName("MyOverloadedName")]
但是,你必须为同一个http方法使用不同的动作名称(正如其他人所说).所以这就是语义.您希望在代码或属性中使用该名称吗?
Phil有一篇与此相关的文章:http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx
如果希望代码执行重载,可以使用该属性.
[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 ) { ... }
这对我有用......在这一种方法中,您可以实际测试以查看是否有传入参数.
不,不,不.去试试下面的控制器代码,我们将"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"); } }
因此,现在如果您调用URL"Customer/LoadCustomer",将调用"LoadCustomer"操作,并使用URL结构"Customer/LoadCustomerByName"调用"LoadCustomer(string str)".
上面的答案我已经从这个代码项目文章 - > MVC Action重载
要解决此问题,您可以编写一个ActionMethodSelectorAttribute
检查MethodInfo
每个操作的内容并将其与发布的Form值进行比较,然后拒绝任何表单值不匹配的方法(当然不包括按钮名称).
这是一个例子: - 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进行十年Web开发的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) { //..... }
希望这有助于并且不会导致某人走上错误的道路.:-)