Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I overload ASP.NET MVC Actions based on the accepted HTTP verbs?

Wanted to use the same URL for a GET/PUT/DELETE/POST for a REST based API, but when the only thing different about the Actions is which HTTP verbs it accepts, it considers them to be duplicate!

"Type already defines a member called 'Index' with the same parameter types."

To which I said, so what? This one only accepts GET, this one only accepts POST... should be able to be co-exist right?

How?

like image 878
MetaGuru Avatar asked Jun 14 '11 18:06

MetaGuru


People also ask

Can we overload action method in MVC?

If we have to overload the action Method in asp.net MVC then we can not do it directly. We have to change the ActionName like this code snippet. Now to run the controller GetEmpName action method with just give the URL like this: http://localhost:49389/Home/GetEmpName.

Can you overload controller method in ASP.NET MVC?

There is only one public signature allowed for each controller method. If you try to overload it, it will compile, but you're getting the run-time error you've experienced.

What are the HTTP methods supported by MVC controller?

The MVC framework includes HttpGet, HttpPost, HttpPut, HttpDelete, HttpOptions, and HttpPatch action verbs. You can apply one or more action verbs to an action method to handle different HTTP requests. If you don't apply any action verbs to an action method, then it will handle HttpGet request by default.

Can we use same action name in MVC?

While ASP.NET MVC will allow you to have two actions with the same name, . NET won't allow you to have two methods with the same signature - i.e. the same name and parameters. You will need to name the methods differently use the ActionName attribute to tell ASP.NET MVC that they're actually the same action.


3 Answers

That's not ASP.NET MVC limitation or whatever. It's .NET and how classes work: no matter how hard you try, you cannot have two methods with the same name on the same class which take the same parameters. You could cheat using the [ActionName] attribute:

[HttpGet] [ActionName("Foo")] public ActionResult GetMe() {    ... }  [HttpPut] [ActionName("Foo")] public ActionResult PutMe() {    ... }  [HttpDelete] [ActionName("Foo")] public ActionResult DeleteMe() {    ... }  [HttpPost] [ActionName("Foo")] public ActionResult PostMe() {    ... } 

Of course in a real RESTFul application the different verbs would take different parameters as well, so you will seldom have such situations.

You may take a look at SimplyRestful for some ideas about how your routes could be organized.

like image 135
Darin Dimitrov Avatar answered Sep 24 '22 17:09

Darin Dimitrov


While ASP.NET MVC will allow you to have two actions with the same name, .NET won't allow you to have two methods with the same signature - i.e. the same name and parameters.

You will need to name the methods differently use the ActionName attribute to tell ASP.NET MVC that they're actually the same action.

That said, if you're talking about a GET and a POST, this problem will likely go away, as the POST action will take more parameters than the GET and therefore be distinguishable.

So, you need either:

[HttpGet] public ActionResult ActionName() {...}  [HttpPost, ActionName("ActionName")] public ActionResult ActionNamePost() {...} 

Or:

[HttpGet] public ActionResult ActionName() {...}  [HttpPost] public ActionResult ActionName(string aParameter) {...} 
like image 34
Thom Avatar answered Sep 25 '22 17:09

Thom


Another option is to have a single method that accepts all and distinguishes between HttpMethod and calls the appropriate code from there. E.g.

            string httpMethod = Request.HttpMethod.ToUpperInvariant();

            switch (httpMethod)
            {
                case "GET":
                    return GetResponse();

                case "POST":
                    return PostResponse();

                default:
                    throw new ApplicationException(string.Format("Unsupported HttpMethod {0}.", httpMethod));
            }
like image 23
The Coder Avatar answered Sep 23 '22 17:09

The Coder