PositiveGuy
PositiveGuy

Reputation: 47763

2 of Same method Names in Controller wired up to Routes with Web API

It's been a while since I've done some controller code in MVC. But is it possible to have overloads of the same method name in your controller such as:

(this is pseudo code, it's not perfect)

[HttpGet] Get()

[HttpGet] Get(int id)

I think you can right? You differentiate that with the route pattern right? Just rechecking, I am working with WCF and I just wondering if I could do this in MVC and I think I could in the past, just don't recall. WCF bitches when you have 2 overloads with method name Get when using WebGet and it's bugging the hell out of me...I don't like that.

Upvotes: 1

Views: 384

Answers (2)

Josh
Josh

Reputation: 557

Use attribute routing.

Add this to your WebApiConfig file:

config.MapHttpAttributeRoutes();

You can then use attributes to specify your routes and required parameters.

[HttpGet]
[Route("/api/mycontroller")]
public IHttpActionResult Get()
{
    var myQuery = {your query};
    return Ok(myQuery);
}

[HttpGet]
[Route("/api/mycontroller/{id:int}")]
public IHttpActionResult Get(int id)
{
    var myQuery = {your query};
    return Ok(myQuery);
}

You can shorten your route attributes by putting a RoutePrefix on your controller.

[RoutePrefix("api/mycontroller")]
public class MyControllerController : WebApiController
{
    ...
}

Then you can cut out that portion on your action routes.

[HttpGet]
[Route("")]
public IHttpActionResult Get()
{
    ...
}

[HttpGet]
[Route("{id:int}")]
public IHttpActionResult Get(int id)
{
    ...
}

Also, you don't NEED to specify the data type in your route parameter:

[Route("{id}")]

I just like strongly typed stuff.

Upvotes: 0

Mikael Engver
Mikael Engver

Reputation: 4768

es you can have overloads but each extra overload has to be marked with the [ActionName] attribute. Otherwise the controller will get confused and throw a AmbiguousMatchException at runtime, but the overloads will compile.

Here is an example with overloads added a Default Home Controller:

public class HomeController : Controller
{
    // Default Action method.
    // Url: /Home
    public ActionResult Index()
    {
        ViewBag.Message = "jump-start your ASP.NET MVC application.";

        return View();
    }

    // Url: /Home/About
    public ActionResult About()
    {
        ViewBag.Message = "Your app description page.";

        return View();
    }

    // Url: /Home/AboutByInt/3
    [ActionName("AboutByInt")]
    public ActionResult About(int id)
    {
        ViewBag.Message = "Your app description page. The Id is: " + id;

        return View();
    }
}

An alternative is to use nullable arguments, that can supplied or not supplied to the Action method:

// Url: /Home/Contact
public ActionResult Contact(int? id)
{
    if (id == null)
    {
        // Page was accessed by url: /Home/Contact
        ViewBag.Message = "id is null";
    }
    else
    {
        // Page was accessed by url: /Home/Contact/[int]
        ViewBag.Message = "id is : " + id;
    }

    return View();
}

Upvotes: 1

Related Questions