14

この無効なjson文字列を逆シリアル化しようとすると(}]最後に欠落しています):

[{"ExtId":"2","Name":"VIP sj�lland","Mobiles":["4533333333","4544444444"]

これを行うことにより:

var result = JsonSerializer.DeserializeFromString<T>(str);    

ServiceStack json デシリアライザーは文字列を受け入れますが、これらの値を持つ C# オブジェクトになってしまうため、間違ったオブジェクトが作成されます。

ExtId : "2"                                      // ok fine.
Name: "VIP sj�lland"                            // ok fine
Mobiles: ["4533333333","4544444444", "544444444"]// Aarg! An array with 3 objects ?!? 
                                                 // There were only two in the JSON string.

この場合、不良データを処理し続けるよりも、例外をスローする方がはるかに優れています。したがって、私は使用してみました:

JsConfig.ThrowOnDeserializationError = true; 

DeserializeFromString を呼び出す直前ですが、例外はスローされませんでした。1 月に、無効な JSON をスローするように ServiceStack.Text を構成するという質問をしたところ、その答えは、ServiceStack は回復力を優先しており、GitHub でプル リクエストを作成できるというものでした。

これはまだですか?そして、誰かがすでにそれを行って、私の問題を解決しましたか? それ以外の場合は、非常にタイトなスケジュールになっているため、ServiceStack でデシリアライゼーション エラーを発生させるためのオプション フラグの作成方法に関するコードまたは提案があれば、ここに返信してください。

4

4 に答える 4

1

これは ServiceStack.Text v4+で解決され、デフォルトでは不完全なコレクションは読み込まれません。

public class Poco
{
    public string ExtId { get; set; }
    public string Name { get; set; }
    public string[] Mobiles { get; set; }
}

var json = "[{\"ExtId\":\"2\",\"Name\":\"VIP sj�lland\",\"Mobiles\":[\"4533333333\",\"4544444444\"]";

var dto = json.FromJson<Poco[]>();

Assert.That(dto[0].ExtId, Is.EqualTo("2"));
Assert.That(dto[0].Name, Is.EqualTo("VIP sj�lland"));
Assert.That(dto[0].Mobiles, Is.Null);

または、優先する場合はエラーをスローできます:

JsConfig.ThrowOnDeserializationError = true;

Assert.Throws<SerializationException>(() => 
    json.FromJson<Poco[]>());
于 2014-09-16T12:52:05.127 に答える
0

最後に}を逃したときに例外がスローされるようにしました。

C# では、JSON の形式は [{"name", "value"}] ではなく {"name", "value"} です。

class M
        {
            public string ExtId { get; set; }
            public string Name { get; set; }
            public List<string> Mobiles { get; set; }
        }

string str = "{\"ExtId\":\"2\",\"Name\":\"VIP\",\"Mobiles\":[\"4533333333\",\"4544444444\"]";

M m = JsonConvert.DeserializeObject<M>(str);

これを実行すると、} がないためエラーが発生します。

使用:

string str = "{\"ExtId\":\"2\",\"Name\":\"VIP\",\"Mobiles\":[\"4533333333\",\"4544444444\"]}";

オブジェクトは正常に逆シリアル化されます。

このオブジェクトの JSON は次の場所から確認できます。

string s = JsonConvert.SerializeObject(m);
于 2015-03-10T14:05:40.917 に答える
0

JSONに関しては、C#は少しうるさいです。以下は有効です!デフォルトの要素として匿名オブジェクト配列がないことに注意してください。

{
    "ExtItem": [
        {
            "ExtId": "2",
            "Name": "VIPsj�lland",
            "Mobiles": [
                "4533333333",
                "4544444444"
            ]
        }
    ]
}

これからPOCOを生成すると、

public class Rootobject
{
    public Extitem[] ExtItem { get; set; }
}

public class Extitem
{
    public string ExtId { get; set; }
    public string Name { get; set; }
    public string[] Mobiles { get; set; }
}

私は個人的に文字列に拡張メソッドを使用します

public static class Extensions
{
    public  static bool DeserializeJson<T>(this String str, out T item)
    {
        item = default(T);
        try
        {
            item = new JavaScriptSerializer().Deserialize<T>(str);
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }
}

これにより、次のように書くことができます。

Rootobject ext;
const string validJson = @"
{
    ""ExtItem"": [
        {
            ""ExtId"":""2"",
            ""Name"":""VIPsj�lland"",
            ""Mobiles"":[
                ""4533333333"",
                ""4544444444""
            ]
        }
    ]
}";
if (validJson.DeserializeJson(out ext))
{ //valid input 
    // following would print 2 elements : 4533333333, 4544444444
    Console.WriteLine(string.Join(", ", ext.ExtItem.First().Mobiles)); 
} //invalid input
于 2014-09-16T09:30:06.970 に答える
-1

を使用するだけNewtonsoft.Json T JsonConvert.DeserializeObject<T>(string value)で、例外がスローされます。

これを使用するobject JsonConvert.DeserializeObject(string value)と、不足しているオブジェクトを配置するだけで正しいオブジェクトが作成されます}]

これは非常に信頼性が高く高速なライブラリであることがわかりました。

于 2014-09-16T10:04:39.327 に答える