Loading routes according to HTTP_HOST in MVC4 - c#

I have a multi-tenant MVC4 website in which I want to set up the the RouteTable according incoming host and domain name eg www.domain1.com, www.domain2.com and www.domain3.co.uk could have one or more additional values appended to the route table according to the host and domain anem.
The DNS server has been set up with a number of distinct zones with hosts, and I'm using IIS7 as a 'custom web server' rather than using Visual Studio 2012 Development Server so that I get the correct HTTP_HOST value available to me in the Request variable.
The problem I have with IIS7 is that to the value of HttpContext.Current.Request.ServerVariables["HTTP_HOST"] is not available if you try to call it in the RegisterRoutes method where all the other route mapping is done.
The main thing I need to do is determine at some point in the request pipeline the the value that will eventually end up in the HTTP_HOST server variable . That value needs storing and the route table appropriately updated before it gets used.
Will it need an Http Module, Http Handler, Action Filter or somesuch? Or is there some other place in the MVC pipeline that I can do this.
Crispin

There's no built in support for routing based on host that I'm aware of, but you can create a Route subclass that pulls the host value in. Here's an example:
http://blog.maartenballiauw.be/post/2009/05/20/aspnet-mvc-domain-routing.aspx
That's written for MVC3, but should work fine in MVC4.

Related

ASP .Net MVC 5 redirect issue

Currently I have an internal server serv that has an application app.
It is running MVC 5 and has 2 pages Account/Logon which maps to controller and an action.
And Orders/Display (again controller/action)
In order for internet users in the outside world to see I have a host server host running IIS. It maps host URLs to the internal app like so
host/Account/Logon -->serv/app/Account/Logon
So basically anything after host/... gets changed to serv/app/....
My problem is if I do RedirectToAction("Display","Orders");
(there are lots of these redirects because there's lots of controller/action combos.
The internal server grabs the host portion but also tacks on "app" in order
to switch to the next page or route
So,host/app/Orders/Display
My problem is that the host IIS maps this URL to host/app/app/Orders/Display
because that what it's mapping is set to do. always add "app"
How can I solve this issue? Is there any way for serv do
a relative mapping? In order words it only sees the original host/Account/Logon
so on switch it would be host/Orders/Display?
Use Redirect() instead of RedirectToAction() and pass in the url.

How to allow some controllers to be visited not others in ASP.NET MVC 4

I will deploy my project in IIS and WS 2008.
I want to know how can I allow some controllers to be visited just inside my network and block people outside to see it.
Use the Request.Url property to check if the request is coming from another domain. Based on the url you can hide this.
Based on this
Either you check the url in controller action method or
Write Custom Authorization attribute

Request to a IIS server (when ASP NET WebForms + MVC co-exist)

Well, there are many questions on SO which proves that you have the possibility to hold both ASP WebForms as well as ASP NET MVC Applications running together.
Note:
In MVC, What happens ? The short answer is Every requests to the webserver first goes through aURLRoutingModule object which reads the request and performs route-selection (depending upon global.asax file). The MvcRouteHandler then handles the controller method invocation.
That is okay.
All I am trying to understand is what happens when a user sends a request to the browser when the web server contains both Web-Forms as well as an ASP.NET MVC Application.
Who reads the URL and understands whether it is an .aspx extension or it is a request to mvc ?
How exactly the ISAPI.dll function in this case?
It's actually fairly simple: the URLRoutingModule checks the disk to see if there is a physical file which matches the current request URL. If there is a match, the Routing module assumes that it shouldn't run for this request, and ASP.NET's default behavior is then to look up and invoke the default handler for this extension. In the case of .aspx, that would be the Web Forms handler.
You can change this via the RouteCollection.RouteExistingFiles property in your RegisterRoutes method. This property controls whether the Routing module should intercept the request regardless of whether there is a physical file on the hard drive.
To understand better what happens when a user sends a request to the browser when the web server contains both Web-Forms as well as an ASP.NET MVC Application is by knowing on how ASP.Net runtime perform the Url routing which it is actually done by the ISAPI filter plugin.
Below are the detailed steps for Webform request:
1) When user enter a url like website1.com/page1.aspx in the browser.
2) Browser will send a Get Request to the IIS server asking for Page1.aspx file.
3) Then ISAPI filter is the first process to access the Http data before IIS can start to do anything. Here it act like a router for IIS request.
4) ISAPI filter will then check the url whether the filename has any extension (.aspx) and check whether the (.aspx) extension is mapped to the aspnet_isapi.dll or not.
5) If ".aspx" is mapped, it will invoke the ASP.net UrlRoutingModule and mapped the HttpHandler for ASP.net files.
For MVC request:
1) It follow the same step like webform request until the ISAPI filter found that there is no filename and file extension exist in the Url since MVC Url only contain the controller and action name.
2) All Url need to be mapped to a handler when the request initially received because routing will not work with unmanaged handler request
3) To direct this unmanaged request to managed code, it can be done by setting wildcard mapping to aspnet_isapi.dll for IIS6. For IIS7, we can just set the runAllManagedModulesForAllRequest="True".
4) Then only ASP.Net UrlRoutingModule will be invoked and try to match the Url with the application defined route.
5) If there is a match, it will direct to HttpHandler of Asp.net MVC framework. But if there is no match, the default Asp.net webform mapping will be used and most likely the request will return a HTTP 404 error result.
For more details you may refer to this web:
Mixing Web Forms and ASP.NET MVC
Web Server and ASP.NET Application Life Cycle in Depth

Registering routes on session start not application start

I am trying to register the route collection in .net based on each session. The code I have works fine, you goto website/username and it loads the correct sub pages, but you have to restart the application to goto website/username2 to load those sub pages. But when the application is restarted the second one works, but then not the first one.
Is there some way to create a different route collection per session not per application using system.web.routing.
Routes are linked to route names and are stored globally for the web application, so you can't really define routes per session.
Can you give an example of why you need different routes for different users?
Most likely it can be solved by simply using route patterns, like setting RouteUrl to somehting like : "member/logo/{size}/{UserName}.jpg", where you can specify UserName and size when generating the route url via Page.GetRouteUrl()
You can create your own route handler. Take a look at : ASP.Net MVC Framework - Create your own IRouteHandler.
Using such approach, you will be able to route differently per request. Each request can then take a look at your session values to get the correct handler.
RouteTable.Routes is static so the same routes are shared across all Sessions. So you can't have a different set of routes for each session.

Running ASP.NET MVC application behind a proxy with different root relative path

I'm having trouble with paths in a ASP.NET MVC application that's running behind a proxy.
Our IIS Application root path is for example http://server/MyApp/
meaning that all urls using the application root ("~/",Url.Action("MyAction","MyController")) are resolved to "/MyApp"
Now we're running behind a proxy server that forwards all requests, but requires you to access the application through a URL like this:
"/Secury/Proxy/RubbishUrl/MyApp"
Because the proxy url is only available on the client, I thought of creating a cookie with the path prefix, and insert this before each generated URL on the server.
Now the question is, what's the best location in code to modify each URL that's resolved/sent to the client (to resources, controller actions, images etc)?
Every path in the application is resolved with the MVC methods (Url.Content, Url.Action etc).
Update:
Not actively looking for an answer anymore (though still interested in a proper solution)
Most of the time Proxies do their own URL translation, however in this case the proxy server is ignoring paths that are transfered in JSON, and they are processed.
My 'solution' for now is just not passing paths in JSON, but instead:
using proper ID's and values in the JSON requests
creating template in URL's in the HTML (which are resolved properly),
replace the ID's and values in the URL template with the values from the JSON requests
This method is actually a much 'cleaner' way IMO then passing the URL's.
You can create your own asp.net mvc controller factory where to decide which controller and action will serve the response based on the requested url. Check this url for a good blog post on how to do this - http://nayyeri.net/custom-controller-factory-in-asp-net-mvc.

Categories

Resources