Conflict with different routes in MVC - asp.net-mvc

I have a website that manages inventory for restaurants. These are the routes I have:
routes.MapRoute(
"Inventory",
"Inventory/{restaurantName}/{restaurantLocationId}/{code}",
new { controller = "Inventory", action = "Index" },
new[] { "MySite.Web.Controllers" }
);
routes.MapRoute( // this route doesn't work
"ListRestaurantInventory",
"Inventory/List/{restaurantLocationId}/{code}",
new { controller = "Inventory", action = "ListRestaurantInventoryItems" },
new[] { "MySite.Web.Controllers" }
);
routes.MapRoute(
"InventoryDetails",
"Inventory/{restaurantName}/{restaurantLocationId}/{code}/Details/{restaurantInventoryItemId}",
new { controller = "Inventory", action = "Details" },
new[] { "MySite.Web.Controllers" }
);
The problem is with the ListRestaurantInventory route, I get a 404 if I try to navigate to /Inventory/List/1/ABC. My other routes work just fine.
I really have no idea what the problem is with my route. Do I need to change the order of my routes, or of the parameters in the URL?

Routes should be listed in order from most specific to least specific.
Your Inventory route is overriding your ListRestaurantInventory because every route that you pass with 4 segments (such as /Inventory/List/1/ABC) beginning with an Inventory segment will match it. This essentially makes your ListRestaurantInventory route an unreachable execution path. Reversing the order of these 2 routes will fix this.
routes.MapRoute(
"ListRestaurantInventory",
"Inventory/List/{restaurantLocationId}/{code}",
new { controller = "Inventory", action = "ListRestaurantInventoryItems" },
new[] { "MySite.Web.Controllers" }
);
routes.MapRoute(
"Inventory",
"Inventory/{restaurantName}/{restaurantLocationId}/{code}",
new { controller = "Inventory", action = "Index" },
new[] { "MySite.Web.Controllers" }
);
routes.MapRoute(
"InventoryDetails",
"Inventory/{restaurantName}/{restaurantLocationId}/{code}/Details/{restaurantInventoryItemId}",
new { controller = "Inventory", action = "Details" },
new[] { "MySite.Web.Controllers" }
);

Related

how to change the default route in nopCommerce

I am using nopCommerce, I want to change my default route from Index to another ActionResult Promotion which is also present in same HomeController, I have done these following tricks, but no solution,
in Nop.Web\Infrastructure\RouteProvider.cs
//home page
routes.MapLocalizedRoute("HomePage",
"",
new { controller = "Home", action = "Index" },
new[] { "Nop.Web.Controllers" });
//for promotion
routes.MapLocalizedRoute("Promotion",
"",
new { controller = "Home", action = "Promotion" },
new[] { "Nop.Web.Controllers" });
in Global.asax
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Promotion", id = UrlParameter.Optional }, // changed to Promotion
new[] { "Nop.Web.Controllers" }
);
I found the solution by just adding value Home as url name in default route, I wounder I changed the Action as Index in Global.asax. This works fine.
//home page
routes.MapLocalizedRoute("HomePage",
"Home", // added value in the default route
new { controller = "Home", action = "Index" },
new[] { "Nop.Web.Controllers" });
//for promotion
routes.MapLocalizedRoute("Promotion",
"",
new { controller = "Home", action = "Promotion" },
new[] { "Nop.Web.Controllers" });

.net mvc route default controller/action but not default parameters

I created this route
routes.MapRoute(
name: "Survey",
url: "{controller}/{action}/{surveyid}/{userid}/{hash}",
defaults: new { controller = "Home", action = "Survey" },
constraints: new { surveyid = #"\d+", userid = #"\d+" }
);
When I then browse to
http://localhost:3086/Home/Survey/1/1/3r2ytg
It works, however if I browse to
http://localhost:3086/1/1/3r2ytg
it does not work.
If I then changed the route like so
routes.MapRoute(
name: "Survey",
url: "{surveyid}/{userid}/{hash}",
defaults: new { controller = "Home", action = "Survey" },
constraints: new { surveyid = #"\d+", userid = #"\d+" }
);
The exact opposite would work (and that makes sense).
But I am curious with the first route i thought both URLs should work since it shoudl grab the default controller and action when none is given.
Update
In the end I went with only this
routes.MapRoute(
name: "Survey",
url: "{surveyId}/{userId}/{hash}",
defaults: new { controller = "Home", action = "Survey" },
constraints: new { surveyId = #"\d+", userId = #"\d+" }
);
as that is the behavior I wanted. However when I then call
#Url.Action("Survey", "Home", new
{
userId = #Model.UserId,
surveyId = survey.Id,
hash = HashHelpers.CreateShortenedUrlSafeHash(#Model.SecretString + survey.Id.ToString() + #Model.UserId.ToString())
})
It generates
/Admin/Home/Survey?userId=25&surveyId=19&hash=2Norc
instead of a shiny path. I can force it with Url.RouteUrl but I thought it should have picked this one automatically.
You need to create route for each combination.
Check this Phil Haack Article
routes.MapRoute(
name: "Survey",
url: "{controller}/{action}/{surveyid}/{userid}/{hash}",
defaults: new { controller = "Home", action = "Survey" },
constraints: new { surveyid = #"\d+", userid = #"\d+" }
);
routes.MapRoute(
name: "Survey",
url: "{surveyid}/{userid}/{hash}",
defaults: new { controller = "Home", action = "Survey" },
constraints: new { surveyid = #"\d+", userid = #"\d+" }
);
Check this Route with Two optional parameters in MVC3 not working
The routehandler doesn't really know that if you say /1/1/3r2ytg the 1 is for surveyId, the other 1 is for userId etc.
It just knows a path (localhost:3086) and x amount of "folders"
So if you call http://localhost:3086/1/1/3r2ytg he will map 1 to controller, 1 to action and 3r2ytg to surveyId.
It can't find userId or hash and since there are no defaults specified he can't find the route.
The defaults in your first route are pointless since they will never trigger.
Default values should be at the end of your url, which kinda makes sense.

Pretty Paged Routing in MVC

I've already seen Paging and routing in ASP.Net MVC but I cannot get that working for me.
On my homepage I want to generate the following pretty urls for my paging:
http://mysite
http://mysite/2
http://mysite/3
Without routing the default urls generated by the pager would be:
http://mysite/?page=1
http://mysite/?page=2
http://mysite/?page=3
My RouteCollection thus far is:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"HomePaging",
"{page}",
new { controller = "Home", action = "Index" },
new { page = #"\d+" },
new[] { "MySite.Controllers" });
routes.MapRoute(
"HomePagingFirst",
"{controller}",
new { controller = "Home", action = "Index", page = 1 },
new[] { "MySite.Controllers" });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "MySite.Controllers" });
}
This is generating the following routes:
http://mysite/1
http://mysite/2
http://mysite/3
Not only is this generating a non-canonical route for the first page but it is also causing all links generated like the following #Html.ActionLink("my site", "Index", "Home") to be appended with the page number of the current page.
Any idea how to do this? If you could, a brief explanation as well as an answer would be most welcome.
I eventually got it working like this. But in all honesty that was through trial and error. If someone could explain why it works I'm sure that would be very helpful to visitors.
routes.MapRouteLowercase(
"HomePaging",
"{controller}",
new { controller = "Home", action = "Index", page = UrlParameter.Optional },
new { page = #"\d+" },
new[] { "MySite.Controllers" });
routes.MapRouteLowercase(
"HomeFirstPage", // Route name
"{page}", // URL with parameters
new { controller = "Home", action = "Index", page = 1 },
new { page = #"\d+" },
new[] { "MySite.Controllers" });

How to set different Default Page in NOPCommerce2.65

I want to set different default page in nop2.65, i have register new Route
//In RouteProvider
//Custome page
routes.MapLocalizedRoute("CustomHome",
"",
new { controller = "Customer", action = "Login" },
new[] { "Nop.Web.Controllers" });
//home page
routes.MapLocalizedRoute("HomePage",
"",
new { controller = "Home", action = "Index" },
new[] { "Nop.Web.Controllers" });
it's work fine set Login Page as Default but when i click on "Home" menu it redirect login page
instead of home page.
i have also tried to set default page in Global.asax file that also not work
//In Global.asax file
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Customer", action = "Login", id = UrlParameter.Optional },
new[] { "Nop.Web.Controllers" }
);
Finally I got the solution in NOP2.65 all route register under NOP.Web->Infrastructure->RouteProvider.cs. if you want to set different route then your RouteProvider.cs like
/In RouteProvider
//Custome page
routes.MapLocalizedRoute("CustomHome",
"", // Route name
new { controller = "Customer", action = "Login" },
new[] { "Nop.Web.Controllers" });
//home page
routes.MapLocalizedRoute("HomePage",
"home/", // Route name
new { controller = "Home", action = "Index" },
new[] { "Nop.Web.Controllers" });
NOTE: Set RouteName as blank for newly register route and modified HomePage RouteName.

ASPNET MVC Routing issue

I need to add a http://mysite/categoryname route, so i added
routes.MapRoute(
"Categories",
"{CategoryName}",
new { controller = "News", action = "Category", CategoryName = "" },
new string[] { "MyProj.Controllers" }
);
The problem is that if i add it before
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "News", action = "Index", id = UrlParameter.Optional },
new string[] { "MyProj.Controllers" }
);
Home page goes in error because it enters in Categories route; if i add Categories route in last position it is never entered and http://mysite/category_name gives me 404.
What am i doing wrong?
You have a few options here:
Change your news category route to include a hard path:
routes.MapRoute(
"Categories",
"category/{CategoryName}",
new { controller = "News", action = "Category", CategoryName = "" },
new string[] { "MyProj.Controllers" }
);
Change your default route to include a hard path:
routes.MapRoute(
"Default", // Route name
"site/{controller}/{action}/{id}", // URL with parameters
new { controller = "News", action = "Index", id = UrlParameter.Optional },
new string[] { "MyProj.Controllers" }
);
Roll your own custom routing class
See http://hanssens.org/post/ASPNET-MVC-Subdomain-Routing.aspx for an unrelated example.
No matter how you do this, as you add Categories, you will obviously run the risk of stepping on other pages in the site - so for example if you have a section of your site named /account and then someone creates a category named, "account," what's supposed to happen?
That said, there is a simpler answer than writing your own Routing class. You can use a Regex in the Category Route, and make it the first rule. For example, if the only 2 categories on the site were jackets and sweaters:
routes.MapRoute(
"Categories",
"{CategoryName}",
new { controller = "News", action = "Category" },
new { CategoryName = "(jackets|sweaters)" }
);
The final argument is a RouteConstraint based in Regex, and so the route will defer to routes included after it if the path is neither /jackets or /sweaters.
Obviously you want to be more robust than that, so you can create a method that builds the Regex at app startup:
routes.MapRoute(
"Categories",
"{CategoryName}",
new { controller = "News", action = "Category" },
new { CategoryName = "(" + String.Join("|", categories) + ")" }
);
categories here would need to be something you provide - some array or database feed of the category names in your app.

Resources