我很好奇你是否可以重载控制器方法在ASP。净MVC。每当我尝试时,都会得到下面的错误。这两个方法接受不同的参数。这是做不到的事情吗?
当前对控制器类型“MyController”上的动作“MyMethod”的请求在以下动作方法之间是不明确的:
我很好奇你是否可以重载控制器方法在ASP。净MVC。每当我尝试时,都会得到下面的错误。这两个方法接受不同的参数。这是做不到的事情吗?
当前对控制器类型“MyController”上的动作“MyMethod”的请求在以下动作方法之间是不明确的:
当前回答
您可以使用[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 Show( string username = null )
{
...
}
这对我很有效……在这个方法中,你可以测试是否有传入参数。
已更新以删除字符串上无效的nullable语法并使用默认参数值。
为了克服这个问题,你可以编写一个ActionMethodSelectorAttribute来检查每个动作的MethodInfo,并将其与发布的表单值进行比较,然后拒绝任何与表单值不匹配的方法(当然,不包括按钮名称)。
举个例子:- http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/
但是,这不是一个好主意。
如果这是尝试对几个视图使用一个GET操作,这些视图POST到不同模型的几个操作,那么尝试为每个POST操作添加一个GET操作,重定向到第一个GET,以防止刷新时出现404。
可能性不大,但很常见。
如果您希望代码进行重载,可以使用该属性。
[ActionName("MyOverloadedName")]
但是,您必须为相同的http方法使用不同的操作名称(正如其他人所说)。所以这只是语义上的。您希望在代码中使用名称还是属性中使用名称?
Phil有一篇相关的文章:http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx
每个控制器方法只允许有一个公共签名。如果您试图重载它,它将被编译,但您将得到您所经历的运行时错误。
如果您不愿意使用不同的动词(如[HttpGet]和[HttpPost]属性)来区分重载方法(这将工作),或者更改路由,那么剩下的就是您可以提供另一个具有不同名称的方法,或者您可以在现有方法内部分派。我是这样做的:
我曾经遇到过必须保持向后兼容性的情况。原来的方法需要两个参数,但新的方法只有一个参数。重载我所期望的方式没有工作,因为MVC不再找到入口点。
为了解决这个问题,我做了以下事情:
Changed the 2 overloaded action methods from public to private Created one new public method which contained "just" 2 string parameters. That one acted as a dispatcher, i.e.: 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); }
当然,这是一个hack,应该稍后进行重构。但就目前而言,它对我有用。
你也可以创建一个dispatcher:
public ActionResult DoSomething(string action, string param1, string param2)
{
switch (action)
{
case "update":
return UpdateAction(param1, param2);
case "remove":
return DeleteAction(param1);
}
}
可以看到,UpdateAction需要2个参数,而DeleteAction只需要一个参数。