有没有可能有一个ASP。NET MVC路由,使用子域信息来确定它的路由?例如:
user1.domain。例子只有一个 user2.domain。例子指向另一个?
或者,我可以让这两个都去到相同的控制器/动作与用户名参数?
有没有可能有一个ASP。NET MVC路由,使用子域信息来确定它的路由?例如:
user1.domain。例子只有一个 user2.domain。例子指向另一个?
或者,我可以让这两个都去到相同的控制器/动作与用户名参数?
当前回答
要在保留标准MVC5路由特性的同时捕获子域,请使用以下从Route派生的SubdomainRoute类。
此外,SubdomainRoute允许将子域可选地指定为查询参数,使sub.example.com/foo/bar和example.com/foo/bar?subdomain=sub等效。这允许您在配置DNS子域之前进行测试。查询参数(在使用时)通过Url生成的新链接传播。行动等。
查询参数还可以使用Visual Studio 2013进行本地调试,而无需使用netsh进行配置或以管理员身份运行。默认情况下,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);
}
}
为了方便起见,从你的RegisterRoutes方法中调用下面的MapSubdomainRoute方法,就像你将普通的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"]; }
}
其他回答
在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);
}
你可以通过创建一个新路由并将其添加到global.asax中的RegisterRoutes中的routes集合来实现。下面是一个自定义路由的简单例子:
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;
}
}
我创建了子域路由库,您可以创建这样的路由。它目前正在为。net Core 1.1和。net Framework 4.6.1工作,但将在不久的将来进行更新。它是这样工作的: 1)在Startup.cs中映射子域路由
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
var hostnames = new[] { "localhost:54575" };
app.UseMvc(routes =>
{
routes.MapSubdomainRoute(
hostnames,
"SubdomainRoute",
"{username}",
"{controller}/{action}",
new { controller = "Home", action = "Index" });
)};
2)控制器/ HomeController.cs
public IActionResult Index(string username)
{
//code
}
3)该库还将允许您生成url和表单。代码:
@Html.ActionLink("User home", "Index", "Home" new { username = "user1" }, null)
将生成<a href="http://user1。localhost: 54575 / Home /指数”> < / >用户家里 生成的URL还取决于当前主机位置和模式。 你也可以为BeginForm和UrlHelper使用html帮助。如果你喜欢,你也可以使用新功能称为标签助手(FormTagHelper, AnchorTagHelper) 该库还没有任何文档,但有一些测试和示例项目,所以请随意探索。
要在保留标准MVC5路由特性的同时捕获子域,请使用以下从Route派生的SubdomainRoute类。
此外,SubdomainRoute允许将子域可选地指定为查询参数,使sub.example.com/foo/bar和example.com/foo/bar?subdomain=sub等效。这允许您在配置DNS子域之前进行测试。查询参数(在使用时)通过Url生成的新链接传播。行动等。
查询参数还可以使用Visual Studio 2013进行本地调试,而无需使用netsh进行配置或以管理员身份运行。默认情况下,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);
}
}
为了方便起见,从你的RegisterRoutes方法中调用下面的MapSubdomainRoute方法,就像你将普通的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"]; }
}
是的,但是你必须创建你自己的路由处理器。
通常情况下,路由不知道域,因为应用程序可以部署到任何域,路由不会关心这种或那种方式。但在你的情况下,你想要基于域的控制器和动作,所以你必须创建一个自定义路由,它可以感知域。