我避免了重定向錯誤的默認ASP.NET方法(很多人都這麼做)。清理AJAX代碼和SEO是其中的原因。通過responseMode =「ExecuteURL」清除HttpContext.Current.Items?
但是,我正在使用以下方法來執行此操作,而且似乎在傳輸中可能會丟失HttpContext.Current.Items
?
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="401" />
<remove statusCode="403" />
<remove statusCode="404" />
<remove statusCode="500" />
<error statusCode="401" responseMode="ExecuteURL" path="/Account/SignIn" />
<error statusCode="403" responseMode="ExecuteURL" path="/Site/Forbidden" />
<error statusCode="404" responseMode="ExecuteURL" path="/Site/NotFound" />
<error statusCode="500" responseMode="ExecuteURL" path="/Site/Error" />
</httpErrors>
我以爲這只是蓋子,我的理解保留Items
下進行Server.Transfer()
。 (參見:Scope of HttpContext.Current.Items和http://weblog.west-wind.com/posts/2010/Jan/20/HttpContextItems-and-ServerTransferExecute)
但我還捕捉了「ExecuteURL」前Items
的東西,和檢索/轉讓後其輸出(或者不管它是什麼),它似乎消失了。我看過它進入Items
集合,我看到Count
增加到5,然後當檢索到值時,集合中只有2個項目。
這是怎麼回事?
如果您想了解更多關於我在做什麼,並建議替代的實現,我接受它。我使用這種方式將ELMAH錯誤ID以不受競態條件限制的方式推送到ViewModel中。 (即這是我更換是:只顯示最近的錯誤一個共同的解決辦法),這裏是我的代碼:
的Global.asax
protected void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args) {
ElmahSupplement.CurrentId = args.Entry.Id;
}
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e) {
if (ElmahSupplement.IsNotFound(e.Exception)) {
ElmahSupplement.LogNotFound((e.Context as HttpContext).Request);
e.Dismiss();
}
}
SiteController.cs
public virtual ActionResult Error() {
Response.StatusCode = 500;
return View(MVC.Site.Views.Error, ElmahSupplement.CurrentId);
}
ElmahSupplement.cs
public class ElmahSupplement {
// TODO: This is a rather fragile way to access this info
private static readonly Guid contextId = new Guid("A41A67AA-8966-4205-B6C1-14128A653F21");
public static string CurrentId {
get {
return
// Elmah 1.2 will fail to log when enumerating form values that raise RequestValidationException (angle brackets)
// https://code.google.com/p/elmah/issues/detail?id=217
// So this id could technically be empty here
(HttpContext.Current.Items[contextId] as string);
}
set {
HttpContext.Current.Items[contextId] = value;
}
}
public static void LogNotFound(HttpRequest request) {
var context = RepositoryProxy.Context;
context.NotFoundErrors.Add(new NotFoundError {
RecordedOn = DateTime.UtcNow,
Url = request.Url.ToString(),
ClientAddress = request.UserHostAddress,
Referrer = request.UrlReferrer == null ? "" : request.UrlReferrer.ToString()
});
context.SaveChanges();
}
public static bool IsNotFound(Exception e) {
HttpException he = e as HttpException;
return he != null && he.GetHttpCode() == 404;
}
}
您的假設是錯誤的,ASP.NET MVC不再使用Server.Transfer,因此它的行爲並不像您期望的那樣。而Server.Transfer也不能用於ASP.NET MVC,因爲MVC是在異步管道上重建的。 –
阿卡什,你似乎在做兩個評論,但我理解他們說同樣的話,所以也許我誤解了?另外,雖然我當然相信你,但我並不真正瞭解Server.Transfer的問題。這不是在MVC處理程序的範圍之外執行的嗎?我想最重要的是,如果你有關於如何解決的建議,請做出來。 18小時直到失去+50。 ( – shannon