nopcommerce 3.5 generic url engine - nopcommerce

I'm looking for the engine root implementation of nopcommerce 3.50 and there is something mysterious for me.
In the Nop.Web project , the "Infrastructure" directory contains GenericUrlRouteProvider class who registers root for generic urls.
This class is a mistery for me because i don't understand how nopcommerce do the difference between urls.
I take one example :
--> if you write this url in your browser : http://localhost:15536/books -->it retdirect to the "book" category dispaying books.
--> if you write this url in your browser : http://localhost:15536/cooking-for-two -->it redirect the product page of the item "cooking-for-two"
this is 2 diifferens contents and pages but this is exactly the same root definition :
routes.MapLocalizedRoute("Product",
"{SeName}",
new { controller = "Product", action = "ProductDetails" },
new[] {"Nop.Web.Controllers"});
routes.MapLocalizedRoute("Category",
"{SeName}",
new { controller = "Catalog", action = "Category" },
new[] { "Nop.Web.Controllers" });
My question is how nopcommerce determine which root to execute (action and controller) when you call http://localhost:15536/books or http://localhost:15536/cooking-for-two... ?

If you have database access you would see there is a table '[dbo].[UrlRecord]'
Do following query
SELECT [Id]
,[EntityId]
,[EntityName]
,[Slug]
,[IsActive]
,[LanguageId]
FROM [dbo].[UrlRecord]
Query result.
Examples:
1) Slug : cooking-for-two , EntityName : Product and EntityId : 22 ,
2) Slug : books, EntityName : Category, EntityId : 1
Based on the EntityName and EntityId system route to corresponding controller action and id
For more details read : http://www.pronopcommerce.com/nopcommerce-id-less-url-structure-demystified-how-does-nopcommerce-270-and-280-resolve-urls

Related

Passing static param to ActionLink in Controller context (ASP.NET MVC)

Is it possible to add some route that always add some param in url?
For example when I write something link this
#Html.ActionLink("Site", "Index", "Admin")
It routes to admin/index?key=some_auth_key. For example I save this param in some static class/variable.
4th parameter of Html.ActionLink can have any number of properties:
Html.ActionLink("Check this", "Edit", "test",
new { id = id, data=name }, new { style = "display:block" })
These properties are inserted into URL based on routing, but if the property name cannot be matched into any route it is added as URL GET parameter.
So if you have standard route {controller}/{action}/{id}, you will get the URL:
test/Edit/[id]?data=[name]

route.GetRouteData(httpContext).Values["action"] is null for Attribute Routing

What I'm trying to do it to get the controller name and action name in an HttpModule.
In the OnBeginRequest of my http module, I have the following code:
foreach (var route in RouteTable.Routes)
{
if (route.GetRouteData(httpContext) != null)
{
Console.WriteLine(string.Format(CultureInfo.InvariantCulture,
"Route info ====== {0}, {1} ======",
route.GetRouteData(httpContext).Values["controller"],
route.GetRouteData(httpContext).Values["action"]));
}
}
If the route is register using conventional routing like this:
routes.MapRoute("BlogDetails", "blog/{blogId}", new { controller = "Blog", action = "Details" });
And when I go to: ~/blog/1 I could see the output
"Route info ====== Blog, Details ======"
But if it's register using:
routes.MapMvcAttributeRoutes();
And in the controller I have:
[RouteArea("blog", AreaPrefix = "blog")]
[Route("{action}")]
On the action I have:[Route("{blogId}", Name="blogDetailRoute")]
And when I go to: ~/blog/1 I only see the output
"Route info ====== Blog, ======"
The action name is missing in that route data.
Anything is different in the attribute routing? Where could I find the action name?
Thanks for helping out!
The routes for attribute routing are stored in a nested IEnumerable<RouteData> named MS_DirectRouteMatches.
var routeData = routes.GetRouteData(httpContext);
if (routeData != null)
{
if (routeData.Values.ContainsKey("MS_DirectRouteMatches"))
{
routeData = ((IEnumerable<RouteData>)routeData.Values["MS_DirectRouteMatches"]).First();
}
}
This example shows how we take the regular route data if it matches the current context, and replace it with attribute routing data if it happens to exist.

Making id'less url in asp.net mvc razor

I am working with URL routing , and have some issues. I want my url to be like this:
www.domain.com/p/myproduct
But I also want to be able to retrieve the ID of the product, without accessing the database. I thought about having a URL like:
www.domain.com/p/myproduct/1
But if I could hide the ID it would be better.
So, how do I do it the simplest way?
Currently my Global.asax has the following route:
routes.MapLocalizedRoute("Product",
"p/{productId}/{SeName}",
new { controller = "Catalog", action = "Product", SeName = UrlParameter.Optional },
new { productId = #"\d+" },
new[] { "Nop.Web.Controllers" });
If all you have is the url then you will have to include the ID there if you want to read it.
The only way to hide it is if you have the ID coming to you from the post of a form say, assuming they have come from a previous page. Then you could store the selected Id and post to url as part of the request.

Default value for parameter in Controller Method is overriding everything

Hello i have just started learning mvc2 and im having a problem with the default value for the parameter page(you can see the method below).
Its always 0 regardless of what i type in the URL. For example this
h.ttp://localhost:52634/Products/List/2
should show page 2 but when in debug mode the page parameter is 0, so im always getting the first page of the list in my view.
i am using the predefined standard routes in global asax when you start a new mvc2 project.
am i missing something?
//This is the ProductsController
public ViewResult List(int page = 0)
{
var products = productsRepo.Products()
//send in source, current page and page size
productList = new PagedList<Product>(products, page, 10);
return View(productList);
}
It's a routing issue, the default route specifies an id property, you're using a property called page. I'm new to MVC myself, but add this route before the default route:
routes.MapRoute("MyRoute", "{controller}/{action}/{page}",
new { controller = "Foo", action = "List", page = UrlParameter.Optional });
Remove the " = 0", and do:
public ViewResult List(int? page)
{
int val = page.GetValueOrDefault(0);
And use val everywhere instead of page. That should work. If not, it's an issue with routing.
HTH.
I know it's very late to answer. As default route for MVC is following
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
which is expecting that parameter name should be id. Now you have 2 options here either change your parameter name to id or the other option is define your own route in route.config file which is under App_Start folder.

How to hide controller name in Url?

How to hide controller name in Url?
I use the ASP.NET MVC.
The original url is: http://www.sample.com/Users.mvc/UserDetail/9615
The "Users" is controller name, the "UserDetail" is action name, and the "9615" is UserId.
How can I hide the controller name and action name in the url.
Just like this: http://www.sample.com/9615
I have writed the following code in the Global.ascx.cs to hide the action name:
routes.MapRoute(
"UserDetail", // Route name
"Users.mvc/{UserId}", // URL with parameters
new { controller = "Users", action = "UserDetail", UserId = "" } // Parameter defaults
);
Using the above code I hid the action name and got this url: http://www.sample.com/Users.mvc/9615
But how can I hide the controller name and get this url: http://www.sample.com/9615
Thanks.
The idea is the same. You do just the thing you did to the action. However, your problem arises from the fact that IIS is probably not mapping www.xyz.com/1234 to ASP.NET runtime. To do so in IIS7, enable integrated mode and in IIS6, add a wildcard mapping in handler map that maps everything to ASP.NET.
To add a wildcard map, see http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx (Search for "IIS6 Extension-less URLs" in that page)
After that, simply add a route:
routes.MapRoute("UserDetails", "{UserID}/{*name}",
new { controller = "Users", action = "UserDetail" , UserID=""});
This should do the trick.
MVC recognizes the difference between "{UserID}" and "{id}" so if you are going to have a route with only "{UserID}" in the Url you need to place it first in the list other wise it never gets hit. And make sure the default includes "id" since it will continually loop over "UserDetails" unless the default references id as apposed to UserID. I found this format works for me:
routes.MapRoute("UserDetails",
"{UserID}",
new { controller = "Users", action = "UserDetail", id = "" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Account", action = "LogOn", id = "" } // Parameter defaults
);

Resources