【问题标题】:Override WebResource javascript method - WebForm_InitCallback()覆盖 WebResource javascript 方法 - WebForm_InitCallback()
【发布时间】:2015-05-14 09:44:56
【问题描述】:

我被 ASP.NET 中的回调和多选选择控件困住了。正如我所注意到的,微软自 2006 年以来就有一个错误(!),当我对选择为 1、2、3 的多选执行回调时,回发数据为 1、1、1。 我已经确定了问题所在,方法如下:

function WebForm_InitCallback() {
    var formElements = theForm.elements,
        count = formElements.length,
        element;
    for (var i = 0; i < count; i++) {
            element = formElements[i];
            var tagName = element.tagName.toLowerCase();
            if (tagName == "input") {
                var type = element.type;
                if ((__callbackTextTypes.test(type) || ((type == "checkbox" || type == "radio") && element.checked))
                && (element.id != "__EVENTVALIDATION")) {
                    WebForm_InitCallbackAddField(element.name, element.value);
                }
            }
        else if (tagName == "select") {
            var selectCount = element.options.length;
                for (var j = 0; j < selectCount; j++) {
                var selectChild = element.options[j];
                if (selectChild.selected == true) {
                    WebForm_InitCallbackAddField(element.name, element.value);
                }
            }
        }
        else if (tagName == "textarea") {
            WebForm_InitCallbackAddField(element.name, element.value);
        }
    }
}

element.value 没有传递正确的值,但 selectedChild.value 在“选择”标签中。

即使我发现了问题,并且我知道如何覆盖此方法,但我不相信这会奏效。覆盖来自资源的 JavaScript 方法是否正确?你建议我这样做吗?

谢谢。

【问题讨论】:

    标签: javascript c# asp.net callback embedded-resource


    【解决方案1】:

    该代码被 Microsoft 视为遗留代码,除非他们认为这是一个严重问题,否则不会对其进行修复。

    他们的解决方法是在将代码发送到浏览器之前实现一个自定义 http 模块来更正代码。

    1. 创建自定义 http 模块
    2. 实现 ReleaseRequestState 事件
    3. 把下面的代码放在那里:

      void context_ReleaseRequestState(object sender, EventArgs e)
      {
          HttpApplication application = sender as HttpApplication;
      
          if (application != null)
          {
              if (application.Request.Url.ToString().Contains("WebResource.axd"))
              {
                  #region Set private value of HttpWriter so we can write to output stream
                  //See http://daniel-richardson.blogspot.com/2008/11/how-to-apply-filter-to-content-returned.html
                  var response = application.Context.Response;
                  var httpWriterField = typeof(HttpResponse).GetField("_httpWriter",
                                       BindingFlags.NonPublic | BindingFlags.Instance);
                  var ignoringFurtherWritesField = typeof(HttpWriter).GetField("_ignoringFurtherWrites",
                                                   BindingFlags.NonPublic | BindingFlags.Instance);
                  var httpWriter = httpWriterField.GetValue(response);
                  ignoringFurtherWritesField.SetValue(httpWriter, false);
                  #endregion
      
                  //We need to read filter property first or we get exception
                  var f = application.Response.Filter;
      
                  application.Response.Filter = new ResponseFilter(application.Response.OutputStream);
              }
          }
      }
      
    4. 创建继承自 Stream 类的类 ResponseFilter。

    构造函数:

    public ResponseFilter(Stream responseStream)
        {
            ResponseStream = responseStream;
        }
    

    写法:

        public override void Write(byte[] buffer, int offset, int count)
        {
            string output = Encoding.UTF8.GetString(buffer, offset, count);
    
            string fixedOutput = output.Replace(@"if (selectChild.selected == true) {
                    WebForm_InitCallbackAddField(element.name, element.value);", "if (selectChild.selected == true) {WebForm_InitCallbackAddField(element.name, selectChild.value);");
    
            byte[] fixedBuffer = Encoding.UTF8.GetBytes(fixedOutput);
    
    
            ResponseStream.Write(fixedBuffer, 0, fixedBuffer.Length);
        }
    

    - 在实现其他抽象方法时,只需简单地调用 ResponseStream 的方法

    source

    【讨论】:

    • 这是可行的解决方案。谢谢。有些事情,我花了很多时间来解决。如果您的 web.config 中有 ,为了对流进行编码,您需要具有 dynamicCompressionBeforeCache="false"。
    猜你喜欢
    • 2011-10-16
    • 2021-12-25
    • 2021-07-09
    • 2013-09-15
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    相关资源
    最近更新 更多