ASP.NET - 无法将索引YYY处的Unicode字符XXX转换为指定的代码页

时间:2012-03-19 17:36:47

标签: c# asp.net .net iis

在ASP.NET 4网站上,尝试将数据从数据库加载到GridView时出现以下错误。

无法将索引49处的Unicode字符\ uD83D转换为指定的代码页。

我发现当数据行包含以下内容时会发生这种情况: 文字文字

据我了解,此文本无法转换为有效的utf-8响应。

  1. 这是真的吗?

  2. 有没有办法在将文本加载到gridview之前清理文本以防止出现此类错误?


  3. 更新

    我有一些进步 我发现当我在字符串上使用Substring方法时,我只会收到此错误。 (我正在使用子字符串将部分文本显示为用户预览)。

    例如,在ASP.NET Web窗体中,我执行此操作:

    String txt = test ;
    
    //txt string can also be created by 
    String txt = char.ConvertFromUtf32(116) + char.ConvertFromUtf32(101) +char.ConvertFromUtf32(115) + char.ConvertFromUtf32(116) + char.ConvertFromUtf32(32) + char.ConvertFromUtf32(128148);
    
    // this works ok txt is shown in the webform label.
    Label1.Text = txt; 
    
    //length is equal to 7.
    Label2.Text = txt.Length.ToString();
    
    //causes exception - Unable to translate Unicode character \uD83D at index 5 to specified code page.
    Label3.Text = txt.Substring(0, 6);
    

    我知道.NET字符串是基于支持代理对的utf-16。

    当我使用SubString函数时,我意外地破坏了代理对并导致异常。     我发现我可以使用 StringInfo类

    var si = new System.Globalization.StringInfo(txt);
    var l = si.LengthInTextElements; // length is equal to 6.
    Label3.Text = si.SubstringByTextElements(0, 5); //no exception!
    

    另一种方法是删除代理对:

    Label3.Text = ValidateUtf8(txt).Substring(0, 3); //no exception!
    
        public static string ValidateUtf8(string txt)
                {
                    StringBuilder sbOutput = new StringBuilder();
                    char ch;
    
                    for (int i = 0; i < body.Length; i++)
                    {
                        ch = body[i];
                        if ((ch >= 0x0020 && ch <= 0xD7FF) ||
                                (ch >= 0xE000 && ch <= 0xFFFD) ||
                                ch == 0x0009 ||
                                ch == 0x000A ||
                                ch == 0x000D)
                        {
                            sbOutput.Append(ch);
                        }
    
                    }
                    return sbOutput.ToString();
                }
    

    这真的是代理对的问题吗?

    哪些角色使用代理对?是否有清单?

    我应该继续支持代理对吗?我应该使用StringInfo类还是只删除无效的字符?

    谢谢!

3 个答案:

答案 0 :(得分:21)

您可以尝试首先将文本编码为UTF8(在行绑定事件或类似事件中)。以下代码将以UTF8编码文本并删除不可编码的字符。

private static readonly Encoding Utf8Encoder = Encoding.GetEncoding(
    "UTF-8",
    new EncoderReplacementFallback(string.Empty),
    new DecoderExceptionFallback()
);

var utf8Text = Utf8Encoder.GetString(Utf8Encoder.GetBytes(text));

答案 1 :(得分:0)

字符U+1F60A是Unicode 6.0中引入的表情符号字符。它的UTF-16表示(SQL Server(你没有提到你正在使用的数据库)使用类似的UCS-2)是使用代理字符的0xD83D 0xDE0A。

由于在Oct 2010中发布了Unicode 6.0,我的 guess 是SQL Server,(ASP).Net 4,或者SQL Server数据和.Net数据之间的转换不支持表情符号代码点。

答案 2 :(得分:0)

我刚刚发现Application Request Routing如果安装在IIS 7.5中会强制%2f处理不同,从而导致问题。

删除ARR为我们解决了这个问题。