当前位置:  开发笔记 > 编程语言 > 正文

你能在ASP.NET MVC中重载控制器方法吗?

如何解决《你能在ASP.NETMVC中重载控制器方法吗?》经验,为你挑选了7个好方法。

我很想知道你是否可以重载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



1> JD Conley..:

如果希望代码执行重载,可以使用该属性.

[ActionName("MyOverloadedName")]

但是,你必须为同一个http方法使用不同的动作名称(正如其他人所说).所以这就是语义.您希望在代码或属性中使用该名称吗?

Phil有一篇与此相关的文章:http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx


实际上,它仍然可以呈现相同的视图文件.您只需要指定视图的名称,而不是盲目地调用`return View();`.例如:`return View("MyOverloadedName");`.
使用它和重载操作的主要缺点是它不能再由同一个视图文件呈现.

2> tvanfosson..:

是.我已经能够通过将每个控制器方法的HttpGet/ HttpPost(或等效AcceptVerbs属性)设置为不同的东西来实现,即,HttpGet或者HttpPost,但不是两者.这样它就可以根据请求的类型判断使用哪种方法.

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

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

我的一个建议是,对于这样的情况,将有一个私有实现,你的两个公共Action方法都依赖于它来避免重复代码.


请注意不要滥用它以违反REST原理。

3> 小智..:

这是你可以做的其他事情......你想要一个能够有参数的方法而不是.

为什么不尝试这个......

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

这对我有用......在这一种方法中,您可以实际测试以查看是否有传入参数.


已更新以删除字符串上的无效可空语法并使用默认参数值.


string可以为空.事实上,它已经可以为空了,只是不需要'?'
@ProfK - 不,string是一个可以为null的引用类型.它不是"可空的".Nullable意味着你正在使用Nullable (即T?).乔希的观点是,你不能把?在字符串之后,因为它不是值类型,Nullable 只接受值类型.
(`string`不能为空.)
我随机找回了这个问题,然后意识到我发布了上面的评论.没有回忆这个......很奇怪!"string"不能是"可空"的,这仍然是正确的.但它可以是'null`!无论哪种方式,我都没有诚意地发布了最初的评论.

4> Shivprasad K..:

不,不,不.去试试下面的控制器代码,我们将"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重载



5> Ian Mercer..:

要解决此问题,您可以编写一个ActionMethodSelectorAttribute检查MethodInfo每个操作的内容并将其与发布的Form值进行比较,然后拒绝任何表单值不匹配的方法(当然不包括按钮名称).

这是一个例子: - http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/

但是,这不是一个好主意.



6> keeney..:

据我所知,在使用不同的http方法时,你只能使用相同的方法.

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

}

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

}


装饰与过载无关.它是允许重载的参数列表.

7> cookdn..:

我已经在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)
{
    //.....
}

希望这有助于并且不会导致某人走上错误的道路.:-)

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有