• 从MS的源代码中分析出来了我的Bug


        近日写一个银行的接口程序,是通过HTTP通讯的。
        我开始选择了System.Net.WebClient的UploadValues来实现,后来发现银行那边用的编码是GB2312,而WebClient似乎是不能指定编码的(.Net1.1和.2.0似乎都是这样),所以通讯是字母和数字的话没有问题,如果通讯是中文的话就出现乱码,导致银行验证数字证书的时候出错。
        走头无路的时候发现.Net2.0还有更低级的HTTP通讯类:WebResponse和WebRequest,所以用这两个类来实现我的目的。结果让我很失望,竟然数字和字母也不能正确发送了。没办法,我自己做了一个调试页面,其实就是把一个空页面设置成<%@ Page ... Trace="true"%>,让我的接口发送数据到这个空页面上,这样可以方便的看到每个Get和Post的字段。
        这个时候看到中文是正常的(也就是说我发送和接受的数据是一致的),英文和数字也都正常,但是“+”传递过程中变成了空格。
        为了这个问题郁闷了很久也没有解决,这时我突然想起来既然WebResponse和WebRequest比WebClient更低级,那么WebResponse会不会是用WebResponse和HttpWebRequest来实现的呢?
        我找来.Net Reflector查看.Net的System.Net.WebClient.UploadValues()源代码如下:
     1public byte[] UploadValues(string address, string method, NameValueCollection data)
     2{
     3      byte[] buffer1;
     4      try
     5      {
     6            this.m_responseHeaders = null;
     7            if (this.m_headers == null)
     8            {
     9                  this.m_headers = new WebHeaderCollection();
    10            }

    11            string text1 = this.m_headers["Content-Type"];
    12            if ((text1 != null&& (string.Compare(text1, "application/x-www-form-urlencoded"true, CultureInfo.InvariantCulture) != 0))
    13            {
    14                  throw new WebException(SR.GetString("net_webclient_ContentType"));
    15            }

    16            this.m_headers["Content-Type"= "application/x-www-form-urlencoded";
    17            WebRequest request1 = WebRequest.Create(this.GetUri(address));
    18            request1.Credentials = this.Credentials;
    19            this.CopyHeadersTo(request1);
    20            request1.Method = method;
    21            using (Stream stream1 = request1.GetRequestStream())
    22            {
    23                  using (StreamWriter writer1 = new StreamWriter(stream1, Encoding.ASCII))
    24                  {
    25                        string text2 = string.Empty;
    26                        foreach (string text3 in data.AllKeys)
    27                        {
    28                              string text4 = text2 + WebClient.UrlEncode(text3) + "=" + WebClient.UrlEncode(data[text3]);
    29                              writer1.Write(text4);
    30                              text2 = "&";
    31                        }

    32                        writer1.Write("\r\n");
    33                  }

    34            }

    35            WebResponse response1 = request1.GetResponse();
    36            this.m_responseHeaders = response1.Headers;
    37            buffer1 = this.ResponseAsBytes(response1);
    38      }

    39      catch (Exception exception1)
    40      {
    41            if (!(exception1 is WebException) && !(exception1 is SecurityException))
    42            {
    43                  throw new WebException(SR.GetString("net_webclient"), exception1);
    44            }

    45            throw;
    46      }

    47      return buffer1;
    48}
    比较我的代码后发现错误在
    string text4 = text2 + WebClient.UrlEncode(text3) + "=" + WebClient.UrlEncode(data[text3]);
    我没有用UrlEncode编码 所以导致加号不能正常传输,所以问题解决。
    另外我想我也找到了为什么System.Net.WebClient.UploadValues()不能指定编码
    很可能跟这个语句有关系
    StreamWriter writer1 = new StreamWriter(stream1, Encoding.ASCII)
    微软在代码里边把编码写死了,这个算不算MS的Bug呢?

  • 相关阅读:
    设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
    数组模拟栈(C语言)
    JDBC数据源连接池的配置和使用实例
    servlet 具体实现
    MySQL查询数据表中数据记录(包括多表查询)
    java开发中的23中设计模式
    eclipse使用和优化配置
    将博客搬至CSDN
    itext poi 学习之旅 (3)读取数据库信息并由excel展现出来
    itext poi 学习之旅 (2)创建excel
  • 原文地址:https://www.cnblogs.com/wormday/p/538509.html
Copyright © 2020-2023  润新知