2
votes

I created two action methods with a different name in the home controller

public ActionResult Default()
{
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    return View("index");
}

public ActionResult Index(int a)
{
    ViewData["Message"] = "Welcome to ASP.NET MVC! and Your Age is " + a;
    return View();
}

And my routing code look like:

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

routes.MapRoute(
    "Default2", // Route name
    "{Home}", // URL with parameters
    new { controller = "Home", action = "Default" }
);

routes.MapRoute(
    "Default", // Route name
    "{controller}", // URL with parameters
    new { controller = "Home", action = "Default" }
);

But still getting problem

when I type URL like http://localhost:7221 then home is coming and Default() method invoking but if I type URL like

http://localhost:7221/Home then getting error. to handle this situation i define route like

routes.MapRoute(
    "Default2", // Route name
    "{Home}", // URL with parameters
    new { controller = "Home", action = "Default" }
);

But it is not working.......can u tell me why.

If I type URL like http://localhost:7221/Home/88 then Index(int a) method should be called but getting error. why

I want that when I type URL http://localhost:7221 or http://localhost:7221/Home then Default() should be called and when I will type

http://localhost:7221/Home/88 then Index(int a) should be invoked. What is wrong in my route? How can I rectify it? if possible rectify my route code. thanks

4

4 Answers

4
votes

The reason why you are having problems is that your routeparameters don't match with the action method. Your action method requires int a, yet you are not providing it in any case, you are giving integer called id.

What you should have in routevalues is:

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

Note how age parameter is optional. Our controller should then look like this:

public class HomeController : Controller
{

    public ActionResult Index(int? age)
    {
        if ( age != null )
            ViewData["Message"] = "Welcome to ASP.NET MVC! and Your Age is " + age;
        else
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }
}

Ofcourse we could use parameter called id but I called it age for demonstration purposes.

Update:

Here's something closer to your original request:

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

Controller:

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        return View();
    }
    public ActionResult IndexA(int age)
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC! and Your Age is " + age;
        return View("Index");
    }
5
votes

This rule should actually cover everything you need:

        routes.MapRoute(
            "Default",
            "{controller}/{action}/{a}",
            new {
                controller = "Home",
                action = "Index",
                a = UrlParameter.Optional 
            }
        );

Note the following:

  1. The parameter name needs to match the parameter on the method, you had id and a - so the framework can't match them. In the rule above, I have put a in the mapping rule to match your method, but you should give it a better name in both places.

  2. This rule defaults to /Home/Index if no controller or action are supplied. If you want to hit the action you have named Default you would go to /Home/Default

  3. If you supply /Home/Index/21 it will call the Index method - but if you don't supply an age it will have a problem as you have no method to match the rule. You need to add a method public ActionResult Index() or use a default value public ActionResult Index(int a = 0)

Here are some examples of URLs that should work against this rule.

  • http://yourapp/ - will go to /Home/Index
  • http://yourapp/Home - will go to /Home/Index
  • http://yourapp/Home/Default - will go to /Home/Default
  • http://yourapp/Home/Index - see my notes above - you need a method to support this
  • http://yourapp/Home/Index/21 - will go to /Home/Index and pass a as 21
2
votes

Remove the braces arround Home, change ID to Age and remove the optional behavior of Age.

routes.MapRoute(
    "Default1", // Route name
     "Home/{Age}", // URL with parameters
     new { controller = "Home", action = "Index" }
);

I hope I uderstood what you are trying to acheive properly. If not, I suggest using a Route debugger to understand further.

Try https://github.com/Haacked/RouteMagic (Available on NuGet as RouteMagic.Mvc)

I haven't tried it myself but I do use one component of it.

Good luck!

1
votes

What are the errors that you are getting? I just don't want to assume anything here. I think the //localhost:7221/Home call is failing because it is being matched against the first route (since the id param is optional) and not the second one as you are expecting it to. Also the name of the parameter in the route definition should match the name of the parameter in the action method declaration.

if i type url like //localhost:7221/Home/88 then Index(int a) method should be called but getting error. why

rename the parameter to id or the route optional parameter to a. The routing engine can not find anything to deduce the value of "a" from so it tries to pass a null value in place of a none nullable int parameter hence the error.

i want that when i type url //localhost:7221 or //localhost:7221/Home then Default() should be called

Then move the mapping of the last route to the top of the code block like that it will be added first to the routes collection and localhost:7221/Home will be matched against it first.

You should also look into this tool by Phil Haack:

http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx