241

サブドメイン情報を使用してルートを決定する ASP.NET MVC ルートを持つことは可能ですか? 例えば:

  • user1 .domain.comは 1 つの場所に
  • user2 .domain.comは別のものに行きますか?

または、これらの両方がusernameパラメーターを使用して同じコントローラー/アクションに移動するようにすることはできますか?

4

10 に答える 10

170

これを行うには、新しいルートを作成し、global.asax の RegisterRoutes のルート コレクションに追加します。以下は、カスタム ルートの非常に簡単な例です。

public class ExampleRoute : RouteBase
{

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var url = httpContext.Request.Headers["HOST"];
        var index = url.IndexOf(".");

        if (index < 0)
            return null;

        var subDomain = url.Substring(0, index);

        if (subDomain == "user1")
        {
            var routeData = new RouteData(this, new MvcRouteHandler());
            routeData.Values.Add("controller", "User1"); //Goes to the User1Controller class
            routeData.Values.Add("action", "Index"); //Goes to the Index action on the User1Controller

            return routeData;
        }

        if (subDomain == "user2")
        {
            var routeData = new RouteData(this, new MvcRouteHandler());
            routeData.Values.Add("controller", "User2"); //Goes to the User2Controller class
            routeData.Values.Add("action", "Index"); //Goes to the Index action on the User2Controller

            return routeData;
        }

        return null;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        //Implement your formating Url formating here
        return null;
    }
}
于 2009-02-12T14:30:49.993 に答える
55

標準のMVC5ルーティング機能を保持しながらサブドメインをキャプチャするには、SubdomainRouteから派生した次のクラスを使用しますRoute

さらに、SubdomainRouteサブドメインをオプションでクエリパラメータとして指定しsub.example.com/foo/barexample.com/foo/bar?subdomain=sub同等のものにすることができます。これにより、DNSサブドメインを構成する前にテストできます。Url.Actionクエリパラメータ(使用中)は、などによって生成された新しいリンクを介して伝播されます。

クエリパラメーターを使用すると、netshで構成したり、管理者として実行したりすることなく、VisualStudio2013でのローカルデバッグも可能になります。既定では、IIS Expressは、昇格されていない場合にのみローカルホストにバインドします。sub.localtest.meのような同義のホスト名にはバインドされません。

class SubdomainRoute : Route
{
    public SubdomainRoute(string url) : base(url, new MvcRouteHandler()) {}

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);
        if (routeData == null) return null; // Only look at the subdomain if this route matches in the first place.
        string subdomain = httpContext.Request.Params["subdomain"]; // A subdomain specified as a query parameter takes precedence over the hostname.
        if (subdomain == null) {
            string host = httpContext.Request.Headers["Host"];
            int index = host.IndexOf('.');
            if (index >= 0)
                subdomain = host.Substring(0, index);
        }
        if (subdomain != null)
            routeData.Values["subdomain"] = subdomain;
        return routeData;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        object subdomainParam = requestContext.HttpContext.Request.Params["subdomain"];
        if (subdomainParam != null)
            values["subdomain"] = subdomainParam;
        return base.GetVirtualPath(requestContext, values);
    }
}

便宜上、昔ながらの方法と同じようにMapSubdomainRoute、メソッドから次のメソッドを呼び出します。RegisterRoutesMapRoute

static void MapSubdomainRoute(this RouteCollection routes, string name, string url, object defaults = null, object constraints = null)
{
    routes.Add(name, new SubdomainRoute(url) {
        Defaults = new RouteValueDictionary(defaults),
        Constraints = new RouteValueDictionary(constraints),
        DataTokens = new RouteValueDictionary()
    });
}

最後に、(真のサブドメインまたはクエリパラメータから)サブドメインに簡単にアクセスするには、次のSubdomainプロパティを使用してController基本クラスを作成すると便利です。

protected string Subdomain
{
    get { return (string)Request.RequestContext.RouteData.Values["subdomain"]; }
}
于 2013-03-08T05:50:33.400 に答える
23

これは私の仕事ではありませんが、この回答に追加する必要がありました。

これは、この問題に対する優れた解決策です。Maartin Balliauw は、通常のルーティングと非常によく似た DomainRoute クラスを作成するコードを書きました。

http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx

サンプルの使用は次のようになります...

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

;

于 2010-04-27T18:22:52.860 に答える
3

はい。ただし、独自のルート ハンドラを作成する必要があります。

通常、ルートはドメインを認識しません。これは、アプリケーションが任意のドメインにデプロイされる可能性があり、ルートが何らかの方法で気にしないためです。しかし、あなたのケースでは、コントローラーとアクションをドメインに基づいたものにしたいので、ドメインを認識するカスタムルートを作成する必要があります.

于 2008-11-10T18:13:16.427 に答える
2

ASP.NET Coreでは、ホストは 経由で利用できますRequest.Host.Host。クエリ パラメータによるホストのオーバーライドを許可する場合は、最初に をオンにしますRequest.Query

ホスト クエリ パラメーターを新しいルート ベースの URL に伝達するには、次のコードをapp.UseMvcルート構成に追加します。

routes.Routes.Add(new HostPropagationRouter(routes.DefaultHandler));

そして、HostPropagationRouter次のように定義します。

/// <summary>
/// A router that propagates the request's "host" query parameter to the response.
/// </summary>
class HostPropagationRouter : IRouter
{
    readonly IRouter router;

    public HostPropagationRouter(IRouter router)
    {
        this.router = router;
    }

    public VirtualPathData GetVirtualPath(VirtualPathContext context)
    {
        if (context.HttpContext.Request.Query.TryGetValue("host", out var host))
            context.Values["host"] = host;
        return router.GetVirtualPath(context);
    }

    public Task RouteAsync(RouteContext context) => router.RouteAsync(context);
}
于 2016-10-12T10:34:08.537 に答える