2011-01-18 14 views
16

優れたJson.Netライブラリを使用して、エンティティフレームワークによって生成されたエンティティをシリアル化しています。私はそうするために、次のコードを使用します。エンティティを直列化するときにJson.Netの予期しない文字( "")が返される

using (MyVoucherEntities context = new MyVoucherEntities()) 
{ 
    List<MyObject> list = context.MyObjects.ToList(); 
    string json = JsonConvert.SerializeObject(list); 
} 

すべてがうまく、私はオブジェクトが正しく1つのシンクタンク除いシリアル化され、意味行く:それは「\」文字をエスケープ追加することには、クライアント側で逆シリアル化するとき、私は悪夢を持つことができます。

[ 
    { 
     \"$id\": \"1\", 
     \"CreationDate\": \"\\\/Date(1293186324257+0000)\\\/\", 
     \"ImageUrl\": \"http:\/\/www.google.com\", 
     \"Title\": \"Here is a title\" 
    } ] 

誰もがなぜ、どのように私はこれらのエスケープ文字を取り除くことができます知っている「\」をスラッシュしていますか?

+0

@Jon Skeetは正しそうですが、デシリアライズ時にどのような問題が発生していますか? – PsychoCoder

+0

デシリアライゼーションの問題は、エスケープ文字(\)によるものではなく、シリアライズされたテキストが「[」で始まり「]」で始まるためです。 @Jone Polvoraの答えを見てください。 {"dummyRoot":とappend}を使ってシリアライズされたテキストを追加すると、そのシリアライズがうまくいくことがわかります。 – ajgreyling

答えて

13

私は私の文字列( "\")にエスケープ文字を持っていた理由を見つけました...私のオブジェクトをシリアル化した後、私はクライアントアプリケーションにWCFを介してjson文字列を返しています。どうやら、WCFは文字列にこれらの文字を自動的に追加してから、ネットワークに送ります。これはデフォルトの動作であり、明らかに必須です。

私はこれらのエスケープ文字が欲しくないので、サービスの戻り値の型をStreamに変更し、json文字列をメモリストリーム内に戻してください。それは完璧に動作し、静かです。

Thx @Jon Skeetと@Chrisあなたの助けに!

+0

Bah!あなたは具体的には、シリアル化時にそれらを追加していると言いました!あなたはそれを固定して喜んで。 :)あなたがあなたのレベルでそれを行うことができるかどうか覚えていませんが、あなたが助けてくれた回答を+1することができます。 – Chris

+7

エスケープ文字を取得する本当の理由は、 _and_WCFは、自然な振る舞いの一部として(既にシリアライズされた)戻り値をシリアライズしています。そのためJSONはエスケープ文字で終わります。ストリームとして返すことで、実質的にWCFシリアライザのエンド・ランを実行しています。もう一つの可能​​な解決策は、メソッドからシリアル化されていないオブジェクトを単純に返し、WCFにシリアル化させることですが、これはJson.Netを使用しないことを意味します。 –

+0

@Brian - あなたが正しいです。私はこの同じ問題を抱えていますが、コントローラでのみ使用されるカスタムコンバータを使用したいので迷惑です。(したがって、このカスタムコンバータを使用してシリアル化するようにクラスに注釈を付けることはできません。コントローラーロジックのカスタムコンバーター、私は文字列を返し、WCFはデータを再シリアル化します... – Jmoney38

21

実際にははエスケープ文字を追加していないと思われます。私はデバッガの文字列を見ているだけだと思っています。にエスケープ文字を追加しています。

ファイルまたはコンソールにダンプしてみてください。

+0

フォームのテキストボックスへのダンプも私のために働いた。素晴らしいヒント –

1

私は出力されたものを完全に引用していないことに注意してください(私はあなたの答えで作業するためのURLを得ています - 答えとして置くのではなく、あなたの質問に編集する必要があります)。私には重要なことは、私は何でも、それを出力していること、それは引用符で囲む必要が決定されていることを思わせるフロントと最後にエスケープされていない引用符があるということです

"[{\"$id\":\"1\",\"CreationDate\":\"\\\/Date(1293186324257+0000)\\\/\",\"ImageUrl\":\"http:\/\/www.c-tina.com\/MyVoucherAdmin\/Images\/shop22\/burger.jpg\",\"Title\":\"Get one burger for free\",\"Description\":\"Bla lbzlfpzkfgmzke\\rdmjdgmj\\r\\r\\rlgfpzkegmkzepk\",\"ShopId\":22,\"PromotionId\":15,\"Shop\":null,\"Features\":[],\"SingleStats\":[],\"WhatsHots\":[],\"EntityKey\":{\"$id\":\"2\",\"EntitySetName\":\"Promotions\",\"EntityContainerName\":\"MyVoucherEntities\",\"EntityKeyValues\":[{\"Key\":\"PromotionId\",\"Type\":\"System.Int32\",\"Value\":\"15\"}]}}]" 

:私は戻って、ファイルに入った文字列は、このましたあなたが引用符で囲んでいるなら、それの中にある引用符をエスケープすることができます。

問題がJSONを生成するために上で引用したコードにある場合、または引用の原因となっているこの処理の後のステップで問題がある場合は、完全な出力が表示されません。デバッグして、シリアライズコールの出力が、潜在的に後の段階で実行されるのではなく、エスケープされたバージョンを確実に生成していることを確認しましたか?デバッガに慣れていない場合は、Jon Skeetがファイルやコンソールにダンプして、混乱がないことを確認してください。

+0

あなたの答えのためにクリス、thx。私はデバッガで検証しましたが、実際には後のステップではなく、シリアライゼーションで引用符を追加しています。それにもかかわらず、私は他のプロジェクトで同じコードを試してみましたが、わかりませんが引用符を追加しません...私はJsonによってこれらの引用符を生成する直列化するオブジェクトの型になりますか?ネットライブラリ? – Renaud

+0

私はJson.netのライブラリを実際に使っていないので、これ以上のアドバイスはできません。これらのオブジェクト内の異なるオブジェクトと異なるデータを試して、違いがあるかどうかを調べることができます。私はそれがなぜそれをするのかについて少し困惑しています、あなたがそれを望んでいたかもしれない状況を考えることはできません。興味のない場合は、deserialiseメソッドを使用してそれをまっすぐに実行すると、期待どおりに機能しますか?ここに何らかの種類のバグがあるかどうか疑問に思う.. – Chris

1

これは役に立ちますか?文字列は「\」2「\\」に戻ってくるだろうがある場合

private HttpContent ConvertToJsonContent(object content) 
{ 
    string jsonObject = JsonConvert.SerializeObject(content, Newtonsoft.Json.Formatting.Indented); 
    return new StringContent(jsonObject, Encoding.UTF8, "application/json"); 
} 

:私は、JSONの内容を返すために、私のWebサービスでそれを使用しました。あなたはアンエスケープ

private HttpContent ConvertToJsonContent(object content) 
{ 
    string jsonObject = Regex.Unescape(JsonConvert.SerializeObject(content, Newtonsoft.Json.Formatting.Indented)); 
    return new StringContent(jsonObject, Encoding.UTF8, "application/json"); 
} 
+0

他の答えは*なぜ*文字がエスケープされていなかったかに関して良い答えを与えていましたが、Unescapeのソリューションは素早く – Cantalouping

2

オブジェクトのリストをシリアライズした結果が配列、すなわちあるので、それは無効なJSONだを使用して、これを避けることができ、JSONは「[」とで終わる「]」で始まります。これを修正するには、ルートオブジェクト(クラスまたは匿名オブジェクトのインスタンス)にオブジェクトのリストをラップする必要があります。結果の文字列は '{'で始まり '}'で終わります。 例: var output = new List<object>(); var json = JsonConvert.SerializeObject(new { root = output }, Formatting.Indented); Response.Write(json);

+0

ellegant!new {x = y}を持つオブジェクトを作成するC#の機能は何ですか?これをコンストラクタレスのインスタンス化に使用しましたが、このようなものはありません。 – ajgreyling

+0

はい、それはありますC#では匿名型と呼ばれていますが、このような単純なタスクのために通常の "名前付き"クラスを作成したくない場合には非常に便利です。 –

関連する問題