我避免使用默认的 ASP.NET 重定向错误的方法(正如许多人所做的那样)。干净的 AJAX 代码和 SEO 是其中的原因。
但是,我是用下面的方法来做的,看来我可能会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>
我以为它只是在幕后表演Server.Transfer()
,据我所知保留Items
。(参见:HttpContext.Current.Items 的范围和http://weblog.west-wind.com/posts/2010/Jan/20/HttpContextItems-and-ServerTransferExecute)
但我也在Items
“ExecuteURL”之前捕获了一些东西,并在传输(或任何它是)之后检索/输出它,它似乎消失了。我已经看到它进入Items
集合,我看到Count
提升到 5,然后当检索到值时,集合中只有 2 个项目。
到底是怎么回事?
如果您想更多地了解我在做什么并推荐一个替代实现,我愿意接受。我正在使用它以一种不受竞争条件的方式将 ELMAH 错误 ID 推送到 ViewModel 中。(即,我要替换的常见解决方法是仅显示最近的错误。)这是我的代码:
全球.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();
}
}
站点控制器.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;
}
}