ASP教程 PHP教程 JSP教程 CGI教程 XML教程
  • ASP.NET教程
  • JAVA教程
    当前位置:教程 > 程序设计 > ASP.NET教程 > 正文

    让UpdatePanel支持文件上传(4):数据传输与解析机制

    编辑:教程网 来源:网络 时间:2011年11月03日 15:40
    现在就要开始整个项目中最有技巧的部分了。如果我们的组件需要在多种浏览器中正常的运行,我们必须好好考虑一下发送和解析数据的方式。如果我们把这部分的机制完全交给ASP.NET AJAX原有的行为来执行,则会遇到问题。下面的代码片断就是IE 7和FireFox在收到服务器端的数据之后,iframe中的DOM结构:

    DOM结构
    <html><head></head><body><pre>33|updatePanel|ctl00_Main_UpdatePanel1|...</pre></body></html>


      很显然,这段代码的意图是为了在页面中直接显示服务器端发送过来的数据。在这种情况下,我们就可以通过“<pre />”元素的innertText属性(IE 7)或者textContent属性(FireFox)来直接获得这段文字。不幸的是,IE6的行为非常奇怪,与前两者可谓大相径庭。IE 6会把这段文字按照XML来解析,接着很自然的显示出错误信息,告诉我们这段文本不是一个有效的XML文档。这非常不合理,因为Response的“Content-Type”是“text/plain”而不是“text/xml”。这是我们要兼容多个浏览器时最头疼的情况。

      还记得我们在向客户段输出真实的数据前后都调用了WriteScriptBlock方法吗?下面就是这个方法的实现:

    WriteScriptBlock方法实现
    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和IE 7会将使用<script />来包含的文本作为一段脚本代码来处理。我们这里在真实的数据两边加上了脚本定义的内容,使它成为了客户端iframe中“__f__”方法的一段注释,因此我们可以通过调用这个方法的toString函数来获得这个方法的文本内容。请注意在RenderPageCallback方法中,我们把文本进行了编码,将“*/”替换为“*//*”,然后再将其发送到客户端,这么做的目的是使这段文本能够成为合法的JavaScirpt代码。

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


      等一下,我们在这里把异步刷新运行正常时输出的文本进行了编码,但是我们在异常情况下的输出并没有这么做,不是吗?没错。因为在异常状况下,错误信息会通过Response的Write方法直接输出(请看PageRequestManager类的OnPageError方法),因此我们无法向前面的代码那样获得它输出的结果。我们现在只能希望错误信息中不要出现“*/”这样的字符串吧(当然,我们可以使用反射机制来重写整个逻辑,但是这样做实在比较复杂)。

      下面,我们就要在客户端的_iframeLoadComplete方法中重新获取这段文本了:

    _iframeLoadComplete与_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)
  • 原文来自 教程网 转载请注明:http://www.websmill.com/chengxu/aspnet/31051.html

  • 上一篇:基于TCP的网络游戏黑白棋系列(二):数据传输
  • 下一篇:在Sql Server2000的建表过程中碰到的外键、触发器方面的问题