【问题标题】:ISO-8859-1 to UTF8 in ASP.NET 2ASP.NET 2 中的 ISO-8859-1 到 UTF8
【发布时间】:2010-11-03 23:17:00
【问题描述】:

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

<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 时,它作为 Merkblätter 被从 postedValues[i] 中拉出 原始字符串字符串是 Merkbl%ufffdtter

有什么想法吗?

【问题讨论】:

  • 看看我调整后的答案

标签: asp.net encoding utf-8 iso-8859-1


【解决方案1】:

我认为像这样将您的编码添加到 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>

【讨论】:

  • 是的,这是我考虑过的一个选项,但不幸的是,这样做还有其他问题......
【解决方案2】:

这是因为您将字符串编码为 ISO-8859-1 并将其解码,就好像它是编码为 UTF-8 的字符串一样。这肯定会弄乱数据。

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

数据被发送到服务器,根据浏览器指定的编码进行解码并放入 Request.Form 集合中。

您所要做的就是从 Request.Form 集合中读取已经解码的字符串。您也不必遍历集合中的所有项目,因为您已经知道文本框的名称。

只要做:

string sentSearchText = Request.Form("SearchTextBox");

【讨论】:

  • “表单根本没有将数据发布为 ISO-8859-1。”我不认为这是真的,浏览器使用接收到的 HTML 的 Content-Type 标头来确定它将使用什么编码来发布表单的内容。
  • 嗯,如何将表单发布为 ISO-8859-1?感谢您对 Request.Form 内容的评论,这是继承的代码并且它有效,所以我从未考虑修复它..
  • 在form标签中使用accept-charset="ISO-8859-1"来指定编码。
  • @Guffa:问题是帖子已经按照 ISO-8859-1 进行,即使有这个显式的 accept-charset 属性,服务器仍然不知道传入请求的编码是什么.数据作为 application/x-www-form-urlencoded 发送,其中 a) 不携带字符集(因为它的 application/* 数据)和 b.) 唯一合理的值是 US-ASCII,因为那是 url 中使用的编码编码。
  • 这是在 url 解码期间字符八位字节发生的事情,事情变得一团糟。服务器假定一旦解析了 %xx 字节值,该集中每个名称和值的完整字节集将被视为 UTF-8。唯一可以修改此特定服务器行为的地方是 web.config(根据 Canavar,我自己没有检查过)。
【解决方案3】:

你有这行代码:-

String sSentSearchText = postedValues[i];

帖子中的八位字节解码发生在这里。

问题在于 META http-equiv 没有告诉服务器有关编码的信息。

您可以将 RequestEncoding="ISO-8859-1" 添加到 @Page 指令中,然后停止尝试自己摆弄解码(因为它已经发生了)。

这也无济于事。看来只能在 web.config 中指定 Request 编码了。

最好完全停止使用 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"));

您现在可以从其余代码中删除编码标记。

【讨论】:

  • 将输入页面设置为 UTF-8 将是我的理想选择;但是,该表单嵌入在客户站点中,他们似乎不想将编码更改为 UTF-8,因此我正在研究替代方案。为什么要编码这样的废话,如果我有资源,我会很高兴地追捕并与提出这个烂摊子的人严厉地说:-)
  • 在 ASP.NET 中编码不是问题,它非常简单。 不管编码,不要碰它,默认的 UTF-8 可以正常工作
  • 在理想情况下,我会使用 UTF-8,但可惜在这个应用程序中并不那么容易......
【解决方案4】:

我最终做的是强制我们的应用使用 ISO-8859-1。不幸的是,底层数据可能包含不适合该代码页的字符,因此我们在显示数据之前检查数据并将关于 127 字符代码的所有内容转换为实体。不理想但对我们有用...

【讨论】:

    【解决方案5】:

    我遇到了同样的问题,这样解决了:

      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%F3t 将按预期返回“A vásárló nem engedélyezte a tranzakciót”。

    【讨论】:

      【解决方案6】:
      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)并将其插入到您的数据库并附加到应用程序数组对象, ELSE 从应用程序 obj 返回函数。

      这是我找到的最好的方法。 如果有人想了解有关应用程序对象、数据库操作等的更多详细信息,请通过 admin@neoturk.net 联系我

      您可以在 lastiktestleri.com/Home 看到上述方法成功运行

      我也用过,HeliconTech 的 ISAPI_Rewrite Lite 版本 用法很简单: url = Request.ServerVariables("HTTP_X_REWRITE_URL") 这将返回指向 /404.asp 的确切 url

      【讨论】:

        【解决方案7】:

        我们遇到了与您相同的问题。这个话题一点也不直截了当。

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

        但是,这只是提示用户浏览器如何解释从服务器发送的字符。用户可能会选择手动覆盖编码。而且,如果用户覆盖了页面的编码,表单中发送的数据的编码也会改变(无论用户设置的编码是什么)。

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

        所以,您可能认为您可以开始了,但是,当在您的页面中时,ASP.NET 已经对发送到表单的所有参数进行了 urldecode。因此,当您实际上在 _charset_ 字段中有值时,包含 Merkblätter 的字段的值已经被 .NET 错误解码。

        你有两个选择:

        1. 在相关的 ASP.NET 页面中,手动执行请求字符串的解析
        2. 在 Global.asax 中的 Application_BeginRequest 中,手动解析请求参数,提取 _charset_ 字段。获取值后,将Request.ContentEncoding 设置为System.Text.Encoding.GetEncoding(&lt;value of _charset_ field&gt;)。如果这样做,您可以像往常一样读取包含 Merkblätter 的字段的值,无论客户端将值发送到什么字符集。

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

        【讨论】:

        • 为什么 ASP.NET 不自动处理 charset 字段而不让我们编写 Application_BeginRequest 代码?这是charset 的链接。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-19
        • 1970-01-01
        • 2014-01-18
        • 1970-01-01
        • 2016-02-10
        • 2014-08-26
        相关资源
        最近更新 更多