Enable updatepanel to support file upload (4): Data Transmission and parsing Mechanism

Source: Internet
Author: User

Now we are about to start the most skillful part of the project. If our components need to run properly in a variety of browsers, we must consider how to send and parse data. If we leave this part of the mechanism completely to the original behavior of ASP. NET Ajax for execution, we will encounter problems. The following code snippet is the DOM structure in IFRAME after IE 7 and Firefox receive data from the server:

Dom Structure

Obviously, this code is intended to directly display the data sent by the server on the page. In this case, you can directly obtain this text by using the innerttext attribute (ie 7) or textcontent attribute (Firefox) of the <PRE/> element. Unfortunately, the behavior of IE6 is very strange, which is quite different from that of the first two. IE 6 parses the text according to XML, and then displays the error message naturally, telling us that this text is not a valid XML document. This is unreasonable because response's "Content-Type" is "text/plain" instead of "text/XML ". This is the biggest headache for us to be compatible with multiple browsers.

Do you still remember that the writescriptblock method was called before and after the actual data is output to the customer segment? The following is the implementation of this method:

Writescriptblock method implementation

internal static class AjaxFileUploadUtility{    internal static void WriteScriptBlock(HttpResponse response, bool begin)    {        string scriptBegin =             "<script type='text/javascript' language='javascript'>window.__f__=function(){/*";        string scriptEnd = "*/}</script>";        response.Write(begin ? scriptBegin : scriptEnd);    }}

IE 6 and IE 7 process the text contained in <script/> as a piece of script code. We add the script-defined content on both sides of the real data to make it a comment of the "_ F _" method in the client IFRAME, therefore, we can call the tostring function of this method to obtain the text content of this method. Note that in the renderpagecallback method, we encode the text, replace "*/" with "* // *", and then send it to the client, the purpose of this operation is to make this text a legal compress cirpt code.

Renderpagecallback

StringBuilder sb = new StringBuilder();HtmlTextWriter innerWriter = new HtmlTextWriter(new StringWriter(sb));renderPageCallbackMethodInfo.Invoke(    this.PageRequestManager,     new object[] { innerWriter, pageControl });writer.Write(sb.Replace("*/", "*//*").ToString());

Wait a moment. Here we encode the output text when the asynchronous refresh is running normally, but we did not do this in case of exceptions, didn't we? Yes. In the case of an exception, the error message will be output directly through the write method of response (see the onpageerror method of the pagerequestmanager class). Therefore, we cannot obtain the output result as in the previous code. We can only hope that the "*/" character string will not appear in the error message. (Of course, we can use the reflection mechanism to rewrite the entire logic, but this is complicated ).

Next, we need to re-obtain the text in the _ iframeloadcomplete method of the client:

_ Iframeloadcomplete and _ parsescripttext

_iframeLoadComplete : function(){    //...    try    {            var f = iframe.contentWindow.__f__;        var responseData = f ? this._parseScriptText(f.toString()) :             this._parsePreNode(iframe.contentWindow.document.body.firstChild);                    if (responseData.indexOf("\r\n") < 0 && responseData.indexOf("\n") > 0)        {            responseData = responseData.replace(/\n/g, "\r\n");        }                    this._responseData = responseData;        this._statusCode = 200;        this._responseAvailable = true;    }    catch (e)    {        this._statusCode = 500;        this._responseAvailable = false;    }        // ...},_parseScriptText : function(scriptText){    var indexBegin = scriptText.indexOf("/*") + 2;    var indexEnd = scriptText.lastIndexOf("*/");    var encodedText = scriptText.substring(indexBegin, indexEnd);    return encodedText.replace(/\*\/\/\*/g, "*/");},

Here, we will determine whether the "_ F _" method exists in the IFRAME window object, rather than directly determining the browser type to determine what to do next, this will bring more browser compatibility.

Firefox's behavior is totally different. It still uses the DOM structure we mentioned at the beginning to display the text obtained from the server in IFRAME. This method is reasonable, because the Content-Type of response is "text-plain ". Therefore, we will use another method to obtain this text:

_ Parseprenode method implementation

_parsePreNode : function(preNode){    if (preNode.tagName.toUpperCase() !== "PRE") throw new Error();    return this._parseScriptText(preNode.textContent || preNode.innerText);},

Note that there are several lines of very important code in the _ iframeloadcomplete method:

_ Iframeloadcomplete

if (responseData.indexOf("\r\n") < 0 && responseData.indexOf("\n") > 0){    responseData = responseData.replace(/\n/g, "\r\n");}

Because the script obtained from the server is divided into multiple parts, the format of each part is "length | type | ID | content ", therefore, the length of a string is an important attribute when parsing text. Therefore, we will replace all "\ r" with "\ r \ n" to keep the content and length consistent, otherwise the parsing process will fail. In fact, such replacement only appears in Firefox. (To be continued)

Click here to download the entire project

English version

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.