そう、
IIS 6 (wildcard application maps/aspnet_isapi.dll ハック) に MVC 2 サイトがあり、好みの場所 (la.acme.com と nyc.acme.com など) に応じて異なる URL にユーザーを誘導したいと考えています。
誰にも 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 など) を許可する「アクション」を実行している場合は、それ以上先に進む必要はありません。
URL に「www」が含まれている場合、または都市のプレフィックスが含まれていない場合は、状況を修正する必要があるため、先に進みましょう。
希望する都市を指定する Cookie (StoreLocationID) がある場合は、/Home/ChooseCity にリダイレクトし、そこで他の Cookie を設定して正しい URL (nyc.acme.com または la.acme.com) にリダイレクトします。
ユーザーがサインインしており、ユーザー アカウントに希望の都市がリストされている場合は、それを使用します (/Home/ChooseCity にリダイレクト -- 上記 3 と同じ)
Cookie もユーザー アカウントにも保存されていないため、IP を使用して zip を取得し、zip がカバーする都市内またはその周辺にあるかどうかを確認します。そうである場合は、上記の 3 と 4 のように /Home/ChooseCity に送信します
最後に、どの都市を希望するか判断できない場合は、/Home/ChooseLocation/ で手動で選択してもらいます。
これはすべて機能します。しかし、ランダムな時間に次のことに気付き始めています...
場合によっては (パターンがないように見えますが)、ユーザーがリンクをクリックして、完全にランダムなページ (クリックしたリンクのリンク先ではない) にたどり着くことがあります。彼らがたどり着く場所は、通常、別のユーザー (離れた都市) が要求していた可能性がある場所のようです (あなたが量子エンタングルメントを考えていることは知っていますが、私はそれを除外しました)。誰が何を要求したのか、IIS が混乱しているようです。
私の質問 (結局) は、上記 (のOnActionExecuted
) の私のロジックが IIS のトリップアップを引き起こしている可能性はありますか? 「ランダムな場所」の問題は、URL に nyc または la を含むユーザー、つまり適切な storelocation cookie を持つユーザーでも発生することに注意してください。これは、URL と Cookie が適切に構成されているため、ユーザーが「/Home/ChooseCity」または「/Home/ChooseLocation」にリダイレクトされないことを意味します。