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に記事とコードがあり ます 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 の文字列シリアル化を少し変更したバージョンです。これを 1 つのヘルパー クラスにまとめました。これは、文字列を 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 に答える