使用子域作为参数

时间:2014-11-17 12:39:57

标签: c# asp.net asp.net-mvc

我有一个使用多个子域运行的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方法中的参数,它包含属性提取的值。这甚至可能吗?

如果无法做到这一点,是否有更好的方式来做我现在正在做的事情而不必依赖会话?

谢谢,

迪伦

3 个答案:

答案 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 
    }
}