MVC3 Route Using Parameter Name in URL - asp.net-mvc-3

I have these routes:
routes.MapRoute("ListPage", "{controller}/{action}/{pn}/{ps}", new { controller = "home", action = "index", pn = 1, ps = 10 });
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "home", action = "index", id = UrlParameter.Optional });
Which allows me to have URLs like:
/foo/bar/1/10
to control lists of foos on a page (page 1, with 10 items a page). Hooray!
However, the following gives a 404:
/foo/bar/1
Using Url.Action("bar", "foo", new { id = 1}) gives the URL
/foo/bar?id=1
Which then matches correctly to the action signature
public ActionResult Bar(int id) { //stuff }
My thinking is that the first route in the table would not match, as both {pn} and {ps} are required.
So it drops to the second route, which should then match the parameter as {id}.
Obviously my thinking is not correct!
Question is: why is the route not matching without the parameter name?

Just try with interchanging routes postition
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "home", action = "index", id = UrlParameter.Optional });
routes.MapRoute("ListPage", "{controller}/{action}/{pn}/{ps}", new { controller = "home", action = "index", pn = 1, ps = 10 });

Related

Trouble with global.asax routing

I have some links in my webapp that looks like this:
localhost:12345/?something=1
localhost:12345/?something=2
localhost:12345/?something=3
localhost:12345/?something=4
each number at the end is an id that i need to pass to my controller to display information related to it.
I know I need to create a new routes.MapRoute in my global.asax page, but I am not really quite sure how to go about it. I tried this:
routes.MapRoute(
"Id", // Route name
"{controller}/{action}/{*Id}", // URL with parameters
new { controller = "Home", action = "Id", Id = "" } // Parameter defaults
);
---EDIT---
I am only successful getting each individual like to display by doing the following:
routes.MapRoute(
"IdRoute", // Route name
"{Id}", // URL with parameters
new { controller = "Home", action = "Index", id = 1 } // Parameter defaults
);
This does work, however, this only works for one id (specifically 1). I am not quite sure how to go about this, but i need i need:
localhost:12345/?something=1
to display the information for id 1,
localhost:12345/?something=2
to display the information for id 2,
localhost:12345/?something=3
to display the information for id 3.
I there are going to be hundreds of ids so hard coding something in would not be a convenient option. I have had no luck so far. Any help would be much appreciated! Thanks!
routes.MapRouteWithName(
"RootName",
"{id}",
new { controller = "Home", action = "Index", id = 1 });
This will produce links like this localhost/1
If you want this kind of links localhost/?id= 1
Then :
routes.MapRouteWithName(
"RootName",
String.Empty,
new { controller = "Home", action = "Index"});
public ActionResult Index(int id)
{
//do something with id, make query to database whatever
// u usually have model class so you would fill model with your data
var model = new YourModel();
//...
return View("Index", model);
}
If you have following Action in, say, HomeController:
public ActionResult SomeAction(int Id)
{
return View()
}
You may use any of following routes:
//* For Id = 3 this will return path "Home/SomeAction/3"
routes.MapRoute(
name: "First",
url: "{controller}/{action}/{Id}",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);
//* For Id = 3 this will return path "SomeAction/3"
routes.MapRoute(
name: "First",
url: "{action}/{Id}",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);
//* For Id = 3 this will return path "Home/SomeAction(3)"
routes.MapRoute(
name: "First",
url: "{controller}/{action}({Id})",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);
//* For Id = 3 this will return path "LadyGaga/SomeAction/3"
routes.MapRoute(
name: "First",
url: "LadyGaga/{action}/{Id}",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);

ASP.NET MVC basic routing with parameters

I have been trying to learn ASP.NET MVC 3 and things are going well apart from the routing aspect, whatever I try I just can't seem to get them quite right.
I have an ActionLink on the main page:
#Html.ActionLink("Contracts", "List", "Contract",
new { User.Identity.Name, page=1 })
Which is meant to access this method in the ContractController:
public ViewResult List(string user, int page = 1)
{
//snip
}
My routes are:
routes.MapRoute(
null,
"Page{page}",
new { Controller = "Contract", action = "List" }
);
routes.MapRoute(
null,
"Page{page}",
new { Controller = "Contract", action = "List", user = "", page = 1 }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The link now will return a 404 error as it can't find the action 'List' in the controller 'Home', which obviously means it didn't use either of the first routes.
Everything worked before I tried to add parameters to the ActionLink, so basically, what am I doing wrong?
Thanks very much.
Alex,
You're doing all the other bits absolutely correctly, however the actionlink has a missing parameter, try this for your actionlink:
#Html.ActionLink("Contracts", "List", "Contract",
new { User.Identity.Name, page = 1 }, null)
Adding the null as the final param (htmlAttributes) is all that's missing for you in this scenario (there are 9 overloads for Html.ActionLink, so it's VERY easy to miss the correct implementation).

Handling Routes in ASP.NET MVC 3

I am trying to get my routes setup for an Area and I have the following URLs that I need to allow:
http://localhost/Review/Setup
http://localhost/Review/Setup/65
http://localhost/Review/Setup/_AjaxGetMember?ReviewId=53
Area = Review | Controller = Setup | Action = Index
Thus for the URLS, they should go to:
http://localhost/Review/Setup/Index
http://localhost/Review/Setup/Index/65
http://localhost/Review/Setup/_AjaxGetMember?ReviewId=53
Here is the route that is currently registered for the area.
context.MapRoute(
"Review_default",
"Review/{controller}/{action}/{id}",
new
{
action = "Index",
id = UrlParameter.Optional
}
);
Right now, 1 and 3 in my first list work but 2 does not without putting Index into the URL. What else can I add to make these URLs work so that Index does not have to be added or show up in the URL?
Thank you.
I did not test it but that's how I would try it:
context.MapRoute(
"Review_setup_directId",
"Review/Setup/{id}",
new
{
controller = "Setup",
action = "Index",
id = UrlParameter.Optional
}
);
Solved it. I needed to add more routes. There may be a more elegant way to do this but I just tested and it works.
context.MapRoute(
"Review_default",
"Review/{controller}/{id}",
new
{
action = "Index",
id = UrlParameter.Optional
},
new
{
id = #"\d*"
}
);
context.MapRoute(
"Review_default2",
"Review/{controller}/{action}/{id}",
new
{
action = "Index",
id = UrlParameter.Optional
},
new
{
action = #"[A-Za-z]+",
id = #"\d*"
}
);
context.MapRoute(
"Review_default3",
"Review/{controller}/{action}/{id}",
new
{
action = "Index",
id = UrlParameter.Optional
},
new
{
action = #"_[A-Za-z]+",
id = #"\d*"
}
);

MVC Routing problem, 404 and unmatched routes

I'm trying to setup a routing scheme in MVC3 that matches against a legacy (SP 2007) system. These are the routes I've setup:
routes.MapRoute("administration",
"Administration/{action}/{id}",
new { controller = "Administration", action = "Index", id = UrlParameter.Optional });
routes.MapRoute("workOrderSearch",
"WorkOrderSearch",
new {controller = "Home", action = "WorkOrderSearch"});
routes.MapRoute("customers",
"{customerNumber}/{action}",
new {controller = "customer", action = "Index"},
new {customerNumber = #"\d*"});
routes.MapRoute("graphicNames",
"{customerNumber}/{graphicNameId}/{action}/{id}",
new {controller="GraphicName", action="Index", id=UrlParameter.Optional},
new {customerNumber = #"\d*",graphicNameId = #"\d*", action=#"\w*"});
routes.MapRoute("workOrders",
"{customerNumber}/{graphicNameId}/{graphicNumber}/WorkOrder/{action}/{id}",
new { controller = "WorkOrder", action = "Index", id = UrlParameter.Optional },
new { graphicNameId = #"\d*", graphicNumber = #"\d*-\d*" });
routes.MapRoute("graphics",
"{customerNumber}/{graphicNameId}/{graphicNumber}/{action}",
new { controller = "Graphic", action = "Index", id = UrlParameter.Optional },
new { graphicNameId = #"\d*", graphicNumber = #"\d*-\d*" });
routes.MapRoute("Default", "", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
It mostly works just fine. However, when trying to hit the "graphicNames" route, I run into a problem. If I use this url:
http://localhost:1234/1234/321/Index
it works fine and I get to the Index action on the GraphicName controller. However, if I do this:
http://localhost:1234/1234/321
I get a 404.
All other routes appear to work as expected.
Edit: The solution was to add a constraint to the customer's route so that actions were only 'action=#"[A-Za-z]*"
Above you have:
routes.MapRoute("graphicNames",
"{customerNumber}/{graphicNameId}/{action}/{id}",
new {controller="GraphicName", action="Index", id=UrlParameter.Optional},
new {customerNumber = #"\d*",graphicNameId = #"\d*", action=#"\w*"});
however before that you have
routes.MapRoute("customers",
"{customerNumber}/{action}",
new {controller = "customer", action = "Index"},
new {customerNumber = #"\d*"});
which based on your url with only TWO parameters
/1234/321
will match the customers route first. Either add a route constraint that action must be alpha only, or move this beneath your graphicNames route, since order is very important in route matching.

Optional parameters in MVC3 routing

I am trying to create routes which can apply 1 and 2 type of URLs.
1 - First route will be at the start of application and I want 2 type of URLs that can used to access index page. I cannot hit below route when I have URL with Home at the end instead going to type 2.
http://www.example.com Or http://www.example.com/Home
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index", name = "" }
);
2 - This type of URL is passing "Name" parameter to load contents from DB. I want this URL like
http://www.example.com/Page?name=Contact Or
http://www.example.com/Page?name=Contact&id=22
But I want above URL like
http://www.example.com/Contact Or http://www.example.com/About
Or
http://www.example.com/Contact/22 Or http://www.example.com/About/33
Where
Contact and About are values for "Name" parameter passed in URL. Below is the Route used
routes.MapRoute(
"DynamicPages",
"{name}",
new { controller = "Home", action = "Page" }
);
Here is a possible solution. I am not sure if this is the right way to do this.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//To match http://www.mysite.com
routes.MapRoute(
"RootUrl",
"",
new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
//To match http://www.mysite.com/Home
routes.MapRoute(
"RootUrlWithAction",
"Home/{action}",
new { controller = "Home", action = "Index" }
);
//To match http://www.mysite.com/Contact Or
// http://www.mysite.com/About Or
// http://www.mysite.com/Contact/22 Or
// http://www.mysite.com/About/33
routes.MapRoute(
"DynamicPages",
"{name}/{id}",
new { controller = "Home", action = "Page",
id = UrlParameter.Optional }
);
// Everything else
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
}
Tested the following routes. Here the site root url is http://localhost:5879/. Refer the output screenshots provided below for each of the below mentioned scenario.
http://localhost:5879/ --> Uses first route map
http://localhost:5879/Home --> Uses second route map
http://localhost:5879/Contact --> Uses third route map
http://localhost:5879/About/33 --> Uses third route map
http://localhost:5879/Home/Page?name=Contact&id=22 --> Uses third route map
http://localhost:5879/Home/Index/2 --> Uses fourth route map
Screenshot #1:
Screenshot #2:
Screenshot #3:
Screenshot #4:
Screenshot #5:
Screenshot #6:
Hope that gives you some idea to solve your issue.

Resources