2012-01-23 33 views
5

Có thể xác định xem yêu cầu hiện tại là một postback không đồng bộ (cập nhật một phần trang) từ bên trong sự kiện Application_Error không?Làm thế nào để xác định xem yêu cầu hiện tại là một postback không đồng bộ, trong sự kiện ASP.NET Application_Error

Cách tốt nhất để xử lý lỗi ứng dụng khi đăng lại không đồng bộ được sử dụng là gì?

Trong ứng dụng_Error, chúng tôi đang chuyển hướng đến các trang lỗi khác nhau nhưng điều đó không hoạt động đúng khi lỗi được đưa ra trong một postback không đồng bộ. Chúng tôi nhận thấy rằng điều này đúng ngay cả khi AllowCustomErrorsRedirect = false và chúng tôi có trình xử lý OnAsyncPostBackError để đặt AsyncPostBackErrorMessage. Trong quá trình postback không đồng bộ, AsyncPostBackErrorMessage của chúng tôi bị ghi đè và máy khách sẽ nhận được lỗi trang web chung.

+0

http://www.codedigest.com/Articles/ASPNETAJAX/115_Error_Handling_in_ASPNet_Ajax_Applications.aspx –

+0

Rất tiếc, chúng tôi đã sử dụng AllowCustomErrorsRedirect = false và cung cấp AsyncPostBackErrorMessage. Vì vậy, tôi không thấy bài viết có liên quan như thế nào. Đã cập nhật câu hỏi để bao gồm việc sử dụng trình xử lý OnAsyncPostBackError. – BlueFox

Trả lời

5

Trong phương thức Application_Error bạn không còn có quyền truy cập trực tiếp vào điều khiển <asp:ScriptManager> trên trang. Vì vậy, đã quá muộn để xử lý sự kiện AsyncPostBackError của nó.

Nếu bạn muốn ngăn chặn chuyển hướng, bạn nên kiểm tra yêu cầu để xem liệu nó có thực sự là một yêu cầu không đồng bộ hay không. Các <asp:UpdatePanel> gây ra một bài trở lại với tiêu đề HTTP sau:

X-MicrosoftAjax:Delta=true 

(also see: ScriptManager Enables AJAX In Your Web Apps)

Một tấm séc cho tiêu đề này sẽ giống như thế này:

HttpRequest request = HttpContext.Current.Request; 
string header = request.Headers["X-MicrosoftAjax"]; 
if(header != null && header == "Delta=true") 
{ 
    // This is an async postback 
} 
else 
{ 
    // Regular request 
} 

Như những gì sẽ là một cách thích hợp để xử lý ngoại lệ là một câu hỏi khác.

+0

Tôi sợ nhìn vào tiêu đề HttpRequest sẽ là giải pháp duy nhất. Tiêu đề đáng tin cậy như thế nào? Ngoài ra, điều này có ảnh hưởng đến việc đăng lại toàn bộ trang (không đồng bộ) không? – BlueFox

+0

Tiêu đề phải khá đáng tin cậy vì nó được sử dụng bởi khung công tác để xác định cách gửi phản hồi. Nó không được can thiệp vào các bài đăng đồng bộ, tiêu đề sẽ không được đặt hoặc đặt thành 'Delta = false' –

+0

FYI - Phương pháp này sáng tạo và đáng tin cậy, nhưng thực tế có thể truy cập ScriptManager từ bên trong Application_Error. Xem câu trả lời của tôi để biết chi tiết. – BrianFinkel

1

Tôi đã có một kịch bản tương tự. Những gì làm việc cho tôi đã gọi Server.ClearError() trong trình xử lý sự kiện của tôi cho AsyncPostBackError của ScriptManager. Điều này ngăn không cho hàm Global.asax Application_Error được gọi.

0

Trong vòng Application_Error, bạn thực sự có thể truy cập ScriptManager để xác định xem yêu cầu hiện tại có phải là một postback không đồng bộ hay không. Đối tượng toàn cục HttpContext.Current.Handler thực sự trỏ đến trang đang được bảo trì, chứa đối tượng ScriptManager, nó sẽ cho bạn biết nếu yêu cầu hiện tại là không đồng bộ.

Tuyên bố sau đây xác minh họa làm thế nào để truy cập vào các đối tượng ScriptManager và nhận được thông tin này:

ScriptManager.GetCurrent(CType(HttpContext.Current.Handler, Page)).IsInAsyncPostBack 

Tất nhiên, tuyên bố rằng sẽ thất bại nếu các yêu cầu hiện tại không phải dành cho một trang, hoặc nếu không có ScriptManager trên trang hiện tại, vì vậy đây là một cặp mạnh mẽ hơn các chức năng bạn có thể sử dụng bên trong Global.asax để làm cho việc xác định:

Private Function GetCurrentScriptManager() As ScriptManager 
    'Attempts to get the script manager for the current page, if there is one 

    'Return nothing if the current request is not for a page 
    If Not TypeOf HttpContext.Current.Handler Is Page Then Return Nothing 

    'Get page 
    Dim p As Page = CType(HttpContext.Current.Handler, Page) 

    'Get ScriptManager (if there is one) 
    Dim sm As ScriptManager = ScriptManager.GetCurrent(p) 

    'Return the script manager (or nothing) 
    Return sm 
End Function 

Private Function IsInAsyncPostback() As Boolean 
    'Returns true if we are currently in an async postback to a page 

    'Get current ScriptManager, if there is one 
    Dim sm As ScriptManager = GetCurrentScriptManager() 

    'Return false if no ScriptManager 
    If sm Is Nothing Then Return False 

    'Otherwise, use value from ScriptManager 
    Return sm.IsInAsyncPostBack 
End Function 

Chỉ cần gọi IsInAsyncPostback() từ bên trong Application_Error để có được một boolean chỉ ra hiện trạng .

Bạn nhận được lỗi ASP.NET chung tại máy khách vì cố gắng chuyển/chuyển hướng yêu cầu async sẽ tạo ra nhiều lỗi hơn, thay thế và do đó làm xáo trộn lỗi ban đầu. Bạn có thể sử dụng mã ở trên để ngăn việc chuyển hoặc chuyển hướng trong các trường hợp như vậy.Cũng lưu ý một khám phá khác mà tôi đã thực hiện: Mặc dù bạn có thể truy cập đối tượng ScriptManager bằng phương pháp này, vì một số lý do thiết lập thuộc tính AsyncPostBackErrorMessage của nó từ bên trong Application_Error không hoạt động. Giá trị mới không được chuyển cho khách hàng. Do đó, bạn sẽ vẫn cần xử lý sự kiện OnAsyncPostBackError của ScriptManager trong lớp trang.

Các vấn đề liên quan