Asp.Net MVC Default Route - asp.net-mvc

I have my default route defined like this
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
However if the user is logged in when they visit the site (This can happen if they ticked the remember me button last time the logged in) I want them to take a different default route and go straight to the logged in page.
Is this possible in global.asax or will I need to put some logic in my home controller to redirect if logged in?

Best to put this in the home controller. A check if authenticated and return the appropriate view.

I want them to take a different default routeRouting in ASP.NET MVC is about routing URLs to action methods on controllers, not about routing users to places in your web site depending on the current circumstances. (Think of routing as a static thing, whereas the rest (authorization, redirection, etc) is only applicable to the current session.)
It is possible to use Routing Constraints to achieve what you want, but I don't think that's what you want.

Related

How do I tell what is part of a route is the controller and what is just a sub folder?

When looking at an MVC page and looking at the form action I can see it is set to:
/admin/WikiAdmin/edit/
So I spent my time looking for a controller called admin. I looked in the routes in the global and nothing was there.
Eventually I found that this url actually maps to the WikiAdmin controller which is confusing. Do does this mean you can have controllers in sub-folders? How does the app know not to forward the request to the admin controller and to actually send it to the WikiAdmin controller?
The admin part of the url is called area. You could read more about areas in this article. And a video here. Basically areas allow you to group multiple controllers sharing some common functionality on the site.
Yes, you can have controllers in sub-folders. With routing it could be a lot of possible URLs.
For example, if you have a route registered as below:
routes.MapRoute(
"admin1",
"admin/{controller}/{action}/",
new { controller = "WikiAdmin", action = "Index"}
);
The url can be /admin/WikiAdmin/Index/ or /admin/WikiAdmin/Edit/ or something else that matches the route. (Assume that there is an Edit action in WikiAdmin controller)
More example, if you have a route registered as below:
routes.MapRoute(
"admin2",
"account/{action}/", //no controller specified in url
new { controller = "WikiAdmin", action = "Index"}
);
Then the url can be /account/Index/ or /account/Edit/ or even /account/. (Because default controller is WikiAdmin and default action is Index)

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
);

Twitter like url routing in asp.net mvc?

I ve seen in twitter, i can get a user view page by just typing in the url say http://twitter.com/pandiyachendur. How to do the same with asp.net mvc? I dont know how twitter does it?
You need to be careful about the order in which you declare your routes. Since there is no common element to a /{username} URL, you need to declare it as the last 'catch-all' route, after all of your specific routes.
RouteTable.Routes.MapRoute(null, "LogIn", new { controller = "Account", action = "LogIn" });
RouteTable.Routes.MapRoute(null, "LogOut", new { controller = "Account", action = "LogOut" });
// ... other routes go here ...
// Final catch-all route to map /{username} to the Account.Details action.
RouteTable.Routes.MapRoute(null, "{id}", new { controller = "Account", action = "Details" });
It's also worth remembering that you need to extend your validation on usernames to prevent people from choosing names that conflict with the specific routes (e.g. LogIn).
I imagine that they have some regular exception that checks the request to see if it matches something that could be a user's profile and then push that request to an appropriate controller action.
They'd likely might list first all of the exceptions are static routes, like "/invitations", and then pass everything else to a default controller action that attempts to display a user's page.

asp.net mvc and portal like functionality

fHi,
I need to build an site with some portal like functionality where an param in the request will indentify the portal. like so http:/domain/controller/action/portal
Now my problem is if an portal doesn't exists there must be an redirect to an other site/page and an user can login in to one portal but if the user comes to an other portal the user must be redirected back to the login page for that portal.
I have something working now, but i feel like there must be an central place in the pipeline to handle this. My current solution uses an custom action filter which checks the portal param and sees if the portal exists and checks if the user logged on in that portal (the portal the user logged on for is in the authentication cookie). I make my own IIndentiy and IPrincipal in the application_postauthentication event.
I have 2 problems with my current approach:
1: It's not really enforced, i have to add the attributes to all controllers and/or actions.
2: The isauthenticated on an user isn't really working, i would like that to work. But for that i need to have access to the params of the route when i create my IPrincipal/IIndenty and i can't seem to find an correct place to do that.
Hope someone can give me some pointers,
Richard.
There's a couple different ways you could do this (as always...). If you want to do it in the controller (or via an attribute) but you also want to do it globally, then you could always use a custom base controller class and apply the logic there. The actionfilterattribute is inherited and bob's your uncle.
ON the other hand, this really feels like a routing concern to me. So I'd probably consider creating a custom route to handle what you're doing. If you do that, then once you get it working you'll want to test it out under load to make sure that you have a good caching strategy in place (so that every request isn't a db lookup for the route + another one for whatever happens in the controller).
You can enforce user authorization through an attribute in the controller. You would apply this to each action (both get and post). I think it's reasonable to add some sort of validation to each action within the controller to write secure code, please correct me if I'm wrong here.
For the missing portal redirect, I would handle this in routing. If you have a relatively small number of portals, you can do this by creating a unique route for each of your controllers and then setting a default route for the redirect. Routes are evaluated in the order you create them, so just put the default route at the bottom. Your route registration would look something like this:
routes.MapRoute(
"Portal1",
"{controller}/{action}/FirstPortal",
new {controller = "defaultController", action = "defaultAction",
portal = "FirstPortal"}
);
routes.MapRoute(
"Portal2",
"{controller}/{action}/SecondPortal",
new {controller = "defaultController", action = "defaultAction",
portal = "SecondPortal"}
);
routes.MapRoute(
"Default",
"{controller}/{action}",
new {controller = "defaultController", action = "defaultAction",
portal = "Default"}
);
This way you can use the "portal" route value to select the portal, and any request that does not match will be routed to the controller/action specified in your Default route, which can take care of redirecting the user appropriately.

ASP.NET MVC Routing Questions

I just started using ASP.NET MVC and I have two routing questions.
How do I set up the following routes
in ASP.NET MVC?
domain.com/about-us/
domain.com/contact-us/
domain.com/staff-bios/
I don't want to have a controller specified in the actual url in order to keep the urls shorter. If the urls looked liked this:
domain.com/company/about-us/
domain.com/company/contact-us/
domain.com/company/staff-bios/
it would make more sense to me as I can add a CompanyController and have ActionResults setup for about-us, contact-us, staff-bios and return appropriate views. What am I missing?
What purpose does the name "Default" name have in the default routing rule in Global.asax? Is it used for anything?
Thank you!
I'll answer your second question first - the "Default" is just a name for the route. This can be used if you ever need to refer to a route by name, such as when you want to do URL generation from a route.
Now, for the URLs that you want to set up, you can bypass the controller parameter as long as you're ok with always specifying the same controller as a default. The route might simply look like this:
{action}/{page}
Make sure that it's declared after your other routes, because this will match a lot of URLs that you don't intend to, so you want the other routes to have a crack at it first. Set it up like so:
routes.MapRoute(null, "{action}/{page}",
new { controller = "CompanyController", action = "Company", page = "contact-us" } );
Of course your action method "Company" in your MyDefault controller would need to have a "string page" parameter, but this should do the trick for you. Your Company method would simply check to see if the View existed for whatever the page parameter was, return a 404 if it didn't, or return the View if it did.
Speaking of setting up routes and Phil Haack, I have found his Route Debugger to be invaluable. It's a great tool for when you don't understand why particular routes are being used in place of others or learning how to set up special routing scenarios (such as the one you've mentioned). It's helped clear up many of the intricacies of route creation for me more than any other resource.
To answer your second question about Global.asax, it an optional file used for responding to application level and session-level events raised by ASP.NET or HTTP modules. The Global.asax file resides in the root directory of the ASP.NET application.If you do not define it assumes you have not defined any application handler or session handler. MVC framework uses the routing engine to which the routing rules are defined in the engine, so as to map incoming URL to the correct controller.
From the controller, you can access the ActionName. If there is no specific controller, it will direct to the default page. The default controller is "Home" with its default action "Index". Refer to MSDN:
http://msdn.microsoft.com/en-us/library/2027ewzw%28v=vs.100%29.aspx
Refer to stackoverflow question
What is global.asax used for?
This is a sample of how a default route should look like
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id =
UrlParameter.Optional }
);

Resources