Summary
ASP. after net Ajax is upgraded from CTP to Beta, a very common problem (I have heard more than 50 complaints) is: when the client calls the web method to obtain the datatable, "A circular reference was detected while serializing an object of Type 'System. reflection. module '. "exception information.
This article analyzes the causes of this exception and provides corresponding solutions, including exception reproduction, causes, solutions, and examples.CodeDownload.
Exception Reproduction
Let's use a simple example first.ProgramReproduce the exception and modify and solve the problem based on the sample program.
First, declare a scriptmanager control on the page. The previewscript. js script needs to be introduced because of the definition of the client datatable and the value-add package:
< ASP : Scriptmanager ID = "Scriptmanager1" Runat = "Server" > < Scripts > < ASP : Scriptreference Assembly = "Microsoft. Web. Preview" Name = "Microsoft. Web. Resources. scriptlibrary. previewscript. js" /> </ Scripts > </ ASP : Scriptmanager >
Next, declare an HTML button and an HTML <div> to call the web method and display the returned datatable:
<Input id ="Btngetdatatable"Type ="Button"Value="Get datatable"Onclick ="Return btngetdatatable_onclick ()"/> <Div id ="Result"> </Div>
In the code above, click the button to call a client JavaScript function named btngetdatatable_onclick (), which is as follows:
FunctionBtngetdatatable_onclick () {pagemethods. getdatatable (cb_getdatatable );}
As you can see, pagemethods. getdatatable () is the client proxy for the web method named getdatatable () on the server. The getdatatable () method on the server side is defined as follows. Note that this method must be static and [system. web. services. webmethod] and [Microsoft. web. script. services. scriptmethod] Two attributes are modified:
[System. Web. Services. webmethod] [microsoft. Web. Script. Services. scriptmethod] Public Static Datatable getdatatable () {datatable mydatatable = New Datatable (); mydatatable. Columns. Add ( New Datacolumn (" ID ", Typeof (Int ); Mydatatable. Columns. Add ( New Datacolumn (" Name ", Typeof ( String ))); For ( Int I = 0; I <10; ++ I) {datarow newrow = mydatatable. newrow (); newrow [" ID "] = I; newrow [" Name "] = String . Format (" Name {0} ", I); mydatatable. Rows. Add (newrow );}Return Mydatatable ;}
The code above is very simple, that is, a able containing two columns (ID and name) is created, and 10 rows of data are filled with the datatable.
Let's return to the Javascript section of the client. We noticed that when calling pagemethods. getdatatable (), we specified a callback function named cb_getdatatable (). The JavaScript function is defined as follows:
function cb_getdatatable (result) { var contentbuilder = New sys. stringbuilder (); for ( var I = 0; I
id :"); contentbuilder. append (result. getrow (I ). getproperty ("
id "); contentbuilder. append ("
name : "); contentbuilder. append (result. getrow (I ). getproperty ("
name "); contentbuilder. append ("
") ;}$ get ("
result "). innerhtml = contentbuilder.
tostring () ;}
The preceding callback function simply formats the returned able (result parameter) and outputs it to the <div> with the ID as result. Note that the SYS. stringbuilder class is used to improve the efficiency of String concatenation, and the $ get () method added in Beta is used to obtain a DOM element based on the ID.
This completes the program. We expect that the client will be able to correctly parse the datatable returned by the server and display it on the page. Run the sample program and click the button on the page. "A circular reference was detected while serializing an object of Type 'System. reflection. module '. "exception information" appears as we wish.
Cause of exception
The cause of the exception is also very simple: the server-side able contains several datarow, and datarow also contains references to the datatable, which will naturally cause cyclic reference. This is exactly what we see in the exception information.
Solution Step 1: modify web. config
After learning the cause, the solution becomes clearer: The JSON serialization component of the custom datatable. However, the value-add component of ASP. NET Ajax has provided us with this component, namely Microsoft. Web. Preview. Script. serialization. converters. datatableconverter. There is no need to re-invent the wheel.
Open the Web. config file and add the following code in <Microsoft. Web >\< scripting >\< WebServices>:
< Jsonserialization Maxjsonlength = "500000000" > < Converters > < Add Name = "Datatableconverter" Type = "Microsoft. Web. Preview. Script. serialization. converters. datatableconverter" /> </ Converters > </ Jsonserialization >
In this way, the datatableconverter in the value-add of ASP. net ajax can be used to serialize the datatable.
If everything is normal, that would be enough. The following error message is returned when you run the program again with joy and click the button:
What's going on? Move the cursor over the result and show a pile of messy things ...... This is not a datatable! What is it?
Solution Step 2: Customize JavaScript helper functions
The reason we see this mess is that the datatableconverter in value-add has a bug (this bug is too fatal ......), A redundant Terminator is added at the end of the serialized JSON string.
After understanding the cause of the error, the solution is also very simple: compile a custom JavaScript helper function and parse the wrong able to the correct one:
FunctionParsebetadatatable (TBL ){Eval('VaRTblrows = '+ TBL. dataarray. Slice (0, TBL. dataarray.Length-1) + ';'); TBL =NewSYS. Preview. Data. able (TBL. columns, tblrows );ReturnTBL ;}
Then, call this helper function in cb_getable able (result). Pay attention to the modification in the first line:
Function Cb_getdatatable (result) {result = parsebetadatatable (result ); VaR Contentbuilder = New SYS. stringbuilder (); For ( VaR I = 0; I <result. get_length (); ++ I) {contentbuilder. append (" <Strong> id </strong>: "); Contentbuilder. append (result. getrow (I). getproperty (" ID "); Contentbuilder. append (" <Strong> name </strong>: "); Contentbuilder. append (result. getrow (I). getproperty (" Name "); Contentbuilder. append (" <Br/> ");} $ Get (" Result "). Innerhtml = contentbuilder. Tostring ();}
After a great deal of hard work, we finally achieved success!
Example program after completion
Run the page again and click the button to get the correct running result as we wish. Is it a sense of accomplishment?
Download Sample Code
Download the sample program in this article: aspnetajaxdatatable.zip
References
- Http://forums.asp.net/thread/1442553.aspx
- Http://forums.asp.net/thread/1251349.aspx
Write as you want
- WriteArticleBe careful and do the same for everything. It is easy to say two words seriously.
- Writing articles should be based on the user's perspective and commercial thinking. How to make readers interested, liked, read, and comment ...... This is a learning.
- It takes one hour to study and solve the problem, and one hour to write.
- There are too many bugs in Windows Live writer, and the writing process is shut down three times abnormally. Fortunately, there are backups and there is no big loss.
(PS: This article selects the self-selected Atlas Book II, of which volume I will be published in next January. I hope you can support it .)