ASP.NET 2中的ISO-8859-1到UTF8

时间:2009-06-18 11:19:13

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

我们有一个页面将数据发布到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

有什么想法吗?

7 个答案:

答案 0 :(得分:7)

你有这行代码: -

String sSentSearchText = postedValues[i];

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

问题是META http-equiv不会告诉服务器有关编码的信息。

您可以在@Page指令中添加RequestEncoding =“ISO-8859-1”并停止尝试自己解码(因为它已经发生)。

这也无济于事。看来你只能在web.config中指定Request encoding。

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

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

答案 1 :(得分:2)

我认为将您的编码添加到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 :(得分:2)

我们遇到了同样的问题。这个话题根本不是直截了当的。

第一个提示是设置发布数据的页面的响应编码(通常与接收.NET中的数据的页面相同)到所需的表单后编码。< / p>

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

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

因此,您可能认为自己很好,但是,在您的页面中,ASP.NET已经将所有参数发送到表单中。因此,当您实际拥有_charset_字段中的值时,.NET中已经错误地解码了包含Merkblätter的字段的值。

您有两种选择:

  1. 在相关的ASP.NET页面中,手动执行请求字符串的解析
  2. 在Application_BeginRequest中,在Global.asax中,手动解析请求参数,提取_charset_字段。获得值后,将Request.ContentEncoding设置为System.Text.Encoding.GetEncoding(<value of _charset_ field>)。如果这样做,您可以像往常一样阅读包含Merkblätter的字段的值,无论客户端将值发送到什么字符集。
  3. 在上述任何一种情况下,您都需要手动阅读Request.InputStream,以获取表单数据。我建议将响应编码设置为UTF-8,以获得接受字符的最大数量的选项,然后在用户重写字符集时处理特殊情况,特别是如上所述。

答案 3 :(得分:1)

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进行检查。在上面的函数和IF解码的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

的确切网址

答案 4 :(得分:0)

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

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

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

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

只是做:

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

  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将按预期返回“Avásárlónemengedélyeztetatranzakciót”。