ASP.NET MVC. Data driven subdomains? - c#

We are creating a multi-tennant web application where we identify tenants via a subdomain (customer1.ourapp.com, customer2.ourapp.com, etc).
Setup of subdomains has to be data driven - i.e. we don't want to have to modify IIS config (manually or programmatically) every time we get a new customer.
In MVC where is the best place to check that a subdomain in a request is valid (i.e. the subdomain exists in some table in the database)
Some options I've considered,
OnActionExecuting in the controller
In a custom action filter
IIS module
As part of the routing setup - a custom route class that knows about the valid sub-domains - similar to this approach - http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx
I think that conceptually this is a routing task so the last option seems right ?? i.e. a request with a subdomain that doesn't exist is essentially an invalid url so it shouldn't match against a route and should instead fall through to a 404. This would also allow us to explicitly define routes that do or don't require a valid subdomain.

I would create a custom action filter and registered it globally in Global.asax (no worries when adding new controllers).
You can also consider creating a custom MvcHandler and specify it when declaring routes. This will allow you to specify a few routes (ie. for static content), which can be shared between all clients.
Other solution is to use only routing and stick to the single domain, so you don't have to shell out for the expensive SSL certificate for wildcard domain.

I was doing it like this in my Base Controller Class before, however, like #Jakub said, using subdomain will be expensive if you or your client need SSL certificate thereafter.
var dotIndex = HostingEnvironment.SiteName.IndexOf('.');
if (dotIndex > 0)
{
var subdomain = HostingEnvironment.SiteName.Substring(0, dotIndex);
customerCode = subdomain;
}

Related

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

Loading routes according to HTTP_HOST in MVC4

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.

How to rewrite urls such as example.com/1Bta62 to example.com/view.aspx?id=1Bta62 whilst the user still sees example.com/1Bta62?

As part of an url shortening service, I need users to be able to go to an url such as example.com/1Bta62 and end up at example.com/view.aspx?id=1Bta62 whilst the example.com/1Bta62 is maintained in their browser address bar. How can this be done?
I am using a windows server (project is C# ASP.NET); I would prefer to not have to use scripts (i.e. just something in web.config would be great) but welcome answers of any method. The url endings such as the one above 1Bta62 are dynamically generated.
Thanks in advance!
Edit: Has anyone actually managed/knows how to do this with the web.config file - I think it can be done?
I would recommend Url Rewrite Module, which has been designed to do just that. It's an IIS module that requires no changes to be done to the app.
IIS URL Rewrite 2.0 enables Web administrators to create powerful
rules to implement URLs that are easier for users to remember and
easier for search engines to find. By using rule templates, rewrite
maps, .NET providers, and other functionality integrated into IIS
Manager, Web administrators can easily set up rules to define URL
rewriting behavior based on HTTP headers, HTTP response or request
headers, IIS server variables, and even complex programmatic rules. In
addition, Web administrators can perform redirects, send custom
responses, or stop HTTP requests
Update:
Take a look at RouteMagic:
http://haacked.com/archive/2011/01/30/introducing-routemagic.aspx
Please try registering the routes in area registration. For e.g.,
context.MapRoute(
"Myproject_default",
"Myproject/{controller}/{action}/{id}",
new { controller = "Myproject", action = "index", id = UrlParameter.Optional }
);

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.

MVC C# custom MvcRouteHandler - How to?

Does anyone have experiences in providing a custom MvcRouteHandler? In my application I'd like to implement a globalization-pattern like http://mydomain/en/about or http://mydomain/de/about.
As for persistance, I'd like to have a cookie read as soon as a request arrives and if there is a language setting in this cookie apply it (so a user arriving at http://mydomain/ would be transferred to http://mydomain/en/ for example). If there is no cookie present, I'd like to get the first language the browser supports, apply this one and store it in this cookie.
I guess this can't be done with the standard routing mechanism mvc provides in it's initial project template. In a newsgroup I got the tip to have a look at the MvcRouteHandler and implement my own. But its hard to find a sample on how to do that.
Any ideas?
I don't believe a custom route handler is required for what you are doing.
For your "globalized" URIs, a regular MVC route, with a constraint that the "locale" parameter must be equal to "en", "de", etc., will do. The constraint will prevent non-globalized URIs from matching the route.
For a "non-globalized" URI, make a "catch-all" route which simply redirects to the default or cookie-set locale URI.
Place the "globalized" route above the "catch-all" route in Global.asax, so that "already-globalized" URIs don't fall through to the redirection.
You would need to make a new route handler if you want a certain URI pattern to trigger something that is not an action on a controller. But I don't think that's what you're dealing with, here.
You should be able to do this with ASP.NET MVC's default template, I'm doing something similar. Just build your routes as {language}/{controller}/{action}/{id}
Just set a default route that goes to a controller that checks for the language cookie, and redirects the user based on that cookie.

Categories

Resources