"Exception" that cannot be caught by try in mvc2.0"

Source: Internet
Author: User

The day before yesterday, when I added a log module to the new project and tested the Log Module, I found that the development staff was very simple.CodeAnd the standard try... catch... method. The code is organized as follows:

  1     Public  Jsonresult savetest ()
2 {
3 Try
4 {
5 // Linqtosql: returned iqueryable data set.
6   VaR iqueryabledata = (From o In _ Context. Orders // . Where (O => O. orderid = 10248)
7 Select New
8 {
9 Shipname = O. shipname,
10 Employee = O. employee,
11 }). Tolist ();
12
13 // LINQ: returns the ienumerable set.
14 VaR ienumerabledata = From d In Iqueryabledata
15 Select New
16 {
17 Shipname = D. shipname,
18 Employeename = D. employee. lastname // Null reference not processedProgramException.
19 };
20
21 Return JSON ( New {Success = True , MSG = Ienumerabledata}, jsonrequestbehavior. allowget );  
22 }
23 Catch (Exception ex)
24 {
25 Return JSON ( New {Success = False , MSG = Ex. Message}, jsonrequestbehavior. allowget );
26 }
27 }

For your convenience, I use the northwind database. At the same time, execute SQL: Update orders set employeeid = NULL where orderid = 10248 in the database. As a result, 18th rows of code above produces an exception during code iteration. Do you think this exception can be caught? Of course, the answer is no!

I was immediately interested when I found this bug. I don't know how Microsoft's MVC project developers would explain it. Next, let me give you an unofficial explanation. Thank you!

We can set the breakpoint in line 18th, and then use the vs2010 debug program. We found that vs did not report any bug when it executed the return JSON command in line 21st. After a few seconds, the breakpoint is directly located in row 18th, and the prompt is very simple: the object is not applied to the instance. This is indeed the expected exception, but it is never caught! Through stacktrace, I found a prompt: At system. Web. MVC. controlleractioninvoker. invokeactionresult (controllercontext, actionresult ). After the code 21st line return JSON is executed, the jsonaction is returned. Is this jsonaction called by invokeactionresult? Is this the key to the problem? The reason is that an exception occurs in the invokeactionresult () function that calls the outer layer of the try catch function (the savetest () function in this example. That is, if an exception occurs to the outer function, how can we try to catch this outer exception in our inner function savetest? So I further confirmed my thoughts through reflector. For details, see:

The execution process of this action. executeresult (controllercontext) is as follows:

In the last figure, javascriptserializer serializer = new javascriptserializer (); During JSON serialization, this outer function reports an exception. This exception cannot be intercepted in the savetest () method of our inner function. At this moment, I have fully understood how this exception cannot be caught! Why is this exception triggered by the outer function?. NetThis is not part of the scope discussed in this article.ArticleThe explanation is clear.

A solution is provided to eliminate the intercepted exception:

Although MVC is very young, but this architecture is really good, we can easily expand it (I am not the support of MVC, haha ). To solve the problem, we only need to customize a feature that inherits the handleerrorattribute feature. Then rewrite the onexception virtual method of the base class. The Code is as follows:

 

Customhandleerrorattribute

     Public    Class  Customhandleerrorattribute: handleerrorattribute
{
Public Override Void Onexception (exceptioncontext context)
{
Base . Onexception (context );
Dynamic ex = Context. exception;
If ( ! Context. exceptionhandled)
Return ;

// Todo: record the ex error object to the System Log Module.
}
}

Then we call the following in the MVC controller:

Call customhandleerror

    /* 
* Invokeactionresult is intercepted to call the executeresult method of the actionresult parameter.
Perform the following operations when executing the executeresult method:
Javascriptserializer serializer = new javascriptserializer ();
Response. Write (serializer. serialize (this. Data ));
Serialize the C # anonymous object into JSON data for callback by jquery Ajax.
*/
[Customhandleerror]
Public Jsonresult savetest ()
{
// Try
// {
// Testmehod ();
// Linqtosql: returned iqueryable data set.
VaR iqueryabledata = (From o In _ Context. Orders // . Where (O => O. orderid = 10248)
Select New
{
Shipname = O. shipname,
Employee = O. employee,
}). Tolist ();

// LINQ: returns the ienumerable set.
VaR ienumerabledata = From d In Iqueryabledata
Select New
{
Shipname = D. shipname,
Employeename = D. employee. lastname // The null reference is not handled, causing an exception that cannot be intercepted.
};

Return JSON ( New {Success = True , MSG = Ienumerabledata}, jsonrequestbehavior. allowget ); // JSON serialization.
// }
// Catch // An error occurs in the outer layer, leading to the failure of the catch function of the inner layer, and an error message cannot be effectively intercepted.
// {
// Return JSON (New {success = false, MSG = "operation failed. "}, Jsonrequestbehavior. allowget );
// }
}

The code looks more concise, right? Even try catch does not need to be written, so you don't have to worry about the appearance of the mysterious character that cannot be captured. This is the end of the nightmare...

Download this sample code here

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.