2

我正在使用 JSON.Net 和 JsonConvert.DeserializeObject 函数将 json 加载到对象中。通常 json 使用转义字符串会导致 DeserializeObject 失败。一些逃脱是:

\' \u0027 允许在字符文字中输入',例如'\''

\" \u0022 允许在字符串文字中输入 ",例如“这是双引号 (\") 字符”

\ \u005c 允许在字符或字符串文字中输入 \ 字符,例如 '\' 或“这是反斜杠 (\) 字符”

\0 \u0000 允许输入代码为 0 的字符

\a \u0007 警报(通常是硬件哔声)

\b \u0008 退格

\f \u000c 换页(下一页)

\n \u000a 换行(下一行)

\r \u000d 回车(移动到行首)

\t \u0009(水平-)制表符

\v \u000b 垂直制表符

在http://www.codeproject.com/Articles/371232/Escaping-in-Csharp-characters-strings-string-forma有一篇文章和代码 可能不需要一些转义码,例如 /r /n,因为 C# 会了解他们。

是否有在 json 文件中转义这些转义码的最佳实践?我想在将数据传递给 DeserializeObject 之前创建一个完整的类来处理数据。

任何人的任何想法?对于了解 json.net 和 regex 的人来说很容易理解。

4

1 回答 1

1

如果我理解正确,您希望将 json 转义序列转换回 C# 转义序列。

如果是这样,您应该能够简单地搜索 json 转义并将其替换为实际的 C# 转义:

var test = value.Replace(@"\u0085","\u0085");

我想从理论上讲,您可以反转 Json.Net 的实用函数ToEscapedJavaScriptString()以从 json 转义到 C# 转义。

以下代码是我使用在 codeplex 上找到的代码编写的 Json.Net 字符串序列化的略微修改版本。我将它合并到一个助手类中。这就是他们将字符串从 C# 转换为 json 的方式,所以也许它会有所帮助。

// Copyright (c) 2007 James Newton-King    
namespace Demo
    {
        using System.Globalization;
        using System.IO;
        using System.Text;

        public class JsonHelper
        {
            public static string ToJson(string value, char delimiter = '"', bool appendDelimiters = true)
            {
                if (string.IsNullOrEmpty(value))
                    return value;

                StringBuilder sb = new StringBuilder(value.Length);
                using (StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture))
                {
                    WriteEscapedString(sw, value, delimiter, appendDelimiters);
                    return sw.ToString();
                }
            }

            private static void WriteEscapedString(TextWriter writer, string s, char delimiter, bool appendDelimiters)
            {
                // leading delimiter
                if (appendDelimiters)
                    writer.Write(delimiter);

                if (s != null)
                {
                    char[] chars = null;
                    int lastWritePosition = 0;

                    for (int i = 0; i < s.Length; i++)
                    {
                        var c = s[i];

                        // don't escape standard text/numbers except '\' and the text delimiter
                        if (c >= ' ' && c < 128 && c != '\\' && c != delimiter)
                            continue;

                        string escapedValue;

                        switch (c)
                        {
                            case '\t': escapedValue = @"\t"; break;
                            case '\n': escapedValue = @"\n"; break;
                            case '\r': escapedValue = @"\r"; break;
                            case '\f': escapedValue = @"\f"; break;
                            case '\b': escapedValue = @"\b"; break;
                            case '\\': escapedValue = @"\\"; break;
                            case '\u0085': escapedValue = @"\u0085"; break; // Next Line
                            case '\u2028': escapedValue = @"\u2028"; break; // Line Separator
                            case '\u2029': escapedValue = @"\u2029"; break; // Paragraph Separator
                            case '\'': escapedValue = @"\'"; break;
                            case '"': escapedValue = "\\\""; break;
                            default: escapedValue = (c <= '\u001f') ? ToUnicode(c) : null; break;
                        }

                        if (escapedValue == null)
                            continue;

                        if (i > lastWritePosition)
                        {
                            if (chars == null)
                                chars = s.ToCharArray();

                            // write unchanged chars before writing escaped text
                            writer.Write(chars, lastWritePosition, i - lastWritePosition);
                        }

                        lastWritePosition = i + 1;
                        writer.Write(escapedValue);
                    }

                    if (lastWritePosition == 0)
                        // no escaped text, write entire string
                        writer.Write(s);
                    else
                    {
                        if (chars == null)
                            chars = s.ToCharArray();

                        // write remaining text
                        writer.Write(chars, lastWritePosition, s.Length - lastWritePosition);
                    }
                }

                // trailing delimiter
                if (appendDelimiters)
                    writer.Write(delimiter);
            }

            private static string ToUnicode(char c)
            {
                char h1 = ToHex((c >> 12) & '\x000f');
                char h2 = ToHex((c >> 8) & '\x000f');
                char h3 = ToHex((c >> 4) & '\x000f');
                char h4 = ToHex(c & '\x000f');

                return new string(new[] { '\\', 'u', h1, h2, h3, h4 });
            }

            private static char ToHex(int n)
            {
                if (n <= 9)
                    return (char)(n + 48);
                return 
                    (char)((n - 10) + 97);
            }

        }
    }
于 2013-03-08T19:39:49.133 回答