Yatendra Khandelwal

  • Random
  • Archive
  • RSS
  • Ask me anything

Handling sub-domains in ASP.Net MVC

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. 

Demo: http://saasapp.yatendra.com

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;

        } 

    }

}

  • 5 months ago
  • Comments
  • Permalink
  • Share
    Tweet

Recent comments

Blog comments powered by Disqus
← Previous • Next →

About

.... technology, business, technology in business, business in technology and more ....
  • Projects

Me, Elsewhere

  • @yatendra on Twitter
  • Linkedin Profile
  • yatendra on github
  • RSS
  • Random
  • Archive
  • Ask me anything
  • Mobile

Effector Theme by Carlo Franco.

Powered by Tumblr