I am using ASP.Net web form Routing for my website but i want to make it more structure & hide all the Querystring ID's with proper Structure like Language/Category/PageName-Title
example: www.abc.com/en/sports/cricket-world-cup
but with my current routing technique i am able to make it work as
www.abc.com/en/1/13/cricket-world-cup
domain/english-folder/language-id/page-id/page-title
How can i make it more structured as `www.abc.com/en/sports/cricket-world-cup
Since i have few Query-string i designed it this way
//For Page.aspx
routes.MapPageRoute("Page_Route", "en/page/{LID}/{PID}/{PageName}", "~/en/Page.aspx", false,
new RouteValueDictionary {
{ "LID", "0"},
{ "PID", "0" },
{ "PageName", "Page-not-found" }},
new RouteValueDictionary {
{ "LID", "[0-9]{1,8}" },
{ "PID", "[0-9]{1,8}" },
});
Result of above Routing get me Friendly URL like this
www.abc.com/en/1/13/cricket-world-cup
But i want to further structure the URL like the one in example.
www.abc.com/en/sports/cricket-world-cup
Example: This url i found is more structure/
http://www.thenational.ae/news/world/europe/turkey-providing-jobs-a-future-for-more-greeks
How can i implement the same structure are they passing querystrings as hiddenfields. Please suggest best approach for such url.
another example is http://mashreqbank.com/uae/en/corporate/lending/trade-finance.aspx
they are using asp.net but i am not sure if it is ASP.Net MVC or ASP.Net webform.
I have been struggling with this kind of routing for quite long and even i cant find a complete example which can take into consideration more than one query-string as most of the example are based on one query-string.
Any help from coding gurus with example would be highly appreciated.
UPDATE:
Let us take this Table into consideration which i use to store page name, title, handler, language regions etc.. This is just a demo table & doesnt resemble the actual website which i am refering to for sample structured url. I am not even sure if they are going it using URL routing or these are actual physical folder & files like old style website where you create actual folder and place files in their etc..
Page_ID Page_Name Page_Title Page_Handler Parent_Page_ID Language_ID Region_ID
1 Home Home index.aspx 0 1 uae
2 Personal Personal index.aspx 0 1 uae
3 Accounts & Deposits Accounts & Deposits index.aspx 2 1 uae
4 Current Account Current Account current-account.aspx 3 1 uae
5 Current Gold Accounts gold Account gold-account.aspx 3 1 uae
6 Easy Saver Easy Saver Account saver-account.aspx 3 1 uae
7 Fixed Deposits Fixed Account fixed-account.aspx 3 1 uae
8 Loans Loans index.aspx 2 1 uae
9 Personal Loans Personal Loans index.aspx 8 1 uae
10 car Loans car Loans car-loan.aspx 8 1 uae
website example for above structure http://mashreqbank.com/
We can use a common page handler if the page design is same this is what i am assuming let us say page.aspx,
Pleae feel to make changes to structure and data inorder to achieve the desired result.
You could simply have something like:
routes.MapPageRoute(
"article-route",
"en/{category}/{pageName}",
"~/en/page.aspx");
And then on en/page.aspx you can access the category and pageName, assuming you have a query to find the correct article based on those two variables:
string category = Page.RouteData.Values["category"] as string;
string pageName = Page.RouteData.Values["pageName"] as string;
Though, if you can't identify a page simply by category and pageName (which seems true per your updated question), you may need the id in the route. In this case, you can ignore the category and pageName route values as they are only there for a nice-looking URL. The only parameter we care about is the id since that is how you identify an article. For example, here are three examples of various routes
routes.MapPageRoute(
"uae-route",
"uae/en/{category}/{id}/{pageName}",
"~/en/index.aspx");
routes.MapPageRoute(
"gbr-route",
"gbr/en/{category}/{id}/{pageName}",
"~/en/index.aspx");
routes.MapPageRoute(
"account-route",
"en/{id}/{pageName}",
"~/en/current-account.aspx");
//then on en/index.aspx and current-account.aspx
int pageId= 0;
if (Int32.TryParse(Page.RouteData.Values["id"] as string, out pageId)) {
// get the page details (including parent page id and language id if needed)
// where Page_ID=pageId.
}
From the sounds of it though, you want to do the first example above, meaning you'll need a way to pull articles by simply category and pageName and not any type of id.
UPDATE: You don't need to create a route for each path... that's the whole point of routing. If you have multiple handlers, then you'll at least need a path for each handler (.aspx page).
It'd be easiest to use an id in the URL, because according to your data structure, that is the only way to identify the page you want to pull. So let's use your example, using these routes:
www.abc.com/en/personal
www.abc.com/en/personal/acounts-deposits/
www.abc.com/en/personal/acounts-deposits/current-account
www.abc.com/en/personal/acounts-deposits/current-gold-account
www.abc.com/en/personal/acounts-deposits/easy-saver
You have one route:
routes.MapPageRoute(
"personal_route",
"en/personal/{category}/{pageName}",
"~/personal.aspx",
false,
new RouteValueDictionary { { "category", string.Empty }, {"pageName", string.Empty}}); //allow for no values
And the personal.aspx has the following code:
protected void Page_Load(object sender, EventArgs e)
{
string category = Page.RouteData.Values["category"] as string;
string pageName = Page.RouteData.Values["pageName"] as string;
if (String.IsNullOrEmpty(category)) {
//no category... must be the /personal route. handle that
}
else if (String.IsNullOrEmpty(pageName)) {
//no page name, just load the category page content
//Psuedo query against your non-existant data schema
//SELECT * FROM SiteContent WHERE Page_Handler='Personal' AND Page_Category=category && Page_URL=""
}
else {
//SELECT * FROM SiteContent WHERE Page_Handler='Personal' AND Page_Category=category && Page_URL=pageName
}
}
As you can see, your problem is you have no way to identify pages without the IDs. You'd need to replace all those IDs in your table with unique URLs. It's doable.
Related
Based on my SEO team's recommendation i am trying to generate SEO friendly urls. For some static pages i have done that easily using RouteCollection.MapRoute() like -
//Home/Solutions
routes.MapRoute("Solutions", "Solutions", new { controller = "Home", action = "Solutions" }, new[] { "MyAuction.Controllers" });
//Home/SolutionOfferings
routes.MapRoute("Offerings", "Offerings", new { controller = "Home", action = "SolutionOfferings" }, new[] { "MyAuction.Controllers" });
//Home/Pricing
routes.MapRoute("Pricing", "Pricing", new { controller = "Home", action = "Pricing" }, new[] { "MyAuction.Controllers" });
I was then trying to generate SEO friendly routes for my dynamic routes. For example there are several auctions scheduled for a day which contains hundreds of vehicles scheduled within the auction. To show details of that scheduled vehicle within the auction the actual URL is somewhat -
http://example.com/Auction/VehicleDetails?AuctionId=42&VehicleId=101
Please note that VehicleId represents the Identity within AuctionVehicles table which also contains other details of the vehicle like Make, Model, Year and VIN etc.
What i want to achieve is to generate a dynamic URL like -
http://example.com/42/honda-civic-2010-123456
where 42 is the auction id while honda is the make, civic is the model, 2010 is the year and 123456 is the last 6 digits of the VIN number.
Not sure how to achieve this.
I tried using this link -
Dynamic Routes from database for ASP.NET MVC CMS
Any help would be greatly appreciated.
Routing is one of the most difficult things to grasp in mvc. The best way i have found is MVC attribute routings in ASP.NET MVC 5. (P.s. i'm typing on a phone)
you simply include this line in your RouteConfig
routes.MapMvcAttributeRoutes();
And then you can set optional parameters and default values and map urls in your actual controllers like this:
[Route("books/{bookName?}")]
public ActionResult View(string bookName)
{
if (!String.IsNullOrEmpty(bookName)
{
return View("OneBooks"), GetBooks(bookName));
}
return View("AllBooks"), GetBooks());
}
Your url will look like www.example.com/books/jungle-book
there are many more things you can do. Please read the following article:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
I also found this links and the sublinks on this page to be helpfull to get a proper understanding of mvc routing (lots of reading!!):
https://www.codeproject.com/Articles/641783/Customizing-Routes-in-ASP-NET-MVC
As I said I think attribute routing is your best bet!
Now, the question. I have an eCommerce website and I have a controller called Store with an action Index. When someone types www.mysite.com/sony, I want to route to controller Store and action Index with parameter brand=Sony. If someone type www.mysite.com/sony-tv, I want to route to controller Store and action Index but with the parameters brand=sony and department=tv.
I obtained that by creating a route for every situation storing in a database, and building the routes dynamically when the app starts. Its works fine in a few cases.
First, i need to index the routes. I need to map the route sony-tv before the sony, otherwise the /sony-tv maps to /sony equally.
When i enter at site's home (www.mysite.com) and click at Url.Action("Index","Store", new {brand=Sony}) it route me to www.mysite.com/sony. NICE!. Now, inside the SONY brand i'll click at Url.Action("Index","Store", new {brand=sony, department=tv}) and I can see all TV's from Sony.
Everything is running fine until here. In the database, I have 1 route to /sony where I say i have a parameter named brand with value Sony and a constrained named brand with value Sony. I have another route saying the same way to sony-tv. The pattern sony-tv has a parameter named brand with value sony and a parameter named deparment with value tv, and the sames constraints of parameters.
In my head, its means that the route for www.mysite.com/Sony is Store/Index/brand=sony and the www.mysite.com/sony-tv is Store/Index/brand=sony&department=tv. With the constraints, i understand that if department is not TV or if the parameter department does not exists, it will send to www.mysite.com/sony
When i'm at www.mysite.com/sony-tv, if I pass my mouse over the other brands, the link build to Url.Action("Index","Store", new {brand=Apple}) is www.mysite.com/Apple-Tv
I have a route to Apple-TV equal to Sony. The URL exists but i'm not passing the TV parameter. I passed on this link (brands links) only the brand. I want to move the user to brand's root he's moved to brands + department.
I don't know, its looks like the department variable is passing through again and I don't know how to cancel that.
I'm completely wrong? What i'm doing is valid? I can do that? Where is my mistake?
At cshtml file:
#Html.ActionLink(febrand.Name.ToUpper(), "Index", new { controller = "Store", brand= febrand.FriendlyName, department = string.Empty })
at final html file (show source code from google chrome):
SONY
Fisrt, that seems like a lot of work for something that you could do with two custom routes. Additionally, as your route table gets larger (eg. adding more brands and/or departments), each request to your site will take longer to fulfill due to having to scan a larger list of routes.
So, lets attempt to fix your route table. Place these two routes above your default route in the global.asax:
routes.MapRoute(
"Department",
"{brand}-{department}",
new { controller = "Store", action = "Index" };
routes.MapRoute(
"Brand",
"{brand}",
new { controller = "Store", action = "Index" });
As for your issue, when you create your action link, the routing engine is holding onto the department route value from the view you are currently on. To make it forget that parameter when generating a link, send a null across for the department variable when you do not need it.
#Html.ActionLink("Apple", "Index", new{controller="Store", brand="Apple", department = string.empty});
EDIT
I feel you may be in a weird edge case with your routing (and there are numerous examples of this problem all across SO, such as here and here). The solution, other than the one I provided, is to switch to Html.RouteLink instead of Html.ActionLink.
RouteLink Signature that we are going to use
Html.RouteLink(string linkText, string routeName, object RouteValues)
Example Brand link for your code
#Html.RouteLink(febrand.Name.ToUpper(), "Brand", new { controller = "Store", action = "Index", brand= febrand.FriendlyName})
Hello to all developers,
I am trying to find some example of Dynamically generate URL(PURL).
I have seen one software which generate personalised URL from MySQL database .
The only thing is that software is using PHP to generate URL and as a .NET developer I dont know about php.
My question is is there a way that I can fetch data from data base and using perticular field i can generate url which is not actually store in my web space..
eeg.
-----database-----
firstname | lastname ....
===========================
xyz abc
pqwert qweoiuy
alfa beta
the URL should be like
http://something.com/somepersonal/xyz_abc.aspx
http://something.com/somepersonal/pqwert_qweoiuy.aspx
http://something.com/somepersonal/alfa_beta.aspx
It is something like personalised page for users or clients.
I have template to use as back page but dont know how to plug and dynamically generate URL..
You're thinking of this a little backward. Generally, one wouldn't do this by generating it directly from the database. You would generally do this by routing the url batch /somepersonal/ to some personalpage control, which would then consider everything after it, like xyz_abc to be an argument. Personalpage would then use that argument to customize its display, be it from the database or wherever.
So to clarify, your URL would look something like:
http://something.com/personal/vish_soni
http://something.com/personal/colonel_gentleman
http://something.com/personal/general_specific
But all of these are being routed to Personalpage, which then uses vish_soni, colonel_gentleman, and general_specific as arguments to query the database or do whatever else it needs to do.
Microsoft has an overview of this pattern and routing in general here.
You can create a controller class and call an action method. For your case, you just need to send parameter and then lookup customer info to prepare the content.
public class HomeController : Controller
{
public ActionResult Me(string id)
{
ViewBag.Message = "Welcome to ASP.NET MVC! "+id;
var contentobj = repository.GetUSerContent(id);
return View("Index",contentobj);
}
}
I'm working on an MVC 3 site hosted by GoDaddy and I need to store dynamic variables in the URL. Something like:
http://www.example.com/{Cat}/{List}/{Item}/{Action} or
http://{Cat}.example.com/{List}/{Item}/{Action}
The latter would be the best.
The site allows users to create custom lists, list categories, and list items. A list category could be something like Sports or News, a list could be NBA Teams or Politics, and a list item would be Lakers or Pres. Obama. The user is able to generate any one of the 3 (only no duplicates).
My goal is to make the URL be something like http://sports.example.com/nba/lakers and have the user routed to Controller = "Items", Action = "Details", with params Cat = "sports", List = "nba", Item = "lakers" and if the user specifies an Action (like Edit, Delete, etc), it replaces Details.
I'm not super familiar with IIS (more specifically IIS via GoDaddy), so IDK if the subdomaining would work (but that is the ultimate goal) and if it is possible, I'd like to know what I would need to do (i.e. self host + steps).
Thanks
this section is a domain http://sports.example.com/ translating to physical address e.g. 203.10.01.1 you'll have to register a subdomains with GoDaddy. ASP.NET MVC will handle ... nba/lakers section. So your domain will be http://sportworldwide.com/ with subdomains like http://nba.sportworldwide.com/lakers. If want to use MVC 3 only. try something like
sportworldwide.com/sport/nba/lakers.
routes.MapRoute("DefaultSport", "sport/{action}/{id}",
new { controller = "Sport", action = "", id= "" });
EDIT:
I can't comment too much on wildcard DNS records performance or etc. The only problem I see is you'll need to write a custom route handler, then you'll need to get the subdomain part of Url e.g. sport and change the action or id value to handle your subdomain urls.
here is example of modifying the route through a routehandler:
asp.net MvcHandler.ProcessRequest is never called
I have the basic Master / Detail Views working great with the default ASP.NET MVC Route; however I would like to build some URLs like this:
/Class/Details/5 -- General Detail view [Working]
What I'm not sure about (and I'm not tied to this URL format, just something roughly equalivent.)
/Class/5/Details/Logs -- Detail View with Logs
/Class/5/Details/Status -- Detail View with current Status
Another way to put this, is like this:
/{controller}/{id}/{controllerSpecificMaster}/{action}/
What I'm trying to avoid, is cluttering up my Views\Class directory with a bunch of Views, which are all basically derivatives of the Details view.
I'm on ASP.NET MVC 1 and .NET 3.5 SP1.
The first thing you need to get down are your routes. You may have already done this, but in case you haven't, here's a route entry that will handle your custom route needs:
routes.MapRoute("Master_Detail",
"{controller}/{id}/{controllerSpecificMaster}/{action}",
new { controller = "Class",
action = "Index",
id = UrlParameter.Optional,
controllerSpecificMaster = "Details"
});
Then, in your action methods where you want to use the route-specified master page, just include the route key in your method arguments, and then pass it to the view:
public ActionResult Logs(int id, string controllerSpecificMaster)
{
//do something
//return view with master name as argument
return View("Logs", controllerSpecificMaster);
}
If you have to do this a lot, I would suggest creating a custom view engine and override the FindView() method.