質問

私はasp.netを初めて使用しますが、iisの経験はほとんどありません。アプリケーションの各ユーザーに独自のサブドメインを取得させたいのですが、全員が同じコントローラーを使用しています。サブドメインは、表示されるコンテンツを制御します。

例:

user1subdomain.mydomain.com/Whatever
user2subdomain.mydomain.com/Whatever

両方が同じコントローラーを使用します。理想的には、パラメーターがユーザー名をコントローラーに提供し、コントローラーが適切なコンテンツを表示できることが理想的です。新しいサブドメインが追加されるたびにルーティングルールを書き換えることなく、新しいサブドメインをデータベースに追加できるように十分な柔軟性を持たせたい。

役に立ちましたか?

解決

MVCはドメインにバインドされず、パスにのみバインドされます(例: http:// domain / path )。

これを適切に行うには、次のものが必要です...

  1. のワイルドカードDNS設定 * .yourdomain.comはサーバーを指します。
  2. IISセットアップのサイト ホストヘッダーなし。その他のサイト IISのそのインスタンスでホストされています 同じIPにはHostヘッダーが必要です 指定されています。
  3. アプリケーションは、 ページの読み込み時にホストヘッダーをリクエストする、 セッション開始またはその他のイベント。

他のヒント

この人のブログで簡単な答えを見つけました。これがうまく機能し、このソリューションが4年以上前のものであることに非常に驚いた。

http://blog.maartenballiauw。 be / post / 2009/05/20 / aspnet-mvc-domain-routing.aspx

カスタムルートの実装:

public class DomainRoute : Route
{
    public string Domain { get; set; }


    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        // Build regex
        domainRegex = CreateRegex(Domain);
        pathRegex = CreateRegex(Url);

        // Request information
        string requestDomain = httpContext.Request.Headers["host"];
        if (!string.IsNullOrEmpty(requestDomain))
        {
            if (requestDomain.IndexOf(":") > 0)
            {
                requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":"));
            }
        }
        else
        {
            requestDomain = httpContext.Request.Url.Host;
        }
        string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;

        // Match domain and route
        Match domainMatch = domainRegex.Match(requestDomain);
        Match pathMatch = pathRegex.Match(requestPath);

        // Route data
        RouteData data = null;
        if (domainMatch.Success && pathMatch.Success)
        {
            data = new RouteData(this, RouteHandler);

            // Add defaults first
            if (Defaults != null)
            {
                foreach (KeyValuePair<string, object> item in Defaults)
                {
                    data.Values[item.Key] = item.Value;
                }
            }

            // Iterate matching domain groups
            for (int i = 1; i < domainMatch.Groups.Count; i++)
            {
                Group group = domainMatch.Groups[i];
                if (group.Success)
                {
                    string key = domainRegex.GroupNameFromNumber(i);
                    if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                    {
                        if (!string.IsNullOrEmpty(group.Value))
                        {
                            data.Values[key] = group.Value;
                        }
                    }
                }
            }

            // Iterate matching path groups
            for (int i = 1; i < pathMatch.Groups.Count; i++)
            {
                Group group = pathMatch.Groups[i];
                if (group.Success)
                {
                    string key = pathRegex.GroupNameFromNumber(i);
                    if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                    {
                        if (!string.IsNullOrEmpty(group.Value))
                        {
                            data.Values[key] = group.Value;
                        }
                    }
                }
            }
        }    
    return data;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return base.GetVirtualPath(requestContext, RemoveDomainTokens(values));
    }

    public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values)
    {
        // Build hostname
        string hostname = Domain;
        foreach (KeyValuePair<string, object> pair in values)
        {
            hostname = hostname.Replace("{" + pair.Key + "}", pair.Value.ToString());
        }

        // Return domain data
        return new DomainData
        {
            Protocol = "http",
            HostName = hostname,
            Fragment = ""
        };
    }}

そして、これがどのように使用できるかです。

routes.Add("DomainRoute", new DomainRoute(
"{controller}-{action}.example.com",     // Domain with parameters
"{id}",    // URL with parameters
new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
));

ほとんど問題ありません。私は思う!

アプリケーション/ルーティングに関しては、ドメインが終了する場所からルーティングが開始されるため、複数のドメインを同じアプリケーションにマッピングしても問題はありません。それは機能します。

IISの観点から、単一のサイトに必要な数のドメインをマップできます(制限があります)-ワイルドカードを使用できるかどうかはわかりません-IISのどのバージョンを使用していますか?

リクエストが到着すると、フックしてドメインを確認できるイベントがあるため、必要なパラメーター(ユーザーなど)を設定します。リクエストのルートURLは、サイクルの後半のコンテキストからも利用できますが、早めに拾いたいでしょう。

ワイルドカードを実行できる場合、かなり簡単になります-リクエストを受け取り、データベース内のユーザーに対してサブドメインを検証し(デフォルトサイトへの有効なリダイレクトでない場合)、ユーザーを設定して通常のルーティングを実行します。

ワイルドカードを実行できない場合、ユーザーがデータベースに追加されるときに、アプリケーションからその場でIISアプリケーション(Webサイト)にホストヘッダーを追加することが課題になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top