localized routes solution - asp.net-mvc-3

I built a french/english app and I would like to use the same controller/view for both language but to have a different route that is map to the current language. Let say I have website.com/Account/Register that return to my Account controller and Register action, I would love to have a route that is website.com/Comptes/Inscription. I know that I can add a custom route in the RegisterRoute section like so :
routes.MapRoute(
"AccountFr", // Route name
"comptes/inscription", // URL with parameters
new { controller = "Account", action = "Register" } // Parameter defaults
);
But it will need a lot of [boring] code to write all the possibles routes and also, I think it won't work when I will use T4MVC as #Url.Action(MVC.Account.Register()) will return /Account/Register no mater if I'm in french or in english.
Anyone as suggestions/ideas for this problem?
Thanks!
EDIT
Since it does not seem to have a good solution using T4MVC does anyone have an other good solution?

Unfortunately, this won't easily work with T4MVC. The root of the problem is that when going through T4MVC, you can't pick a specific route. Instead, the route gets selected based on the Controller, action and parameters.

Related

Codeigniter - custom routes

Lets say I have a controller 'standard' with an action 'main'.
If I go to www.myapp.com/standard/main it will invoke the main action in the standard controller.
Now if I want to change the URL I go into the routes.php and set sth like the following:
$route['welcome'] = "standard/main";
Now I can visit www.myapp.com/welcome and it will invoke the same action.
However it is still possible to visit www.myapp.com/standard/main. I now have two routes which lead to the same controller action.
Is this the usual way or should I somehow disable the now unwanted www.myapp.com/standard/main route? If so, how would I do that?
Thanks in advance.
That is completely for you to decide the default behavior. If you decide to disable the original url, you can write something like
$route['standard/main'] = 'standard/404';
Or any custom location, it depends on your project and how you wish it should look like, for example you can 'block' any method from being accessed directly:
$route['standard/(:any)'] = 'standard/404';
But bear in mind, if you route like you did $route['welcome'] = "standard/main";, then you should always remember that the function $this->uri->segment(n) will show different values, for example if I will go to url yoursite.com/welcome/123, the value of $this->uri->segment(2) will be 123, but if I visit the original URL yoursite.com/standard/main/123, it's value will change to main.
Bear that in mind and decide for yourself!
Assuming that this is a common structure you'll be using, for each action, you can check the segment's in the URL and then redirect appropriately. In the case of going from standard/main to welcome, you would have the following:
class Standard extends CI_Controller {
public function main() {
if($this->uri->segment(1) == 'standard') {
redirect('welcome', 'location', '301');
}
}
}
This would then check the first segment in the URL and if it sees that you've come to this URL, redirect you to the appropriate route. This can then be applied to each action you want to do the same thing for. Supplying a 301 signifies a permanent redirect.
Update
Just found a similar (the same?) question: Only allow URL's specified in routes to be seen in Codeigniter

Dynamically create sitemap and route it to the root level

I am trying to dynamically create a sitemap for my site and I wan't it to be (I believe it is necessary to have it) located at the root level, ie. Domain.com/sitemap.xml
So far I have an action result in the home controller like this:
public ActionResult SiteMap()
{
...
return this.Content(xml, "text/xml");
}
This works fine for creating the file but it is located at Domain.com/Home/Sitemap and my understanding is the the sitemap is supposed to be located at the root level. Is there a way to rewrite the url or add a new route for it in the Global.asax file? By default the Global.asax file contains this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
So it seems like this may be the place to add something like a check if the requested route is Sitemap.xml and just redirect it to Home/sitemap (or just serve the sitemap right there). I'm not sure how to do this, if it is possible, as I have never messed around with the RegisterRoutes section.
Another problem that may arise would be the extension .xml, I would think that IIS would think this is a file on the drive and ignore the route all together.
Am I going down the correct path, or is there a better way to do this? Or is it not possible and I have to just physically create the file?
Edit (Solved)
I just occurred to me that I have been thinking about this the wrong way. All I would have to do is have a method to create/update a sitemap file and save it to /sitemap.xml periodicity or every time a page is added. I can't believe this wasn't obvious to me.
You could add a route:
routes.MapRoute(
"sitemap",
"sitemap.xml",
new { controller = "Home", action = "SiteMap" }
);
and make sure that you put this route before your default route.
This might be slightly off topic, (but in the same breath, kind of close... I think) Have a look at MVCSitemapProvider.
It's simple enough to use in a project, I started using it lately and it works like a charm. I can add some code samples if you do end up wanting to go this route?

MVC Custom Routing and Localization

Okay guys, so I've been stuck for at least 2 days, with googling and checking out all other stack articles I could find.
I just want to check to see if the first parameter in my route is a valid culture name, and if it isn't modify the url/route before execution to include a culture value.
Is that so hard?! I don't think it should be.
I could just modify things in a basecontroller class, from which all other controllers inherit, and check there and then modify all route data and send it on its way. The problem lies with some other custom routes I have.
Okay, so here's the problem with my code, and why I think it would be easiest to do before execution of any controllers.
routes.MapRoute(
"Localization",
"{lang}/{controller}/{action}",
new { lang="en-US",controller="Home",action="Index"}
);
routes.MapRoute(
"Solutions",
"{lang}/Solutions/{controller}/{action}",
new { lang="en-US", controller = "WhatWeDo", action = "Index"}
);
routes.MapRoute(
"Default", // Route name
"{lang}/{controller}/{action}/{id}", // URL with parameters
new { lang = "en-US", controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
So, if I try to modify things, I run into this nasty /solutions/ custom route for certain solutions, and for other answers it requires a custom redirect (Yielding a permanently moved error), and checking to see if certain parameters are null.
Is there any way to extract the route data and modify my route/url in the global.asax file? It would be easiest there, and I really would like to just plop it in so that it's always there, and I can just route normally.
I'm probably not making a whole lot of sense, but I'm a bit frustrated. Any suggestions?
I am not totally sure about what you are trying to achieve, is it to "enforce" language in routes?
You could try writing your own RouteHandler to handle things?
I wrote about something similar on my blog.

how to create Codeigniter route that doesn't override the other controller routes?

I've got a lot controller in my Codeigniter apps, ex: Signup, Profile, Main, etc..
Now I want to build "User" controller.
what I want:
if people goes to url: example.com/signup, I want use default route to "Signup" Controller
if people goes to url: example.com/bobby.ariffin, I want to reroute this to "User" Controller because the url not handled by any Controller in my apps.
I had create this in my config/routes.php:
$route['(:any)'] = "user";
but it's override all the route in my apps to "User" Controller.
Is there any simple route for Codeigniter that doesn't override the other controller routes?
Update---
I've got simple regex for this problem, from: Daniel Errante's Blog
$route['^(?!ezstore|ezsell|login).*'] = “home/$0″;
where ezstore, ezsell, and login are the name of controller in Your Apps.
You can also use a foreach statement for this. That way you can keep your controllers in a nice neat list.
$controller_list = array('auth','dashboard','login','50_other_controllers');
foreach($controller_list as $controller_name)
{
$route[$controller_item] = $controller_name;
}
$route['(:any)'] = "user/display/$1";
You're going to have to explicitly define all of those routes. Otherwise you will always end up at the "user_controller".
$route['signup'] = "signup";
$route['(:any)'] = "user/display/$1";
or something similar. They are ran in order, so what ever is defined first, is going to happen first. So if you catch (:any), you're going to send ANYTHING to that controller.
Also keep in mind that you can use regular expressions, so if you know there is always going to be a '.' in there, you could test for that.

need help with mvc & routes

I'm very new to MVC and I'm trying to get a new site set up using it. For SEO reasons we need to make the url of a page something like "Recruiter/4359/John_Smith" or basically {controller}/{id}/{name}. I have that working when I create the url in the code behind like so...
//r is a recruiter object that is part of the results for the view
r.Summary = searchResult.Summary + "... <a href=\"/Recruiter/" + r.Id + "/" + r.FirstName + "_" + r.LastName + "\">Read More</a>"
But when I am using the collection of results from a search in my view and iterating through them I am trying to create another link to the same page doing something like <%=Html.ActionLink<RecruiterController>(x => x.Detail((int)r.Id), r.RecruiterName)%> but that doesn't work. When I use that code in the view it gives me a url in the form of /Recruiter/Detail/4359 I was told by a coworker that I should use the Html.ActionLink to create the link in both the view and the controller so that if the route changes in the future it will automatically work. Unfortunately he wasn't sure how to do that in this case. So, my problems are...
How can I make the Html.ActionLink work in the view to create a url like I need (like r.Summary above)?
How do I use the Html.ActionLink in a controller instead of hardcoding the link like I have above?
I came across this blog post which got me going in the right direction.
http://www.chadmoran.com/blog/2009/4/23/optimizing-url-generation-in-aspnet-mvc-part-2.html
It is a good idea to use the ActionLink method to write out links as your coworker says, that way they will always match your routes.
In your current case the reason it is writing out the method is because it is based on the default routing. You can fix this by adding another route above the default one in the Global.asax. You just need to stipulate the format you want like this:
routes.MapRoute(
"Recruiter",
"Recruiter/{id}/{name}",
new { controller = "Recruiter", action = "Details" }
);
MVC will work through your routes in the order they are registered so putting this before the default will make it use your route instead.
EDIT:
You might find this route debugging tool useful.

Resources