mvc route actionlink url use name instead of id - asp.net-mvc

I think I already asked this but the solution didn't really made sense. Anyway, I have ActionLinks on my views like this:
foreach( var item in Model){
<%: Html.ActionLink(item.Name, "Details", new {id = item.Id}) %>
}
now, when it goes to my Action Details obviously this will be the url
/MyThings/Details/{id}
I was wondering if it's possible to show the name of that item instead of the id Using a slug? or modifying the global asax like so:
/MyThings/Details/CarKeys
The thing is the names need to be unique, is there a way I can modify the global asax to show the name instead of the id?
Any advice is much appreciated!

If this is solely for SEO purposes, just include both the ID and the Name. The name will be part of the URL but not used by your application. Just add another route that uses the template: {controller}/{action}/{id}/{name}
You'll also want to transform your name to make sure that it has only valid characters for urls. There are tons of articles about this on the net and it's pretty simple. Here's an example: http://chrismckee.co.uk/creating-url-slugs-permalinks-in-csharp/

Sure, you just have to change your routing rules. Look in your Global.asax.cs file, or in your area registration file, for something like this:
routes.MapRoute(..., "{controller}/{action}/{id}", ...);
... and change it to something like this:
routes.MapRoute(..., "{controller}/{action}/{name}", ...);
Then have your action take the name instead of the ID:
Html.ActionLink(item.Name, "Details", new {item.Name})

Related

Creating an ActionLink and MapRoute that there is a constant name in it

In my Asp.net MVC 5 (C#) project I want to create some links by #Html.ActionLink or every you know is better like:
/Tags/Linq
/Tags/SqlServer
/Tags/MVC
That Tags is constant name and after that in the URL is tag name.For example like ScottGu's Blog
In addition I want to pass a parameter such as Id but I don't want to show in the URL.
How can I do it?
And how should I write a suitable MapRoute for it?
Please help me.
For example (don't forget to write it before default route):
routes.MapRoute(
"Tags",
"tags/{tagTerm}",
new { controller = "Tags", action = "SearchTagResults" }
);
In addition (passing Id) use POST not GET.

Razor Url.Action adding site folder path into Url

I have an MVC project that lives on server in /root/folder1/, and a domain name pointing there.
So the url, www.site.com/Home is working fine.
However, all my #Html.ActionLinks and #Url.Action, etc. are rendering as www.site.com/folder1/Home
The links still work, but it is ugly, and I don't want the folder name to be known.
Anyone know why it's doing this and how to stop it?
You should be using something like this for your ActionLinks
#Html.ActionLink("Link Text", "ActionName", "ControllerName") 'NOTE YOU DO NOT NEED TO INCLUDE THE Controller part of the controller name. So for say AdminController you could simply set the controllerName in the ActionLink to `Admin`
You can also setup your ActionLinks like the below if you have to pass an Id or other value to the controller.
#Html.ActionLink("Link Text", "ActionName", "ControllerName", New With {.YourVariableName = "SomeValue"})
If you need to specify and HTML attribute for the control being rendered you can set those with one more overload.
#Html.ActionLink("Link Text", "ActionName", "ControllerName", New With {.YourVariableName = "SomeValue"}, New With {.htmlAttributeName = ""})
If you need to Specify the HTML attribute without a need to pass a value to the controller you can simply replace New With{.YourVariableName = "SomeValue"}withNothing`
Hope this works or at least points you in the right direction. A fresh MVC project out of the box has a Controllers folder. Which means server path looks something like root/controllerFolder/controller/action using the above works fine for me and only produces Url's that follow the standard {controller}/{action}/{id}. Say I have a need to call an Edit Action inside the AdminController which needs an ID so it knows what record I want to edit and I also want to add a class to this button so I can style it or anything else. I would do this
#Html.ActionLink("Edit", "Edit", "Admin", NEW WITH {.ID = #currItem.Id}, NEW WITH{.Class = "MyButtonClass"})
The URL that is generated will look like this
www.mysite.com/Admin/Edit/2
maybe this is a little more than you needed but your question appears to actually follow the standard {controller}/{action}/{id}. Just in-case I am missing something I figured I would try to at least point you in the right direction.

make url shorter of some controllers and actions

I would like to make some urls of my asp.net MVC4 app shorter. For example I have Account controller and such action ForgotPassword. Url looks like this
http://www.mydomain.com/account/forgotpassword
I would like to make the url shorter(example below) without renaming actual controller and action names. What is the best way to do that?
http://www.mydomain.com/a/fp
You could register a simple route:
routes.MapRoute(
name: "ForgottenPassword",
url: "a/fp",
defaults: new { controller = "Account", action = "ForgottenPassword" }
);
...in RouteConfig.cs if you're using MVC4.
If i am not wrong, then your talking about Friendly URL's?
Please have a look # quysnhat.wordpress.com
There was a very nice post in Hanselman's web.
Also, there were few questions related to friendly url's(in case it helps you) :-
How can I create a friendly URL in ASP.NET MVC?
http://www.intrepidstudios.com/blog/2009/2/10/function-to-generate-a-url-friendly-string.aspx
The easiest but not the best way of doing it is to hand-code your custom routes:
routes.MapRoute(
name: "AccountForgotRoute",
url: "a/fp/{id}",
defaults: new { controller = "Account", action = "ForgotPassword", id = UrlParameter.Optional }
);
The downside to that is if you will have tons of controllers and action methods and you like all of them to be "shortened", then you will have to write a lot of routes.
One alternative is to define your custom routes in a database and write it out on a file. So for example you have in a database row an accountcontroller-forgotpassword key with a value of a/fp, you dynamically build the route definition, write it in a file and let your application pick it up. How your application can pick up the route definition can be done like this. That link is still applicable for MVC 4. But this one is really messy, IMO, but is an alternative.

How can I achieve clean URL routing with custom user ID?

My ASP.NET MVC site allows users to register and give themselves user names, which will be unique and allow others to browse their pages with a clean URL that includes their name, like Twitter, Facebook, LinkedIn etc. do.
For example:
mysite.com/michael.guthrie
mysite.com/john
mysite.com/john/images
mysite.com/john/blog
etc.
The problem is that the first URL segment might be used for other "regular" controllers/actions, like:
mysite.com/about
mysite.com/register
So basically I seek for a routing scheme that says something like: If the first URL segment is a known controller, treat it as a controller (and parse the relevant action and parameters as usual), but if not - treat it as a user name, and pass it to a dedicated controller+action which will parse it and continue accordingly.
I don't want a solution that will enforce me to add routes for every specific controller that I have, such that after the routing module will go over all of them and won't find a match, it will get to the last one which defines a route for this special user name segment. The reason is primarily maintenance (I must remember to add a route every time I code a new controller, for example.)
I assume I can implement my own MvcRouteHandler / IRouteHandler but I feel there must be simpler solution that won't have me tweak MVC's out-of-the-box routing mechanism.
Note: I've read How to achieve nice litle USER page url like facebook or twitter? and it doesn't answer my question, it's just says that there is a URL rewriting module.
Do you know any good, elegant, clean way to achieve that?
You should have your first route be your Usesr route, with a route constraint along the lines of what I described in this answer: MVC routing question.
If your route is in the form {username}/{controller}/{id}, this route should cover all contingencies.
in the global.asax file you can map your routes
in the registerRoutes() method you can do something like this:
routes.MapRoute(
"ToonStudenten", // Route name
"{controller}/{action}/{userID}, // URL with parameters
new { controller = "Docent", action = "ToonStudenten", userID = UrlParameter.Optional} // Parameter defaults
);
I believe you can change the way your views look with this mapRouting, not entirely sure how though.. will try and search it up
You may want to take a look at this post:
MVC 3 keeping short url
You don't need to set a route for each URL. With a little help from route constraints you can do something like this:
routes.MapRoute(
"Home", // Route name
"{action}", // URL with parameters
new { controller = "Home", action = "Index" }, // Parameter defaults
new { action = "TaskA|TaskB|TaskC|etc" } //Route constraints
);
routes.MapRoute(
"Account", // Route name
"{action}", // URL with parameters
new { controller = "Account", action = "Logon" }, // Parameter defaults
new { action = "Logon|Logoff|Profile|FAQs|etc" } //Route constraints
);

Routing with sub domains

I have an MVC website which has 3 main components
Member area which has the path /Member/{controller}/{action}/{id}
Individual pages which will respond to any subdomain, e.g. user1.example.com/{controller}/{action}/{id}, user2.example.com/{controller}/{action}/{id}
Main website which will respond to any url under www.example.com/{controller}/{action}/{id}
What is the easiest way to handle the routes that will allow the above 3 items to co-exist? I have tried many MapRoutes from the global.asax.cs file and also making a new class based on RouteBase but not having much luck.
It sounds like you're heading in the right direction - essentially you need to create a custom route which looks at the request and constructs the route value dictionary. Rather than reinvent the wheel though, someone has already created a nice implementation which allows you to include placeholders in the domain itself like so:
routes.Add("DomainRoute", new DomainRoute(
"{controller}.example.com", "{action}/{id}",
new { controller = "Home", action = "Index", id = "" }));
http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx

Resources