ASP.NET MVC3 : ActionMethod with same name and different arguments for List and Details view

1.1k Views Asked by At

I have a ProdcutsController where i have 2 Action methods. Index and Details. Index will return list of products and Details will return details of a selected product id.

So my urls are like

sitename/Products/   

will load index view to show a list of products.

 sitename/Products/Details/1234  

will load details view to show the details of product 1234.

Now i want to avoid the "Details" word from my second url. so that it should look like

   sitename/Products/1234 

I tried to rename my action method from "Details" to "Index" with a parameter in it. But it showed me the error "Method is is ambiguous"

I tried this

 public ActionResult Index()
{
    //code to load Listing view
}
public ActionResult Index(string? id)
{
    //code to load details view
}

I am getting this error now

The type 'string' must be a non-nullable value type in order to use
it as parameter 'T' in the generic type or method 'System.Nullable<T>

Realized that it does not support method overloading ! How do i handle this ? should i update my route definition ?

3

There are 3 best solutions below

2
On

Use this:

public ActionResult Index(int? id)
{
    //code to load details view
}

Assuming the value is an integer type.

This is another option:

public ActionResult Index(string id)
{
    //code to load details view
}

A string is a reference type so a null can already be assigned to it without needing a Nullable<T>.

1
On

You can just use one Action method.

Something like:

public ActionResult Index(int? Id)
{
  if(Id.HasValue)
  {
    //Show Details View
  }
  else
  {
    //Show List View
  }
}
0
On

You can create two routes and use route constraints:

Global.asax

        routes.MapRoute(
            "Details", // Route name
            "{controller}/{id}", // URL with parameters
            new { controller = "Products", action = "Details" }, // Parameter defaults
            new { id = @"\d+" }
        );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

First route has a constraint that requires id to have one or more digits. Because of this constraint it won't catch routes like ~/home/about etc.

ProductsController

    public ActionResult Index()
    {
        // ...
    }

    public ActionResult Details(int id)
    {
        // ...
    }