我有一个使用多个子域运行的ASP.net MVC(5.2)站点,其中子域名是我数据库中客户端的名称。基本上我想要做的是使用子域作为我的动作方法中的变量,以允许我从我的数据库中获取正确的数据。
几年前我做了类似的事情,但它很乱,而且不直观,所以想知道是否有比以前更好的方法。这是我以前做的:
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
Session["subdomain"] = GetSubDomain(Request.Url);
}
private static string GetSubDomain(Uri url) {
string host = url.Host;
if (host.Split('.').Length > 1) {
int index = host.IndexOf(".");
string subdomain = host.Substring(0, index);
if (subdomain != "www") {
return subdomain;
}
}
return null;
}
如果子域名不是" www",那基本上为会话变量分配了一个键,但是我真的不满意这种做法,因为它依赖于我知道会话可能包含这个神奇的价值!
理想情况下,我希望能够创建一个属性,我可以用我的类/方法来提取子域,然后允许我包含一个"子域"我的action方法中的参数,它包含属性提取的值。这甚至可能吗?
如果无法做到这一点,是否有更好的方式来做我现在正在做的事情而不必依赖会话?
谢谢,
迪伦
答案 0 :(得分:0)
您可以在Session
中的Session_Start
事件的global.asax
中设置名称,这意味着它只会发生一次,并会在用户持续时间内保持不变;会话
public void Session_Start(object sender, EventArgs e)
{
Session["subdomain"] = GetSubDomain(Request.Url);
}
答案 1 :(得分:0)
看起来有一种很好的方式来做我所追求的目标:
ASP.NET MVC Pass object from Custom Action Filter to Action
它实际上使用路由数据将自定义参数传递给操作,并且还可以传递除简单字符串之外的对象等。
从好的方面来说,它避免使用会话并依赖于魔术值,但在缺点方面,它意味着处理每个请求的URL,如果涉及数据库,这可能不是一个好主意。
答案 2 :(得分:0)
你的权利不需要存储在会话中,恕我直言也不应该存在,我会将其重构为自己的类并使用HttpContext.Current
。
public interface ISubDomainProvider
{
string SubDomain { get; set; }
}
public class SubDomainProvider : ISubDomainProvider
{
public SubDomainProvider()
{
string host = HttpContext.Current.Request.Url.Host; // not checked (off the top of my head
if (host.Split('.').Length > 1)
{
int index = host.IndexOf(".");
string subdomain = host.Substring(0, index);
if (subdomain != "www")
{
SubDomain = subdomain;
}
}
}
public string SubDomain { get; set; }
}
你选择如何使用它,如果你使用IoC容器,它只是通过构造函数将这个类注入你的控制器的情况,我喜欢这样,因为它更容易进行模拟和单元测试。当然你仍然可以这样做:
public class SomeController : Controller
{
private readonly ISubDomainProvider _subDomainProvider;
public SomeController()
{
_subDomainProvider = new SubDomainProvider();
}
}
您甚至可以创建自己的抽象控制器类:
public abstract class MyAbstractController : Controller
{
public MyAbstractController()
{
SubDomain = new SubDomainProvider();
}
protected string SubDomain {get; set; }
}
public class SomeController : MyAbstractController
{
public ActionResult SomeAction()
{
// access the subdomain by calling the base base.SubDomain
}
}