3
votes

I have a web page www.example.com which points to a HomeController index. When I run the website I get the HomeView.

Now the requirement is when I type www.example.com/Japan I need to run a different view.

What I did:

 public ActionResult Index(string country)
    {
        ViewBag.Message = "my country=" + country;

        return View();
    }

But it gives me an error:

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

System.Web.Mvc.ActionResult Index() on type MvcApplication_2.Controllers.HomeController System.Web.Mvc.ActionResult Index(System.String) on type MvcApplication_2.Controllers.HomeController

What should I be doing to achieve this one?

I do not want to use http://example.com/country/japan.

I want to use http://example.com/japan.

my code: RouteConfig.cs

 namespace MvcApplication_2
 {
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

        routes.MapRoute(
        name: "ByCountry",
        url: "{country}",
        defaults: new { controller = "Home", action = "IndexByCountry" }
    );


    }
}

}

Homecontroller.cs

 public class HomeController : Controller
 {
    [HttpGet]
    public ActionResult Index()
    {
        ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

        return View();
    }


    [ActionName("IndexByCountry")]
    public ActionResult Index(string country)
    {
        ViewBag.Message = "Japan man.";

        return View("Index");
    }

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

        return View();
    }

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }
}
2
Can you post your route definitions?Thomas Stringer
just the default route definitions. I have not added any one.Venkat
You need to register the ByCountry route before the Default route. Switch up that order so the default route is last.Thomas Stringer

2 Answers

5
votes

You can't have the same HTTP verb for the same action name. In other words, having HttpGet for the same action name, even an overload, isn't possible.

You have three options:

Change one or your action methods to a different HTTP action verb...

[HttpGet]
public ActionResult Index()
{
    //..
}

[HttpPost]
public ActionResult Index(string country)
{
    //..
}

Or, change the name of your action method...

public ActionResult CountryIndex(string country)
{
    ViewBag.Message = "my country=" + country;

    return View();
}

Or, you can change the action name from the overloaded method...

public ActionResult Index()
{
    //..
}

[ActionName("IndexByCountryName")]
public ActionResult Index(string country)
{
    //..
}

Working example

This uses the last option, keeping the method name overloaded but specify the ActionNameAttribute for the overload

Actions

    public ActionResult Index()
    {
        ViewBag.Message = "no country selected!";

        return View();
    }

    [ActionName("IndexByCountry")]
    public ActionResult Index(string country)
    {
        ViewBag.Message = string.Format("County selected :: {0}", country);

        // the below ActionResult reuses the Index view but 
        // here you could have a separate view for the country 
        // selection if you like
        //
        return View("Index");
    }

Routes

        routes.MapRoute(
            name: "ByCountry",
            url: "{country}",
            defaults: new { controller = "Home", action = "IndexByCountry" }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
2
votes

You can use AttributeRouting.

[Route("Home/Index/{country}")
public ActionResult Index(string country)
{
    ViewBag.Message = "my country=" + country;

    switch(country)
    {
        case "Country1":
             return View("ViewName")
    }

    // To do
}