Existing Problems and Solutions: transfer the datatable from the client to the server in ASP. NET Ajax

Source: Internet
Author: User

Summary

In "Existing Problems and Solutions: Get the server-side datatable on the ASP. NET Ajax client ",Article. Net Ajax.Program. Jeffrey Zhao was more intelligent about this, fundamentally solving the problem of transferring datatable from the server to the client.

However, this only solves half of the problem. Sending a able from the client to the server is still not feasible, which is more serious than the previous one. This article analyzes the causes and provides solutions.

This article includes the following content:

    1. Exception reproduction-first exception: stack overflow caused by cyclic reference during JSON serialization on the client
    2. Solve the first exception-destroy the circular reference
    3. Exception replay-the second exception: the deserialize () method on the server throws an exception.
    4. Solve the second exception-simple deserialize () method
    5. Example program after completion
    6. ExampleCodeDownload
    7. References

 

Exception reproduction-first exception: stack overflow caused by cyclic reference during JSON serialization on the client

The following describes the existing problems and solutions: getting the server-side datatable on the ASP. NET Ajax client. If you have not read the sample program, familiarize yourself with the sample program. In this article, we can get a datatable on the client. The callback function of the client is as follows:

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 ();}

The result is the client datatable. Let's define a global datatable outside the function and keep the datatable first:

 
VaRM_mydatatable =Null;

Modify the callback function to keep the result in m_myable able:

 
FunctionCb_getdatatable (result) {result = parsebetadatatable (result); m_mydatatable = result;VaRContentbuilder =NewSYS. stringbuilder ();//......}

Then add a button to the page:

 
<Input ID="Btnsenddatatable" Type="Button" Value="Send datatable" Onclick="Return btnsenddatatable_onclick ()" />

The event handler function specified in onclick is defined as follows:

 
FunctionBtnsenddatatable_onclick () {pagemethods. senddatatable (m_mydatatable, cb_senddatatable );}

We can see that pagemethods. senddatatable () is the client proxy for the web method named senddatatable () on the server. We send the previously saved datatable (m_mydatatable) back to the server. The senddatatable () 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 VoidSenddatatable (datatable mydatatable ){// Do anything you like. Save it to database or XML file, etc.}

We didn't do anything in the example program. In the specific application, you can do whatever you like. We only need to ensure that the datatable can be sent in the past.

Return to the Javascript section of the client. We noticed that when calling pagemethods. senddatatable (), we specified a callback function named cb_senddatatable (). The JavaScript function is defined as follows:

 
FunctionCb_senddatatable (result ){Debugger;}

Nothing to mention. As long as the callback function can be successfully executed, that is, the debugger is hit, we will be successful!

This completes the sample program, runs it, and click "Get able". The interface shown in is displayed. If an exception occurs, see the article "Existing Problems and Solutions: Get the server-side datatable on the ASP. NET Ajax client" for correction.

Then, click "Send datatable" to send the datatable back to the server ................................................ After a long wait and no response from the browser, an out of stack space exception is thrown:

The call stack in the upper-right corner shows that the same function has been called for countless times-a circular reference problem occurs obviously.

Let's add a breakpoint in btnsenddatatable_onclick () to see what the client's datatable is. For more information about debugging JavaScript, see my article.

As shown in, test m_mydatatable. _ rows [0]. _ owner = m_mydatatable in immediate window and return true. It indicates that there is a circular reference: The _ owner attribute of each row object in the client's datatable is referenced back to the datatable itself, which causes the client to perform continuous serialization, until the stack overflows.

 

Solve the first exception-destroy the circular reference

The _ owner attribute of the row object of the client able does not seem useful when it is returned to the server. So the best way to solve this circular reference problem is to clear the _ owner attribute of each row object before sending the client's datatable back to the server.

Compile an auxiliary function preparesendingdatatable (), accept a client datatable, and return a datatable that destroys the circular reference:

 
FunctionPreparesendingdatatable (datatable ){For(VaRI = 0; I <datatable. get_length (); ++ I) {datatable. _ rows [I]. _ owner =Null;}ReturnDatatable ;}

Modify btnsenddatatable_onclick (), call the Helper function, and then send:

 
FunctionBtnsenddatatable_onclick (){VaRMydatatable = preparesendingdatatable (m_mydatatable); pagemethods. senddatatable (mydatatable, cb_senddatatable );}

In this case, the first exception is that the client's JSON serialization occurs when cyclic reference causes stack overflow!

 

Exception replay-the second exception: the deserialize () method on the server throws an exception.

Don't be too happy-run the sample program again and click "Get able" and "Send datatable. The following error is returned:

Open fiddler and you will see the following exception details:

Still "system. notsupportedexception" exception ......

Through some means, we can know ASP. net Ajax comes with Microsoft. web. preview. script. serialization. converters. datatableconverter does not implement the deserialize () method at all. This method only throws system. notsupportedexception exception ......

It seems speechless, right? However, ASP. NET Ajax has its own considerations. After all, datatable is a very complex object. The relationship information, such as row, column, data type, update, and delete, is complex. Implementing this deserialize () method is indeed a huge project.

 

Solve the second exception-simple deserialize () method

If you have any problems, you cannot escape them. Here I simply implemented the deserialize () method of a datatable, which ignores too many complicated things. You just created the most basic and most basic datatable. You can make improvements based on this:

 Using System; Using System. Data;Using System. configuration; Using System. Collections. Generic; Using System. Web; Using System. Web. Security; Using System. Web. UI; Using System. Web. UI. webcontrols; Using System. Web. UI. webcontrols. webparts; Using System. Web. UI. htmlcontrols; Namespace Dflying. Atlas { /// <Summary>     /// Simple implementation of datatable converter-deserialize () method.      /// </Summary>      Public   Class Datatableconverter: Microsoft. Web. Preview. Script. serialization. converters. datatableconverter { Public   Override   Object Deserialize (idictionary < String , Object > Dictionary, type T, Microsoft. Web. Script. serialization. javascriptserializer serializer ){ // There's no rows in the datatable, return null object. Array rowdicts = (Dictionary [" _ Array "] As Array ); If (Rowdicts. Length = 0 ){ Return   Null ;} Datatable mydatatable = New Datatable (); // Get column info              Foreach ( String Colkey In (Rowdicts. getvalue (0) As Idictionary <String , Object >). Keys) {mydatatable. Columns. Add (colkey );} // Create and Add rows to the datatable              Foreach ( Object Rowobj In Rowdicts) {idictionary < String , Object > Rowdict = rowobj As Idictionary < String , Object >; Datarow newrow = mydatatable. newrow (); Foreach (Datacolumn Column In Mydatatable. columns) {newrow [column. columnname] = rowdict [column. columnname];} mydatatable. Rows. Add (newrow );} // Done!              Return Mydatatable ;}}}

The comment is very detailed. If you cannot fully understand it, please refer to a series of brilliant in-depth articles by Jeffrey Zhao. If you only want to use it, it doesn't matter.

Place it in the app_code directory, modify web. config, and use our own ableableconverter:

    jsonserialization   maxjsonlength  = " 500000000 " >    converters  >   Add   name  = " datatableconverter "  type  = " dflying. atlas. datatableconverter " />     converters  >   jsonserialization  > 

After a great deal of hard work, we finally achieved success!

 

Example program after completion

Add a breakpoint to the public static void senddatatable (datatable mydatatable), run the sample program again, and click "Get datatable" and "Send datatable. As we wish, the server obtains the correct datatable:

Next, the debugger in the client callback function is also successfully hit. Finally ......

 

Download Sample Code

Download the sample program in this article: aspnetajaxdatatable_send.zip

 

References

    1. Http://forums.asp.net/thread/1442553.aspx
    2. Http://forums.asp.net/thread/1251349.aspx
    3. In-depth Atlas series: comprehensive example (1)-obtain the specific client type directly when calling the server Method
    4. In-depth Atlas series: Web Sevices access in Atlas example (7)-write javascriptconverter to process types with cyclic references

 

Write as you want

    1. there are a lot of content in this article, and it is difficult to solve the problem
    2. ASP. NET Ajax still takes a long time to complete.
    3. Windows Live writer has many bugs that cannot be tolerated !!
    4. the problem analysis method is always the most important
    5. stomachache ............
Related Article

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.