有没有可能有一个ASP。NET MVC路由,使用子域信息来确定它的路由?例如:
user1.domain。例子只有一个 user2.domain。例子指向另一个?
或者,我可以让这两个都去到相同的控制器/动作与用户名参数?
有没有可能有一个ASP。NET MVC路由,使用子域信息来确定它的路由?例如:
user1.domain。例子只有一个 user2.domain。例子指向另一个?
或者,我可以让这两个都去到相同的控制器/动作与用户名参数?
当前回答
如果你正在考虑为你的项目提供多租户功能,为每个租户提供不同的域/子域,你应该看看SaasKit:
https://github.com/saaskit/saaskit
代码示例可以在这里看到:http://benfoster.io/blog/saaskit-multi-tenancy-made-easy
一些使用ASP的例子。NET核心:http://andrewlock.net/forking-the-pipeline-adding-tenant-specific-files-with-saaskit-in-asp-net-core/
编辑: 如果你不想在你的ASP中使用SaasKit。你可以看看Maarten为MVC6实现的域路由:https://blog.maartenballiauw.be/post/2015/02/17/domain-routing-and-resolving-current-tenant-with-aspnet-mvc-6-aspnet-5.html
但是,这些gist没有得到维护,需要对其进行调整,以便与ASP的最新版本一起工作。净的核心。
直接链接到代码:https://gist.github.com/maartenba/77ca6f9cfef50efa96ec#file-domaintemplateroutebuilderextensions-cs
其他回答
在定义了一个新的Route处理程序(它将查看URL中传递的主机)之后,您可以使用一个基本控制器的思想,它知道正在访问它的站点。它是这样的:
public abstract class SiteController : Controller {
ISiteProvider _siteProvider;
public SiteController() {
_siteProvider = new SiteProvider();
}
public SiteController(ISiteProvider siteProvider) {
_siteProvider = siteProvider;
}
protected override void Initialize(RequestContext requestContext) {
string[] host = requestContext.HttpContext.Request.Headers["Host"].Split(':');
_siteProvider.Initialise(host[0]);
base.Initialize(requestContext);
}
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
ViewData["Site"] = Site;
base.OnActionExecuting(filterContext);
}
public Site Site {
get {
return _siteProvider.GetCurrentSite();
}
}
}
ISiteProvider是一个简单的接口:
public interface ISiteProvider {
void Initialise(string host);
Site GetCurrentSite();
}
我建议你去卢克·桑普森的博客
如果你正在考虑为你的项目提供多租户功能,为每个租户提供不同的域/子域,你应该看看SaasKit:
https://github.com/saaskit/saaskit
代码示例可以在这里看到:http://benfoster.io/blog/saaskit-multi-tenancy-made-easy
一些使用ASP的例子。NET核心:http://andrewlock.net/forking-the-pipeline-adding-tenant-specific-files-with-saaskit-in-asp-net-core/
编辑: 如果你不想在你的ASP中使用SaasKit。你可以看看Maarten为MVC6实现的域路由:https://blog.maartenballiauw.be/post/2015/02/17/domain-routing-and-resolving-current-tenant-with-aspnet-mvc-6-aspnet-5.html
但是,这些gist没有得到维护,需要对其进行调整,以便与ASP的最新版本一起工作。净的核心。
直接链接到代码:https://gist.github.com/maartenba/77ca6f9cfef50efa96ec#file-domaintemplateroutebuilderextensions-cs
为了在使用Web API时捕获子域,重写Action Selector以注入子域查询参数。然后在控制器的动作中使用子域查询参数,如下所示:
public string Get(string id, string subdomain)
这种方法使调试更加方便,因为当使用localhost而不是实际的主机名时,可以手动指定查询参数(有关详细信息,请参阅标准MVC5路由答案)。这是动作选择器的代码:
class SubdomainActionSelector : IHttpActionSelector
{
private readonly IHttpActionSelector defaultSelector;
public SubdomainActionSelector(IHttpActionSelector defaultSelector)
{
this.defaultSelector = defaultSelector;
}
public ILookup<string, HttpActionDescriptor> GetActionMapping(HttpControllerDescriptor controllerDescriptor)
{
return defaultSelector.GetActionMapping(controllerDescriptor);
}
public HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
var routeValues = controllerContext.Request.GetRouteData().Values;
if (!routeValues.ContainsKey("subdomain")) {
string host = controllerContext.Request.Headers.Host;
int index = host.IndexOf('.');
if (index >= 0)
controllerContext.Request.GetRouteData().Values.Add("subdomain", host.Substring(0, index));
}
return defaultSelector.SelectAction(controllerContext);
}
}
通过将其添加到WebApiConfig来替换默认的动作选择器。注册:
config.Services.Replace(typeof(IHttpActionSelector), new SubdomainActionSelector(config.Services.GetActionSelector()));
你可以通过创建一个新路由并将其添加到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;
}
}
这不是我的工作,但我必须把它加到这个答案上。
这里有一个解决这个问题的好办法。martin 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
))
;