It depends on how you plan on implementing multitenancy (eg. using authorization with common urls, subdomains, custom domains, or any combination). But you should be able to do just about any approach with Azure and MVC2. If you plan on using a custom domain for each tenant, versus a subdomain, you will need to be happy with using CNAME entries (not A records) to point each custom domain to Azure but that usually is not a problem.
MVC offers many extension points where you can implement multitenancy in its various flavors. The main goal is to uniquely identify the user by either a login or the url.
We have an MVC2 application running in Azure that parses the request url to differentiate the tenant. There are many ways to do this. We took the approach of extending the Controller class to provide our app with the unique tenant information so we could use it as needed to make appropriate repository calls to display the proper views etc.
Here is a sample of what a MultiTenant Controller might look like:
public class MultiTenantController : Controller {
public string TenantCode { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
TenantCode = GetTenantCode(filterContext.HttpContext.Request);
}
private string GetTenantCode(System.Web.HttpRequestBase request) {
string host = new RequestParser(request.Url.AbsoluteUri).Host;
return _tenantService.GetTenantCodeByHostAddress(host);
}
}
NOTES:
- The RequestParser function
above is just any implementation
that knows how to parse urls in a
safe manner.
- _tenantService
can access some kind of persistent
store (Azure Tables in our case) to
get the TenantCode from the host
address in the url.
All of your controllers would inherit from the above class. Then, to differentiate between tenants you just refer to the TenantCode within your controller like so:
public class HomeController : MultiTenantController {
...
public ViewResult Index() {
var vm = _homeService.GetHomePageViewModelForTenant(TenantCode);
return View(vm);
}
}
Using the above implementation you could serve different sites or data to urls like the following:
http://subtenant1.yourdomain.com
http://subtenant2.yourdomain.com
http://www.customtenantdomain.com
Your backend store (eg. Table Storage) just needs to cross reference host names with the tenant like the table below. In the code above GetTenantCode would access the data.
HostName TenantCode
---------------------- --------------
subtenant1 Tenant1ID
subtenant2 Tenant2ID
www.customtenantdomain Tenant3ID
For www.customtenantdomain.com to work, the tenant needs a CNAME entry for www in their DNS records for customtenantdomain.com that points to your Azure Web Role's address.