MVC routing not working when default and custom route refer to same controller - asp.net-mvc-routing

I have two routers in my global.asax, one is a default router which is like:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Test", action = "Action1", id = UrlParameter.Optional }
);
and other is Custom router:
routes.MapRoute(
"CustomRouter", // Route name
"Test/{id}/{FacetString}/{CurrPageNo}",
new { controller = "Test", action = "Action12", id = "", FacetString = UrlParameter.Optional, CurrPageNo=UrlParameter.Optional }
);
some how when I pass url "http://localhost/Test/1001/State=TX" the second router should get executed but some how its not executing.
I had read that the sequence of router is important, hence I tried to exchange there sequence, but it is still not working, if I place it above default router than, the cutom router gets called for all the other actions in that router, which should not happen

the last URL-component State=TX looks like a query string parameter to me. Shouldn't it be ?State=TX (which then wouldn't match your route) or /State/TX

it seems like you should use constraints, reducing match rate for your custom router. You can use forth parameter to define your constraints. In this case it can be something like this
routes.MapRoute(
"CustomRouter", // Route name
"Test/{id}/{FacetString}/{CurrPageNo}",
new { controller = "Test", action = "Action12", id = "", FacetString = UrlParameter.Optional, CurrPageNo=UrlParameter.Optional
, new {id=#"\d+"});
in this way your second URL section requires to be numeric in order to get executed.

According your second route your url should be in one of these formats
http://localhost/Test/1001
http://localhost/Test/1001/State
http://localhost/Test/1001/State/3
Also there is no need of controller = "Test", action = "Action12" as they are not part of the second route definition
Have a look at this MSDN link on ASP.NET routing

Related

Asp.net Mvc 2 How to reroute to www.example.com/my-profile

i would like to reroute this address www.exmaple.com/my-profile to a profile controller i have in my mvc application. There is my global.aspx, as you can the the default routing is
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}/", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
This is the Maproute i'm trying to use to reroute to www.exmaple.com/my-profile
routes.MapRoute(
"Profile", // Route name
"{profile_name}/", // URL with parameters
new { controller = "Portfolio", action = "Index", page = UrlParameter.Optional } // Parameter defaults
);
The problem is when i type www.exmaple.com/profile it trys to direct me to the default maproute, not the one i have specified.
But when i can do this www.example.com/profile/my-profile
routes.MapRouteLowercase(
"Profile", // Route name
"profile/{profile_name}/", // URL with parameters
new { controller = "Portfolio", action = "Index", page = UrlParameter.Optional } // Parameter defaults
);
it works fine, but i dont want to add profile before my-profile. I would like it to work like facebook.com/my-profile or youtube.com/my-profile.
Does anyone one know how i accomplish this, i have been looking for a solution for over 2 months (on and off)
Thanks
Your routing if I remember rightly will return the first matching pattern for the URL. I would expect in your case, your URL is matching your default pattern first.
Move your more specific route above your 'default' route and see if this helps.

ASP MVC RedirectToAction passing an array of objects without using ViewData

I have the following method
public ActionResult Search(FormCollection form)
{
.......
Publication[] publicationsResult = server.SearchLibrary(this.getSession(), sq);
return RedirectToAction("BookListing", new { publications = publicationsResult });
}
Which gets a list of publications from the server and stores it in an array of type Publication.
I would like to show the results in another page, thus I redirected to the following method:
public ActionResult BookListing(Publication[] publications)
{
Publication[] p = publications;
return View(publications);
}
And I also have the following Routes defined:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Library", action = "Search", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"PublicationListing", // Route name
"{controller}/{action}/{publications}", // URL with parameters
new { controller = "Library", action = "BookListing", publications = UrlParameter.Optional } // Parameter defaults
);
When in Search the publications array is populated with over 13000 objects, however when I redirect to BookListing null is passed.
Is there a way to pass an array of objects from one action method to another using RedirectToAction?
Thanks.
You always have the TempData collection. This is persisted between the action redirects for a single request and so provides you with storage for anything like this...

Deploy .net MVC 2 application on IIS6

I want to deploy my .net MVC 2 application on IIS6.0.
Will it require to change route path in global.asax file.
In my application i have used html link, ajax request and Html.ActionLink.
The code lines in the Global.asax file are:
routes.MapRoute(
"LogOn",
"{controller}/{action}/{id}",
new { controller = "Account", action = "Index", id = UrlParameter.Optional }
);
Please suggest me.
MVC2 works just fine in IIS6, though there are some gotchas with the 4.0 framework. Your routes won't be a problem, but you'll have to add a wildcard map for aspnet_isapi.dll to enable extensionless URLs.
Can't see a reason why it won't work. The routes don't need to be setup differently if you intend to deploy to IIS6.
The best way to find out is to try it ;)
I just put in an extension to tell iis to use the asp_net.dll. My urls aren't as pretty, but they work. i.e. they are like http://example.com/Home.aspx/ActionName/Id
routes.MapRoute(
"root", // Route name
"", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}.aspx/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

Trouble Figuring Out The routes.Maproute For This URL (C#)

Despite the plethora of URL routing posts, I have yet to reach enlightenment on the subject.
I have an MVC app that works fine, but I want to get fancy and do some URL rewriting to make it easier on my users.
The default route is a slight variation on the usual:
routes.MapRoute(
"Default",
"{controller}/{action}/{query}",
new{ controller = "SomeController", action="Index", query = "" });
What I want to do is re-route the URL http://mysite.com/12345 to the Details action of SomeController with the 12345 query. I tried this:
routes.MapRoute(
"DirectToDetails",
"{query}",
new{ controller = "SomeController", action="Details" query="" });
routes.MapRoute(
"Default",
"{controller}/{action}/{query}",
new{ controller = "SomeController", action="Index", query = "" });
but that ends up obscuring http://mysite.com/ and it goes to SomeController/Details instead of SomeController/Index.
EDIT:
per the advice of #Jon I removed the query = "" in the anonymous object:
routes.MapRoute(
"DirectToDetails",
"{query}",
new{ controller = "SomeController", action="Details" });
... which addressed the question as far as it went; now when I submit the form at Views/SomeView/Index (that submits to the aforementioned SomeController/Details) I get a "resource cannot be found" error.
Here is the form declaration:
<% using (Html.BeginForm(
"Details",
"SomeController",
FormMethod.Post,
new { id = "SearchForm" })) { %>
<% Html.RenderPartial("SearchForm", Model); %>
<%= Html.ValidationMessageFor(model => model.Query) %>
<% } %>
Remove the query = "" (obviously it's not optional exactly because of the problem you're having - no need to put it in the 3rd argument if there's no sensible default) and use the overload of MapRoute that takes a 4th parameter with route constraints:
routes.MapRoute(
"DirectToDetails",
"{query}",
new { controller = "SomeController", action="Details" },
new { query = #"\d+" });
Obviously you will need to adjust the regex if it's not an integer...
In response to your edit...make sure that you've removed the default for query from the "short" route - you've posted the default one there. Also suggest you double check the form and make sure it's posting a value for query (maybe set a break point on the post action method and make sure the query parameter is being bound correctly?).

Content-Aware Route Mapping in ASP.NET MVC 2

I am working with ASP.NET MVC 2 and would like to optimize my routing. The desired result is as follows:
http://www.url.com/Sites/
http://www.url.com/Sites/Search/NY001
http://www.url.com/Sites/NY001
http://www.url.com/Sites/NY001/Photos
The problem with this scenario is that I want to treat the URL bits differently depending on their content, in a sense. As one can imagine, "NY001" is the identifier for a specific site, not for an action that lives in the Sites controller. My current solution is to define a special route map for the site-specific URLs and to specify each action in the Sites controller separately before that.
// currently in place, works
routes.MapRoute("SiteList", "Sites", new { controller = "Sites", action = "Index" });
routes.MapRoute("SiteSearch", "Sites/Search/{searchString}", new { controller = "Sites", action = "Index", searchString = "" });
routes.MapRoute("SiteNotFound", "Sites/NotFound", new { controller = "Sites", action = "NotFound" });
// and so on...
routes.MapRoute("Site", "Sites/{siteId}/{action}", new { controller = "Sites", action = "Index", siteId = "" });
As this is one of the central components of my web application, these actions are growing daily and the list is getting a bit unwieldy. I would love to be able to distill the long list of action-specific routes to a single declaration, similar to this:
routes.MapRoute("Sites", "Sites/{action}/{id}", new { controller = "Sites", action = "Index", id = UrlParameter.Optional });
The problem is that the routing framework has no way of differentiating between this new route and the site-specific one in the above example; therefore, both are matches. Am I stuck with declaring each action separately? Should I consider using a regular expression to differentiate based on the URLs' content?
Thanks in advance and I apologize in advance if this question has already been asked in a different form.
Not sure what exactly you want to accomplish. Of course you can't really map URLs with different signatures with one route, but you can reduce the list like this:
routes.MapRoute("Site", "Sites/{siteId}/{action}", new { controller = "Sites", action = "Index" }, new { action = "(?:Index|Photos|News)", siteId = #"[A-Z0-9]+" });
for urls:
http://www.url.com/Sites/NY001
http://www.url.com/Sites/NY001/Photos
http://www.url.com/Sites/NY001/News
This route will only map to actions Index, Photos, News (and whatever else you put in that reg. expression).