简体   繁体   English

重写OnActionExecuted和获取怪异的IIS响应

[英]Overriding OnActionExecuted and Getting Weird IIS Responses

So, 所以,

I have an MVC 2 site on IIS 6 (wildcard application maps/aspnet_isapi.dll hack) that where we want to direct people to different URLs depending on their preferred location, let's say la.acme.com vs. nyc.acme.com. 我在IIS 6上有一个MVC 2站点(通配符应用程序maps / aspnet_isapi.dll hack),在该站点上我们希望根据人们的首选位置将人们定向到不同的URL,例如la.acme.com与nyc.acme.com。

I do not want anyone to end up at www.acme.com or acme.com. 我不希望任何人以www.acme.com或acme.com结尾。

To accomplish this I am doing the following (I'll admit it may not be the best way, which is why I am asking this question): 为了做到这一点,我正在做以下事情(我承认这可能不是最好的方法,这就是为什么我问这个问题):

In my base controller, I am doing the following: 在我的基本控制器中,我正在执行以下操作:

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);
    }

Here's a summary of the lengthy code in OnActionExecuted above: 这是上面OnActionExecuted冗长代码的摘要:

  1. if the user is on an "Action" where we will allow www.acme.com or acme.com (like PrivacyPolicy), then don't bother going any further; 如果用户在“操作”中允许我们访问www.acme.com或acme.com(例如PrivacyPolicy),则无需再进行任何操作;

  2. if the url contains "www" or it does not contain the city prefix, then let's move on as we need to fix the situation; 如果网址包含“ www”或不包含城市前缀,那么请继续进行处理,以解决问题;

  3. if they have a cookie (StoreLocationID) that specifies their preferred city, then redirect to /Home/ChooseCity where we will set other cookies and redirect to the correct URL: nyc.acme.com or la.acme.com. 如果他们有指定其首选城市的cookie(StoreLocationID),则重定向到/ Home / ChooseCity,我们将在其中设置其他cookie并重定向到正确的URL:nyc.acme.com或la.acme.com。

  4. if they are signed-in, and if their user account lists a preferred city, then use that (redirect to /Home/ChooseCity -- same as 3 above) 如果他们已登录,并且其用户帐户列出了首选城市,则使用该城市(重定向到/ Home / ChooseCity-与上述3相同)

  5. they have no cookie and no stored in a user account, so use their IP to get a zip and see if the zip is in or around a city we cover, if so send to /Home/ChooseCity as in 3 & 4 above 他们没有Cookie,也没有存储在用户帐户中,因此请使用其IP获取邮政编码,并查看该邮政编码是否在我们覆盖的城市之内或附近,如果是的话,请按照上述3和4的说明发送至/ Home / ChooseCity

  6. finally, if we cannot determine what city they'd prefer, we have them choose manually at /Home/ChooseLocation/ 最后,如果我们无法确定他们想要的城市,请让他们在/ Home / ChooseLocation /

This all works . 这一切有效 BUT, we are starting to notice the following at random times... 但是,我们开始在随机时间注意到以下情况...

Sometimes (and with no seeming pattern) a user will click a link and end up at a completely random page (not the destination of the clicked link). 有时(没有看上去的样式),用户将单击一个链接并最终到达一个完全随机的页面(而不是单击的链接的目标)。 It would seem that the location they end up at is usually a location that another user (cities apart) may have been requesting (I know that you're thinking quantum entanglement, but I've ruled that out). 他们最终到达的位置似乎通常是另一个用户(相隔两个城市)可能正在请求的位置(我知道您正在考虑量子纠缠,但我已经排除了这一点)。 It's as if IIS is getting confused as to whom asked for what. 好像IIS对于谁要求什么感到困惑。

My question (after all that) is can my logic above (in OnActionExecuted ) be causing IIS to trip up? 我的问题(毕竟)是上面的逻辑(在OnActionExecuted )是否会导致IIS跳闸? It should be noted that the "random locations" problem arises even for users with nyc or la in the URL...users who have the proper storelocation cookie. 应当注意的是,即使对于URL中带有nyc或la的用户,也会出现“随机位置”问题……具有适当存储位置cookie的用户。 This means that the user should never be redirected to "/Home/ChooseCity" or "/Home/ChooseLocation" as they have the proper configuration of URL and cookies. 这意味着永远不要将用户重定向到“ / Home / ChooseCity”或“ / Home / ChooseLocation”,因为它们具有正确的URL和cookie配置。

The final answer to this is that I was using static classes/properties in places where this was not appropriate. 对此的最终答案是,我在不合适的地方使用了静态类/属性。 I did not understand that such static classes were shared across the entire web application (meaning all users). 我不明白这种静态类是在整个Web应用程序(意味着所有用户)之间共享的。 I assumed they were contained to one user at a time. 我假设它们一次只包含一个用户。

The weird behavior was the result of race conditions on shared properties. 怪异的行为是共享属性上竞争条件的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM