Tôi đã có thể khắc phục sự cố này bằng cách sử dụng thiết lập sau trong biểu mẫu web asp.net sử dụng .NET 3.5.
Mẫu mà tôi đã triển khai bỏ qua giải pháp chuyển hướng tùy chỉnh của .NET trong web.config như tôi đã viết riêng để xử lý tất cả các tình huống với mã trạng thái HTTP chính xác trong tiêu đề.
Đầu tiên, phần customErrors của web.config trông giống như sau:
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" />
Thiết lập này đảm bảo rằng chế độ CustomErrors được bật, một cài đặt chúng tôi sẽ cần sau này và cung cấp tùy chọn all-else-failed cho defaultRedirect của error.htm. Điều này sẽ hữu ích khi tôi không có trình xử lý cho lỗi cụ thể hoặc có điều gì đó dọc theo đường kết nối cơ sở dữ liệu bị hỏng.
Thứ hai, đây là sự kiện Lỗi asax toàn cầu:
protected void Application_Error(object sender, EventArgs e)
{
HandleError();
}
private void HandleError()
{
var exception = Server.GetLastError();
if (exception == null) return;
var baseException = exception.GetBaseException();
bool errorHandled = _applicationErrorHandler.HandleError(baseException);
if (!errorHandled) return;
var lastError = Server.GetLastError();
if (null != lastError && HttpContext.Current.IsCustomErrorEnabled)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(lastError.GetBaseException());
Server.ClearError();
}
}
Mã này đang chuyển trách nhiệm xử lý lỗi cho một lớp khác. Nếu lỗi không được xử lý và CustomErrors được bật, điều đó có nghĩa là chúng tôi gặp phải trường hợp đang sản xuất và bằng cách nào đó, lỗi vẫn chưa được xử lý. Chúng tôi sẽ xóa nó ở đây để ngăn người dùng nhìn thấy nó, nhưng hãy đăng nhập nó vào Elmah để chúng tôi biết chuyện gì đang xảy ra.
Lớp applicationErrorHandler trông như thế này:
public bool HandleError(Exception exception)
{
if (exception == null) return false;
var baseException = exception.GetBaseException();
Elmah.ErrorSignal.FromCurrentContext().Raise(baseException);
if (!HttpContext.Current.IsCustomErrorEnabled) return false;
try
{
var behavior = _responseBehaviorFactory.GetBehavior(exception);
if (behavior != null)
{
behavior.ExecuteRedirect();
return true;
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return false;
}
Về cơ bản, lớp này sử dụng mẫu lệnh để định vị trình xử lý lỗi thích hợp cho loại lỗi được đưa ra. Điều quan trọng là phải sử dụng Exception.GetBaseException () ở cấp độ này, vì hầu hết mọi lỗi sẽ được bao bọc trong một ngoại lệ cấp cao hơn. Ví dụ: thực hiện "ném System.Exception () mới" từ bất kỳ trang aspx nào sẽ dẫn đến việc nhận HttpUnhandledException ở cấp độ này, không phải là System.Exception.
Mã "nhà máy" rất đơn giản và trông giống như sau:
public ResponseBehaviorFactory()
{
_behaviors = new Dictionary<Type, Func<IResponseBehavior>>
{
{typeof(StoreException), () => new Found302StoreResponseBehavior()},
{typeof(HttpUnhandledException), () => new HttpExceptionResponseBehavior()},
{typeof(HttpException), () => new HttpExceptionResponseBehavior()},
{typeof(Exception), () => new Found302DefaultResponseBehavior()}
};
}
public IResponseBehavior GetBehavior(Exception exception)
{
if (exception == null) throw new ArgumentNullException("exception");
Func<IResponseBehavior> behavior;
bool tryGetValue = _behaviors.TryGetValue(exception.GetType(), out behavior);
if (!tryGetValue)
_behaviors.TryGetValue(typeof(Exception), out behavior);
if (behavior == null)
Elmah.ErrorSignal.FromCurrentContext().Raise(
new Exception(
"Danger! No Behavior defined for this Exception, therefore the user might have received a yellow screen of death!",
exception));
return behavior();
}
Cuối cùng, tôi đã có một thiết lập chương trình xử lý lỗi có thể mở rộng. Trong mỗi "hành vi" được xác định, tôi có một triển khai tùy chỉnh cho loại lỗi. Ví dụ: một ngoại lệ Http sẽ được kiểm tra mã trạng thái và xử lý thích hợp. Mã trạng thái 404 sẽ yêu cầu Server.Transfer thay vì Request.Redirect, cùng với mã trạng thái thích hợp được viết trong tiêu đề.
Hi vọng điêu nay co ich.