Ich vermeide die Standard-ASP.NET-Ansatz der Umleitung auf Fehler (wie viele Leute). Sauberer AJAX-Code und SEO gehören zu den Gründen.HttpContext.Current.Items gelöscht über responseMode = "ExecuteURL"?
Allerdings verwende ich die folgende Methode, um es zu tun, und es scheint, dass ich HttpContext.Current.Items
in der Übertragung verlieren kann?
<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>
Ich nahm an, es erfolgt nur eine Server.Transfer()
unter die Decke, die ich Items
verstehen bewahrt. (Siehe: Scope of HttpContext.Current.Items und http://weblog.west-wind.com/posts/2010/Jan/20/HttpContextItems-and-ServerTransferExecute)
Aber ich bin auch etwas in Items
vor dem „ExecuteURL“ Erfassen und Abrufen/es nach der Übertragung ausgibt (oder was auch immer es ist), und es scheint zu verschwinden. Ich habe es in der Items
Sammlung gesehen, sehe ich die Count
Erhöhung auf 5, und wenn der Wert abgerufen wird, gibt es nur 2 Elemente in der Sammlung.
Was ist los?
Wenn Sie mehr darüber verstehen möchten, was ich mache und eine alternative Implementierung empfehlen, ich bin dafür offen. Ich benutze dies, um die ELMAH-Fehler-ID in ein ViewModel auf eine Weise zu übertragen, die frei von Rennbedingungen ist. (. Dh eine gemeinsame Abhilfe für diesen, die ich ersetzt habe, ist die jüngsten Fehler nur Anzeige) Hier ist mein Code:
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;
}
}
Ihre Annahme ist falsch, ASP.NET MVC verwendet nicht länger Server.Transfer und verhält sich daher nicht wie erwartet. Und Server.Transfer funktioniert auch nicht mit ASP.NET MVC, da MVC in einer asynchronen Pipeline neu erstellt wird. –
Akash, du scheinst zwei Kommentare zu machen, aber ich verstehe, dass sie dasselbe sagen, also habe ich vielleicht falsch verstanden? Auch, obwohl ich Ihnen glaube, verstehe ich das Problem mit Server.Transfer nicht wirklich. Wird das nicht außerhalb des MVC-Handlers ausgeführt? Ich denke, vor allem, wenn Sie einen Vorschlag haben, wie Sie ansprechen, machen Sie es bitte. 18 Stunden bis die +50 verloren ist. :( – shannon