代码之家  ›  专栏  ›  技术社区  ›  Gordon Thompson

iso-8859-1到utf8 in ASP.NET 2

  •  3
  • Gordon Thompson  · 技术社区  · 15 年前

    我们有一个页面可以将数据发布到我们的ASP.NET应用程序的ISO-8859-1中。

    <head>
        <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
        <title>`Sample Search Invoker`</title>
    </head>
    <body>
    
    <form name="advancedform" method="post" action="SearchResults.aspx">
        <input class="field" name="SearchTextBox" type="text" />
        <input class="button" name="search" type="submit" value="Search &gt;" />
    </form>
    

    以及代码隐藏(searchresults.aspx.cs)

    System.Collections.Specialized.NameValueCollection postedValues = Request.Form;
    String nextKey;
    for (int i = 0; i < postedValues.AllKeys.Length; i++)
    {
        nextKey = postedValues.AllKeys[i];
    
        if (nextKey.Substring(0, 2) != "__")
        {
            // Get basic search text
            if (nextKey.EndsWith(XAEConstants.CONTROL_SearchTextBox))
            {
                // Get search text value
                String sSentSearchText = postedValues[i];
    
                System.Text.Encoding iso88591 = System.Text.Encoding.GetEncoding("iso-8859-1");
                System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
    
                byte[] abInput = iso88591.GetBytes(sSentSearchText);
    
                sSentSearchText = utf8.GetString(System.Text.Encoding.Convert(iso88591, utf8, abInput));
    
                this.SearchText = sSentSearchText.Replace('<', ' ').Replace('>',' ');
                this.PreviousSearchText.Value = this.SearchText;
            }
        }
    }
    

    当我们通过merkbl_tter时,它会从postedvalues[i]中提取出来,作为merkbl_?/tter 原始字符串是merkbl%ufffdtter

    有什么想法吗?

    7 回复  |  直到 14 年前
        1
  •  7
  •   AnthonyWJones    15 年前

    你有这行代码:

    String sSentSearchText = postedValues[i];
    

    《邮报》中的八位位组译码就发生在这里。

    问题是meta-http-equiv没有告诉服务器有关编码的信息。

    您只需将requestencoding=“iso-8859-1”添加到@page指令中,就可以停止自己乱弄解码了(因为它已经发生了)。

    这也没用。似乎您只能在web.config中指定请求编码。

    最好是完全停止使用ISO-8859-1,并将其保留为默认的UTF-8编码。我看不到任何收获,只有使用限制性编码时才会感到痛苦。

    编辑

    如果改变发布表单编码似乎是不可能的,那么我们似乎除了自己处理解码之外别无选择。为此,在接收代码中包含这两个静态方法:

    private static NameValueCollection GetEncodedForm(System.IO.Stream stream, Encoding encoding)
    {
        System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.ASCII);
        return GetEncodedForm(reader.ReadToEnd(), encoding);
    }
    
    
    private static NameValueCollection GetEncodedForm(string urlEncoded, Encoding encoding)
    {
        NameValueCollection form = new NameValueCollection();
        string[] pairs = urlEncoded.Split("&".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
    
        foreach (string pair in pairs)
        {
            string[] pairItems = pair.Split("=".ToCharArray(), 2, StringSplitOptions.RemoveEmptyEntries);
            string name = HttpUtility.UrlDecode(pairItems[0], encoding);
            string value = (pairItems.Length > 1) ? HttpUtility.UrlDecode(pairItems[1], encoding) : null;
            form.Add(name, value);
        }
        return form;
    }
    

    现在不要分配:

    postedValues = Request.Form;
    

    用途:

    postValues = GetEncodedForm(Request.InputStream, Encoding.GetEncoding("ISO-8859-1"));
    

    现在可以从其余代码中删除编码mararky。

        2
  •  2
  •   Canavar    15 年前

    我认为像这样将您的编码添加到web.config中可能会解决您的问题:

    <configuration>
       <system.web>
          <globalization
               fileEncoding="iso-8859-1"
               requestEncoding="iso-8859-1"
               responseEncoding="iso-8859-1"
               culture="en-US"
               uiCulture="en-US"
            />
       </system.web>
    </configuration>
    
        3
  •  2
  •   Erik A. Brandstadmoen    14 年前

    我们和你有同样的问题。这个话题一点也不直截了当。

    第一个技巧是设置 响应 将数据(通常与在.NET中接收数据的页面相同)发布到所需表单的页面编码。

    但是,这只是向用户的浏览器提示如何解释从服务器发送的字符。用户可以选择手动重写编码。而且,如果用户重写了页面的编码,那么以表单形式发送的数据的编码也会更改(更改为用户已将编码设置为的内容)。

    不过,有一个小把戏。如果使用名称添加隐藏字段 _charset_ (注意下划线)在您的表单中,大多数浏览器都会用发布表单时使用的字符集名称填写此表单字段。此表单字段也是HTML5规范的一部分。

    所以,您可能会认为自己很好去做,但是,在您的页面中,ASP.NET已经对发送到表单中的所有参数进行了urledcoded。所以当你在 查尔塞特 字段,包含 默克尔 已被.NET错误地解码。

    您有两种选择:

    1. 在有问题的ASP.NET页中,手动执行请求字符串的分析
    2. 在application ou beginrequest中,在global.asax中,手动分析请求参数,提取 查尔塞特 字段。当你得到这个值时,设置 Request.ContentEncoding System.Text.Encoding.GetEncoding(<value of _charset_ field>) . 如果这样做,则可以读取包含 默克尔 和往常一样,无论客户机发送的值是什么字符集。

    在上述任何一种情况下,您都需要手动读取 Request.InputStream ,以获取表单数据。我建议将响应编码设置为utf-8,以获得您接受的字符数最多的选项,然后在用户特别重写字符集时处理特殊情况,如上所述。

        4
  •  1
  •   neoturk.net    15 年前
    Function urlDecode(input)
     inp = Replace(input,"/","%2F")
     set conn = Server.CreateObject("MSXML2.ServerXMLHTTP")
     conn.setOption(2) = SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS
     conn.open "GET", "http://www.neoturk.net/urldecode.asp?url=" & inp, False
     conn.send ""
     urlDecode = conn.ResponseText
    End Function
    

    要加快速度,只需在数据库上为解码和编码的URL创建一个表,然后在global.asa application.on_start部分读取它们。然后将它们放到应用程序对象上。 然后对该应用程序obj执行检查过程。在上述函数中,如果应用程序数组中不存在解码的URL,则从远程页请求一次(提示:urldecode.asp应位于不同的服务器上,请参见: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316451 )然后将它插入到数据库中并附加到应用程序数组对象,否则将从应用程序对象返回函数。

    这是我发现的最好的方法。 如果有人想进一步了解应用程序对象、数据库操作等,请通过admin@neoturk.net与我联系。

    您可以在:lastiktestleri.com/home上看到上述方法成功工作。

    我也用过,Helicontech的isapi重写Lite版本 用法很简单:url=request.servervariables(“http_x_rewrite_url”)。 这将返回指向/404.asp的确切URL。

        5
  •  0
  •   Guffa    15 年前

    这是因为您将字符串编码为iso-8859-1,并将其解码为一个编码为utf-8的字符串。这肯定会弄乱数据。

    表单不会以ISO-8859-1的形式发布数据,因为您使用该编码发送页面。您尚未为表单数据指定任何编码,因此浏览器将选择能够处理表单中数据的编码。它可以选择ISO-8859-1,但也可以选择其他编码。

    数据将发送到服务器,在服务器上对其进行解码并放入请求。表单集合,根据浏览器指定的编码。

    您只需读取已从request.form集合中解码的字符串。您也不必遍历集合中的所有项,因为您已经知道文本框的名称。

    只做:

    string sentSearchText = Request.Form("SearchTextBox");
    
        6
  •  0
  •   Gordon Thompson    15 年前

    我最终做的是强迫我们的应用程序使用ISO-8859-1。不幸的是,基础数据可能包含不适合该代码页的字符,因此我们在显示数据之前先浏览数据,然后将127字符代码的所有内容转换为实体。不理想,但对我们有用…

        7
  •  0
  •   balint    15 年前

    我也有同样的问题,像这样解决了:

      System.Text.Encoding iso_8859_2 = System.Text.Encoding.GetEncoding("ISO-8859-2");
      System.Text.Encoding utf_8 = System.Text.Encoding.UTF8;
    
      NameValueCollection n = HttpUtility.ParseQueryString("RT=A+v%E1s%E1rl%F3+nem+enged%E9lyezte+a+tranzakci%F3t", iso_8859_2);
      Response.Write(n["RT"]);
    

    a+v%e1s%e1rl%f3+nem+enged%e9lyezte+a+tranzakci%f3 t将按预期返回“a v_s_3 nem enged_)lyezte a tranzakci_3 t”。