How do I get this ASP.NET routing to work properly? - asp.net

I'm trying to write a really simple prototype of a CMS system using ASP.Net MVC 3.
The system has a single controller with two actions: show and create.
The format for the 'Show' action is meant to take up to 5 optional parts, e.g. domain.com/part1/part2/part3/part4/part5
The format for the 'Show' action is similar, but should have a leading 'create' part e.g. domain.com/create/part1/part2/part3/part4/part5
I have the following settings in my global.asax:
routes.MapRoute(
"CreatePageRoute",
"create/{part1}/{part2}/{part3}/{part4}/{part5}",
new
{
controller = "Page",
action = "Create",
part1 = UrlParameter.Optional,
part2 = UrlParameter.Optional,
part3 = UrlParameter.Optional,
part4 = UrlParameter.Optional,
part5 = UrlParameter.Optional
});
routes.MapRoute(
"Default",
"{part1}/{part2}/{part3}/{part4}/{part5}",
new
{
controller = "Page",
action = "Show",
part1 = UrlParameter.Optional,
part2 = UrlParameter.Optional,
part3 = UrlParameter.Optional,
part4 = UrlParameter.Optional,
part5 = UrlParameter.Optional
}
);
If my 'Show' method fails to find a page matching the supplied path, it returns a 'not found' page that includes an options to create a new page with the supplied path. This link is defined using the following:
#Html.ActionLink("Yes", "Create")
[the "Yes" represents the answer to the question "do you want to create a page for this path?"]
So when testing the 'Default' route, I see that my 'Show' action is called successfully for all of the following paths:
{empty}
a
a/b
a/b/c
a/b/c/d
a/b/c/d/e
which is great.
However, the resulting 'create' link generated by the statement "#Html.ActionLink("Yes", "Create")" gives inconsistent results. It seems to generate a different hyperlink depending on the length of the input. The results are as follow:
For path "{empty}", the link offers "localhost{:port}/" - I was hoping for "localhost{:port}/create"
For path "/a", the link offers "localhost{:port}/" - I was hoping for "localhost{:port}/create/a"
For path "/a/b", the link offers "localhost{:port}/a" - I was hoping for "localhost{:port}/create/a/b"
For path "/a/b/c", the link offers "localhost{:port}/a/b" - I was hoping for "localhost{:port}/create/a/b/c"
For path "/a/b/c/d", the link offers "localhost{:port}/create/a/b/c/d" - which is what I was hoping for
For path "/a/b/c/d/e", the link offers "localhost{:port}/create/a/b/c/d/e" - which is what I was hoping for
Why does it only work when I supply "/a/b/c/d" or "/a/b/c/d/e"?
I know I'm being idiotic, please help me
Sandy

I believe that multiple optional parameters are causing the discrepency.
How about:
routes.MapRoute("Create5", "create/{part1}/{part2}/{part3}/{part4}/{part5}", new { controller = "Page", action = "Create", part5 = UrlParameter.Optional });
routes.MapRoute("Create3", "create/{part1}/{part2}/{part3}", new { controller = "Page", action = "Create", part3 = UrlParameter.Optional });
routes.MapRoute("Create1", "create/{part1}", new { controller = "Page", action = "Create", part1 = UrlParameter.Optional });
routes.MapRoute("Default5", "{part1}/{part2}/{part3}/{part4}/{part5}", new { controller = "Page", action = "Show", part5 = UrlParameter.Optional });
routes.MapRoute("Default3", "{part1}/{part2}/{part3}", new { controller = "Page", action = "Show", part3 = UrlParameter.Optional });
routes.MapRoute("Default1", "{part1}", new { controller = "Page", action = "Show", part1 = UrlParameter.Optional });

Related

mvc3 map routes

I am looking to use the following urls and maps some routes accordingly
<domain>/Home/About
<domain>/Home/SiteList
<domain>/Site/<id>/ (this one is defaulted to the details view)
<domain>/Site/<id>/section1/ (this one goes to section1 route in the Site controller)
<domain>/Site/<id>/section2/ (this one goes to section2 route in the Site controller)
e.g.
<domain>/Site/london/siteinfo
The above are covered by
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
However, i also want to use the following routes
<domain>/Site/<siteid>/section1/controller/action (where controller gets data linked to the <siteid> and action is optional)
an example link would be:
<domain>/Site/london/siteinfo/manager (manager is a controller and will list managers for the site)
if have tried various routes and read various posts but could not find anything which was applicable to me.
Can anyone provide some help please?
Thanks
Rudy
Add one more route below "Default":
routes.MapRoute(
"MyRouteName", // Route name
"{controller}/{action}/{id}/{section}/{subsection}", // URL with parameters
new { controller = "Home", action = "Index", id= "", section= "", subsection = "" } // Parameter defaults
);

ASP.NET Multiple route and invalid dataroute values

I have multiple routes which refer to different controllers and a few of routes have identical number of parameter. please look at my sample below
routes.MapRoute("AdInfo", "{controller}/{action}/{AdGUID}/{UserID}/{Category}",
new
{
controller = "Home",
action = "DetailAd",
AdGUID = UrlParameter.Optional,
UserID = UrlParameter.Optional,
Category = UrlParameter.Optional
});
routes.MapRoute("PostAd", "{controller}/{action}/{MainCategory}/{SubCategory}/{SubCategoryGUID}",
new
{
controller = "Classified",
action = "Post",
MainCategory = UrlParameter.Optional,
SubCategory = UrlParameter.Optional,
SubCategoryGUID = UrlParameter.Optional
});
Routes AdInfo and PostAd have three parameters but both of them refer to different controller and action. asp.net mvc interpret wrongly, when i click URL which are suppose to link to Controller Classified - action post with route data values MainCategory, subcategory, and subcategoryGUID. somehow, the route data values are AdGUID,UserID,and category.
Do you have any idea how to solve this issue?
You're almost there, basically you're creating a catch all route and specifying the default, except you have two catchall routes setup. It should be like this at the very least:
routes.MapRoute("AdInfo", "Home/{action}/{AdGUID}/{UserID}/{Category}",
new
{
controller = "Home",
action = "DetailAd",
AdGUID = UrlParameter.Optional,
UserID = UrlParameter.Optional,
Category = UrlParameter.Optional
});
routes.MapRoute("PostAd", "Classified/{action}/{MainCategory}/{SubCategory}/{SubCategoryGUID}",
new
{
controller = "Classified",
action = "Post",
MainCategory = UrlParameter.Optional,
SubCategory = UrlParameter.Optional,
SubCategoryGUID = UrlParameter.Optional
});
Of course in some situations this won't work. The only way I can see being able to use this route for multiple controllers too is by adding a suffix after the controller like this:
routes.MapRoute("AdInfo", "{Controller}/{action}/SomeNameThatSeperatesThisRouteFromTheNext/{AdGUID}/{UserID}/{Category}",
Or if on the second route the action will always be the same, then just hard code it into the route and now you will have two distinct routes (Make sure the route you hard code is declared before the other route).

ASP.NET MVC How can better filter my route?

I have added a new route to my routing table:
routes.MapRoute(
"ModuleRoute", // Route name
"Module/{href}", // URL with parameters
new { controller = "Module", action = "GetHtml" }// Parameter defaults
);
I need this route to match on the following url structure:
/module/123abc.html
The problem is it also matches on this structure
/module/Launch/123abc.html
Calling link :
<%: Html.ActionLink("Launch", "Launch", new { href = item.Href })%>
How do I stop that from happening? I want he second structure to continue to be matched by the default route. I thought that because the number of parameters are different that this would not be a problem.
How can better filter my route to prevent this?
Thanks!
i agree with Max Toro, i've done some testing and that URL doesn't match Module/{href}.
This:
<%: Html.ActionLink("Launch", "Launch", new { href = item.Href })%>
is actually hitting the default route. You see this if you change the default route to the below (note the id is changed to href
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{href}", // URL with parameters
new { controller = "Home", action = "Index", href = UrlParameter.Optional } // Parameter defaults
);
so, this proves it is falling through the first route since it gets a proper url (no querystrings)
what it is doing (when you have the usual default route with id) is that the controller and action are matched but the id isn't. This is OK - the route still matches but leaves off the id. All additional values, such as your href are appended as querystring parameters so you end up with:
module/Launch?href=123abc.html
The way to get around it is to add another route similar to the one above that uses href instead of id
something like:
routes.MapRoute(
"Launch",
"Module/Launch/{href}",
new { controller = "Module", action = "Launch", href = UrlParameter.Optional }
);

asp.net mvc outbound routing from a GET form post

I have a route that looks like this:
new { controller = "ControllerName", action = "PhotoGallery", slug = "photo-gallery", filtertype = UrlParameter.Optional, filtervalue = UrlParameter.Optional, sku = UrlParameter.Optional}
and I have a form that looks like this:
<%using(Html.BeginForm("PhotoGallery", "ControllerName", FormMethod.Get)) {%>
<%:Html.Hidden("filtertype", "1")%>
<%:Html.DropDownList("filtervalue", ViewData["Designers"] as SelectList, "Photos by designer", new { onchange = "selectJump(this)" })%>
<%}%>
Right now when the form is submitted I get the form values appended to the url as query strings (?filtertype=1 etc) Is there a way to get this form to use routing to render the URL?
So the form would post a URL that looked like this:
www.site.com/photo-gallery/1/selectedvalue
and not like"
www.site.com/photo-gallery?filtertype=1&filtervalue=selectedvalue
Thanks!
If you only have some of the parameters present, Mvc will create a Query String type Url unless it finds an exact matching url.
Suggest you will need something like:
routes.Add("testRoute",
new Route("/{action}/{controller}/{slug}/{filtertype}/{filtervalue}",
new { controller = "ControllerName", action = "PhotoGallery", slug = "photo-gallery", filtertype = UrlParameter.Optional, filtervalue = UrlParameter.Optional}
);
make sure this is before your existing route

ASP.NET MVC : Ignore latter route elements in url for a form's action

I have a URL /products/search where Products is the controller and Search is the action. This url contains a search form whose action attribute is (and should always be) /products/search eg;
<%using( Html.BeginForm( "search", "products", FormMethod.Post))
This works ok until I introduce paging in the search results. For example if I search for "t" I get a paged list. So on page 2 my url looks like this :
/products/search/t/2
It shows page 2 of the result set for the search "t". The problem is that the form action is now also /products/search/t/2. I want the form to always post to /products/search.
My routes are :
routes.MapRoute( "Products search",
"products/search/{query}/{page}",
new { controller = "Products", action = "Search", query = "", page = 1 });
routes.MapRoute( "Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" });
How can I force Html.BeginForm(), or more specifically Url.Action( "Search", "Products"), to ignore the /query/page in the url?
Thanks
Fixed by adding another route where query and page are not in the url which is kind of counter intuitive because the more specific route is lower down the order
routes.MapRoute(
"",
"products/search",
new { controller = "Products", action = "Search", query = "", page = 1 });
routes.MapRoute(
"",
"products/search/{query}/{page}",
new { controller = "Products", action = "Search"} //, query = "", page = 1 });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" });
The order is really important, the first route it hits that matches it uses. Therefore catch all type routes should be at the very end. Here is a helpful route debugger youc an use to figure out what the problem is.
Route Debugger

Resources