1

所以,

我在 IIS 6 上有一个 MVC 2 站点(通配符应用程序映射/aspnet_isapi.dll hack),我们希望根据他们的首选位置将人们引导到不同的 URL,比如说 la.acme.com 与 nyc.acme.com。

我不希望任何人最终访问 www.acme.com 或 acme.com。

为了做到这一点,我正在做以下事情(我承认这可能不是最好的方法,这就是我问这个问题的原因):

在我的基本控制器中,我正在执行以下操作:

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {

        ReturnURL = requestContext.HttpContext.Request.Url.PathAndQuery;

        BaseUrl = requestContext.HttpContext.Request.Url.Host;
        if (!requestContext.HttpContext.Request.Url.IsDefaultPort) {
            BaseUrl += ":" + requestContext.HttpContext.Request.Url.Port;
        }
        ViewData["BaseUrl"] = BaseUrl;

        base.Initialize(requestContext);
    }

protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {


        var route = filterContext.RequestContext.RouteData;
        var controller = route.GetRequiredString("controller");
        var action = route.GetRequiredString("action");
        string basePlusHttp = "http://" + BaseUrl;
        string basePlusHttps = "https://" + BaseUrl;

        string actionsToSkip = "ChooseCity|DisplayPhoto|ChooseLocation|Press|ContactUs|AboutUs|TermsOfService|PrivacyPolicy|Logon|Register|Prospect|";

        if (!actionsToSkip.Contains(action + "|")) {
            if (BaseUrl.Contains("www.acme.com") || basePlusHttp.StartsWith("http://acme.com") || basePlusHttps.StartsWith("https://acme.com")) {
                if (filterContext.HttpContext.Request.Cookies["StoreLocationID"] != null && Convert.ToInt32(filterContext.HttpContext.Request.Cookies["StoreLocationID"].Value) > 0) {
                    filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/" + Convert.ToInt32(filterContext.HttpContext.Request.Cookies["StoreLocationID"].Value) + "?returnURL=" + ReturnURL);
                } else {
                    aspnet_User user = Repository.GetAspnet_User(filterContext.HttpContext.User.Identity.Name);
                    if (user != null) {
                        if (user.StoreLocationID != null) {
                            int storeLocationID = Convert.ToInt32(user.StoreLocationID);
                            filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/" + storeLocationID + "?returnURL=" + ReturnURL);
                        } else {
                            //get location by IP
                            string zip = getZipFromIP();
                            if (!string.IsNullOrEmpty(zip)) {
                                var zipCode = Repository.GetZipCode(zip);
                                if (zipCode != null) {
                                    var storeLocation = Repository.GetStoreLocationByZipCodeID(zipCode.ZipCodeID);
                                    if (storeLocation != null) {
                                        filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/" + storeLocation.StoreLocationID + "?returnURL=" + ReturnURL);
                                    } else {
                                        filterContext.HttpContext.Response.Redirect("/Home/ChooseLocation/");
                                    }
                                } else {
                                    filterContext.HttpContext.Response.Redirect("/Home/ChooseLocation/");
                                }
                            } else {
                                filterContext.HttpContext.Response.Redirect("/Home/ChooseLocation/");
                            }
                        }
                    } else {
                        //get location by IP
                        string zip = getZipFromIP();
                        if (!string.IsNullOrEmpty(zip)) {
                            var zipCode = Repository.GetZipCode(zip);
                            if (zipCode != null) {
                                var storeLocation = Repository.GetStoreLocationByZipCodeID(zipCode.ZipCodeID);
                                if (storeLocation != null) {
                                    filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/" + storeLocation.StoreLocationID + "?returnURL=" + ReturnURL);
                                } else {
                                    filterContext.HttpContext.Response.Redirect("/Home/ChooseLocation/");
                                }
                            } else {
                                filterContext.HttpContext.Response.Redirect("/Home/ChooseLocation/");
                            }
                        } else {
                            filterContext.HttpContext.Response.Redirect("/Home/ChooseLocation/");
                        }

                    }
                }
            } else { //make sure the storelocation chookie value is correct based on the URL...we should not have a nyc.acme.com url with an 'la' cookie.
                if (BaseUrl.Contains("nyc.")) {
                    if (filterContext.HttpContext.Request.Cookies["StoreLocationID"] == null) {
                        filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/3?returnURL=" + ReturnURL);
                    } else {
                        if (filterContext.HttpContext.Request.Cookies["StoreLocationID"].Value != "3") {
                            filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/3?returnURL=" + ReturnURL);
                        }
                    }
                }

                if (BaseUrl.Contains("la.")) {
                    if (filterContext.HttpContext.Request.Cookies["StoreLocationID"] == null) {
                        filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/5?returnURL=" + ReturnURL);
                    } else {
                        if (filterContext.HttpContext.Request.Cookies["StoreLocationID"].Value != "5") {
                            filterContext.HttpContext.Response.Redirect("/Home/ChooseCity/5?returnURL=" + ReturnURL);
                        }
                    }
                }
            }
        }





        base.OnActionExecuted(filterContext);
    }

这是上面冗长代码的摘要OnActionExecuted

  1. 如果用户在我们将允许 www.acme.com 或 acme.com(如 PrivacyPolicy)的“操作”上,那么不要再费心了;

  2. 如果 url 包含“www”或者它不包含城市前缀,那么让我们继续,因为我们需要修复这种情况;

  3. 如果他们有指定首选城市的 cookie (StoreLocationID),则重定向到 /Home/ChooseCity,我们将在其中设置其他 cookie 并重定向到正确的 URL:nyc.acme.com 或 la.acme.com。

  4. 如果他们已登录,并且如果他们的用户帐户列出了首选城市,则使用该城市(重定向到 /Home/ChooseCity - 与上面的 3 相同)

  5. 他们没有 cookie,也没有存储在用户帐户中,所以使用他们的 IP 获取 zip 并查看 zip 是否在我们覆盖的城市内或周围,如果是,请发送到 /Home/ChooseCity,如上面 3 和 4

  6. 最后,如果我们无法确定他们喜欢哪个城市,我们让他们在 /Home/ChooseLocation/ 手动选择

这一切都有效。但是,我们开始随机注意到以下内容......

有时(并且没有看似模式)用户会点击一个链接并最终进入一个完全随机的页面(不是点击链接的目的地)。看起来他们最终到达的位置通常是另一个用户(分开的城市)可能一直在请求的位置(我知道你正在考虑量子纠缠,但我已经排除了这一点)。就好像 IIS 对谁要求什么感到困惑。

我的问题(毕竟)是我上面的逻辑(in OnActionExecuted)会导致 IIS 出错吗?应该注意的是,即使对于 URL 中带有 nyc 或 la 的用户,也会出现“随机位置”问题......拥有正确 storelocation cookie 的用户。这意味着用户不应该被重定向到“/Home/ChooseCity”或“/Home/ChooseLocation”,因为他们已经正确配置了 URL 和 cookie。

4

1 回答 1

0

对此的最终答案是,我在不合适的地方使用了静态类/属性。我不明白这样的静态类是在整个 Web 应用程序(即所有用户)中共享的。我假设它们一次只包含一个用户。

奇怪的行为是共享属性竞争条件的结果。

于 2011-02-19T15:47:13.673 回答