[英]Overriding OnActionExecuted and Getting Weird IIS Responses
所以,
我在IIS 6上有一个MVC 2站点(通配符应用程序maps / 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
冗长代码的摘要:
如果用户在“操作”中允许我们访问www.acme.com或acme.com(例如PrivacyPolicy),则无需再进行任何操作;
如果网址包含“ www”或不包含城市前缀,那么请继续进行处理,以解决问题;
如果他们有指定其首选城市的cookie(StoreLocationID),则重定向到/ Home / ChooseCity,我们将在其中设置其他cookie并重定向到正确的URL:nyc.acme.com或la.acme.com。
如果他们已登录,并且其用户帐户列出了首选城市,则使用该城市(重定向到/ Home / ChooseCity-与上述3相同)
他们没有Cookie,也没有存储在用户帐户中,因此请使用其IP获取邮政编码,并查看该邮政编码是否在我们覆盖的城市之内或附近,如果是的话,请按照上述3和4的说明发送至/ Home / ChooseCity
最后,如果我们无法确定他们想要的城市,请让他们在/ Home / ChooseLocation /
这一切有效 。 但是,我们开始在随机时间注意到以下情况...
有时(没有看上去的样式),用户将单击一个链接并最终到达一个完全随机的页面(而不是单击的链接的目标)。 他们最终到达的位置似乎通常是另一个用户(相隔两个城市)可能正在请求的位置(我知道您正在考虑量子纠缠,但我已经排除了这一点)。 好像IIS对于谁要求什么感到困惑。
我的问题(毕竟)是上面的逻辑(在OnActionExecuted
)是否会导致IIS跳闸? 应当注意的是,即使对于URL中带有nyc或la的用户,也会出现“随机位置”问题……具有适当存储位置cookie的用户。 这意味着永远不要将用户重定向到“ / Home / ChooseCity”或“ / Home / ChooseLocation”,因为它们具有正确的URL和cookie配置。
对此的最终答案是,我在不合适的地方使用了静态类/属性。 我不明白这种静态类是在整个Web应用程序(意味着所有用户)之间共享的。 我假设它们一次只包含一个用户。
怪异的行为是共享属性上竞争条件的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.