In SaasApp which is framework for mulituser-multitenant SAAS framework for ASP.Net MVC, what I wanted was that when user types the url without a subdomain my app should display the website where user can get details about the product and plans, select a plan and register an account (in this post account refers to say a company that can have multiple users) with selected plan. Once an account is created their users should be able to go to their selected subdomain like myaccount.[SAAS app domain].com, login and access the product. I wanted the subbdomain “myaccount” to be forwarded as a parameter to required actions in the controller to identify the account I am dealing with.
ASP.Net MVC has a sophisticated and flexible routing mechanism. It allows developers to create their own customized routing system by extending RouteBase class and providing your own implementation of GetRouteData(HttpContextBase) function.
Following is what I have used -
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SaasApp.Utility; namespace System.Web.Routing { public class DomainRoute : RouteBase { public override RouteData GetRouteData(HttpContextBase httpContext) { //get subdomain, the string before first dot in the url string subdomain = UtilityHelper.GetSubdomain(httpContext.Request.Headers["HOST"]); RouteData routeData = new RouteData(this, new MvcRouteHandler()); if (!string.IsNullOrEmpty(subdomain)) { //url has subdomain routeData.Values.Add("account", subdomain); string filepath = httpContext.Request.FilePath; string[] parts = filepath.Split('/'); switch (parts[1].ToLower()) { case "app": routeData.Values.Add("controller", "App"); if (parts.Length > 2) { switch (parts[2].ToLower()) { case "index": routeData.Values.Add("action", "Index"); break; case "about": routeData.Values.Add("action", "About"); break; default: routeData.Values.Add("action", "Index"); break; } } else { routeData.Values.Add("action", "Index"); } break; case "account": routeData.Values.Add("controller", "Account"); if (parts.Length > 2) { switch (parts[2].ToLower()) { case "login": routeData.Values.Add("action", "Login"); break; case "logout": routeData.Values.Add("action", "Logout"); break; } } break; default: if (httpContext.Request.IsAuthenticated) { httpContext.Response.Redirect("/App/Index"); } httpContext.Response.Redirect("/Account/Login"); break; } } else { //url does not have subdomain string filepath = httpContext.Request.FilePath; string[] parts = filepath.Split('/'); switch (parts[1].ToLower()) { case "home": routeData.Values.Add("controller", "Home"); if (parts.Length > 2) { switch (parts[2].ToLower()) { case "index": routeData.Values.Add("action", "Index"); break; case "plans": routeData.Values.Add("action", "Plans"); break; case "selectplan": routeData.Values.Add("action", "SelectPlan"); if (parts.Length > 3) { routeData.Values.Add("planType", parts[3]); } else { routeData.Values.Add("planType", "1"); } break; case "selectaplan": routeData.Values.Add("action", "SelectAPlan"); break; case "accountcreated": routeData.Values.Add("action", "AccountCreated"); if (parts.Length > 3) { routeData.Values.Add("accountName", parts[3]); } else { routeData.Values.Add("accountName", ""); } break; case "about": routeData.Values.Add("action", "About"); break; default: routeData.Values.Add("action", "Index"); break; } } else { routeData.Values.Add("action", "Index"); } break; default: httpContext.Response.Redirect("/Home/Index"); break; } } return routeData; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { //Implement your formating Url formating here return null; } } }
0 nhận xét:
Đăng nhận xét