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

RuS*_*uSh 16 .net c# asp.net iis

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

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

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

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

  1. 这是真的吗?

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


更新:

我有一些进展,我发现当我在字符串上使用Substring方法时,我只会收到此错误.(我正在使用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);
Run Code Online (Sandbox Code Playgroud)

我知道.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!
Run Code Online (Sandbox Code Playgroud)

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

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();
            }
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢!

Las*_*sus 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));
Run Code Online (Sandbox Code Playgroud)