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
Can you overload controller methods in ASP.NET MVC?
提问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 AcceptVerbs
attribute) for each controller method to something distinct, i.e., HttpGet
or HttpPost
, but not both. That way it can tell based on the type of request which method to use.
是的。我已经能够通过将每个控制器方法的HttpGet
/ HttpPost
(或等效AcceptVerbs
属性)设置为不同的东西来做到这一点,即,HttpGet
or 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 ActionMethodSelectorAttribute
that examines the MethodInfo
for 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 ActionResult
to deal with both Post
and Get
:
您可以使用单个ActionResult
来处理Post
和Get
:
public ActionResult Example() {
if (Request.HttpMethod.ToUpperInvariant() == "GET") {
// GET
}
else if (Request.HttpMethod.ToUpperInvariant() == "POST") {
// Post
}
}
Useful if your Get
and Post
methods have matching signatures.
如果您的Get
和Post
方法具有匹配的签名,则很有用。
回答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
回答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”操作,您将收到如下图所示的错误。
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)”。
The above answer i have taken from this codeproject article --> MVC Action overloading
我从这篇 codeproject 文章中获得的上述答案 --> MVC Action 重载