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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/436866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 03:21:13  来源:igfitidea点击:

Can you overload controller methods in ASP.NET MVC?

c#asp.net-mvcoverloading

提问by Papa Burgundy

I'm curious to see if you can overload controller methods in ASP.NET MVC. Whenever I try, I get the error below. The two methods accept different arguments. Is this something that cannot be done?

我很好奇您是否可以在 ASP.NET MVC 中重载控制器方法。每当我尝试时,都会收到以下错误。这两种方法接受不同的参数。这是不能做的事吗?

The current request for action 'MyMethod' on controller type 'MyController' is ambiguous between the following action methods:

当前对控制器类型“MyController”的操作“MyMethod”的请求在以下操作方法之间不明确:

采纳答案by JD Conley

You can use the attribute if you want your code to do overloading.

如果您希望代码进行重载,则可以使用该属性。

[ActionName("MyOverloadedName")]

But, you'll have to use a different action name for the same http method (as others have said). So it's just semantics at that point. Would you rather have the name in your code or your attribute?

但是,您必须为相同的 http 方法使用不同的操作名称(正如其他人所说)。所以在这一点上它只是语义。您更愿意在代码或属性中使用名称?

Phil has an article related to this: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx

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

回答by keeney

As far as I know you can only have the same method when using different http methods.

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

i.e.

IE

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

}

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

}

回答by tvanfosson

Yes. I've been able to do this by setting the HttpGet/HttpPost(or equivalent AcceptVerbsattribute) for each controller method to something distinct, i.e., HttpGetor HttpPost, but not both. That way it can tell based on the type of request which method to use.

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

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

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

One suggestion I have is that, for a case like this, would be to have a private implementation that both of your public Action methods rely on to avoid duplicating code.

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

回答by Ian Mercer

To overcome this problem you canwrite an ActionMethodSelectorAttributethat examines the MethodInfofor each action and compares it to the posted Form values and then rejects any method for which the form values don't match (excluding the button name, of course).

为了克服这个问题,您可以编写一个ActionMethodSelectorAttribute检查MethodInfo每个操作的 ,并将其与发布的表单值进行比较,然后拒绝表单值不匹配的任何方法(当然不包括按钮名称)。

Here's an example:- http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/

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

BUT, this isn't a good idea.

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

回答by Farrel

Here's something else you could do... you want a method that is able to have a parameter and not.

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

Why not try this...

为什么不试试这个...

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

This has worked for me... and in this one method, you can actually test to see if you have the incoming parameter.

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



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

回答by Andiih

Create the base method as virtual

将基本方法创建为虚拟

public virtual ActionResult Index()

Create the overridden method as override

创建覆盖的方法作为覆盖

public override ActionResult Index()

Edit: This obviously applies only if the override method is in a derived class which appears not to have been the OP's intention.

编辑:这显然仅适用于覆盖方法位于派生类中的情况,而派生类似乎不是 OP 的意图。

回答by DevDave

You could use a single ActionResultto deal with both Postand Get:

您可以使用单个ActionResult来处理PostGet

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

Useful if your Getand Postmethods have matching signatures.

如果您的GetPost方法具有匹配的签名,则很有用。

回答by Kasey Speakman

I needed an overload for:

我需要一个重载:

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

There were few enough arguments where I ended up doing this:

我最终这样做的论据很少:

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
    }
}

It's not a perfect solution, especially if you have a lot of arguments, but it works well for me.

这不是一个完美的解决方案,特别是如果你有很多争论,但它对我来说效果很好。

回答by Keyjote

I like this answer posted in another thread

我喜欢在另一个帖子中发布的这个答案

This is mainly used if you inherit from another controller and want to override an acction from the base controller

这主要用于如果您从另一个控制器继承并希望覆盖来自基本控制器的操作

ASP.NET MVC - Overriding an action with differing parameters

ASP.NET MVC - 覆盖具有不同参数的操作

回答by Shivprasad Ktheitroadala

No,No and No. Go and try the controller code below where we have the "LoadCustomer" overloaded.

不,不,不。去试试下面的控制器代码,我们重载了“LoadCustomer”。

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

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

If you try to invoke the "LoadCustomer" action you will get error as shown in the below figure.

如果您尝试调用“LoadCustomer”操作,您将收到如下图所示的错误。

enter image description here

在此处输入图片说明

Polymorphism is a part of C# programming while HTTP is a protocol. HTTP does not understand polymorphism. HTTP works on the concept's or URL and URL can only have unique name's. So HTTP does not implement polymorphism.

多态是 C# 编程的一部分,而 HTTP 是一种协议。HTTP 不理解多态性。HTTP 适用于概念或 URL,而 URL 只能具有唯一名称。所以 HTTP 没有实现多态。

In order to fix the same we need to use "ActionName" attribute.

为了解决这个问题,我们需要使用“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");
        }
    }

So now if you make a call to URL "Customer/LoadCustomer" the "LoadCustomer" action will be invoked and with URL structure "Customer/LoadCustomerByName" the "LoadCustomer(string str)" will be invoked.

因此,现在如果您调用 URL“Customer/LoadCustomer”,将调用“LoadCustomer”操作,并使用 URL 结构“Customer/LoadCustomerByName”调用“LoadCustomer(string str)”。

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

The above answer i have taken from this codeproject article --> MVC Action overloading

我从这篇 codeproject 文章中获得的上述答案 --> MVC Action 重载