サブドメイン情報を使用してルートを決定する ASP.NET MVC ルートを持つことは可能ですか? 例えば:
- user1 .domain.comは 1 つの場所に
- user2 .domain.comは別のものに行きますか?
または、これらの両方がusername
パラメーターを使用して同じコントローラー/アクションに移動するようにすることはできますか?
サブドメイン情報を使用してルートを決定する ASP.NET MVC ルートを持つことは可能ですか? 例えば:
または、これらの両方がusername
パラメーターを使用して同じコントローラー/アクションに移動するようにすることはできますか?
これを行うには、新しいルートを作成し、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;
}
}
標準のMVC5ルーティング機能を保持しながらサブドメインをキャプチャするには、SubdomainRoute
から派生した次のクラスを使用しますRoute
。
さらに、SubdomainRoute
サブドメインをオプションでクエリパラメータとして指定しsub.example.com/foo/bar
、example.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
、メソッドから次のメソッドを呼び出します。RegisterRoutes
MapRoute
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"]; }
}
これは私の仕事ではありませんが、この回答に追加する必要がありました。
これは、この問題に対する優れた解決策です。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
))
;
はい。ただし、独自のルート ハンドラを作成する必要があります。
通常、ルートはドメインを認識しません。これは、アプリケーションが任意のドメインにデプロイされる可能性があり、ルートが何らかの方法で気にしないためです。しかし、あなたのケースでは、コントローラーとアクションをドメインに基づいたものにしたいので、ドメインを認識するカスタムルートを作成する必要があります.
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);
}