2012-04-14 11 views
14

Quando provo a deserialise questa stringa non valida JSON (}] mancante alla fine):ServiceStack.Text JSON deserializzazione crea oggetto sbagliato invece di gettare sulla stringa di input non valido JSON

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

In questo modo:

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

il deserializzatore ServiceStack json accetta la stringa, ma crea un oggetto sbagliato, perché io alla fine con un oggetto C# avere questi valori:

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. 

In questo caso sarebbe molto meglio lanciare un'eccezione anziché continuare con dati non validi. Pertanto ho provato a utilizzare:

JsConfig.ThrowOnDeserializationError = true; 

appena prima di chiamare DeserializeFromString ma non è stata generata alcuna eccezione. A gennaio ho posto questa domanda Configure ServiceStack.Text to throw on invalid JSON e la risposta è stata che ServiceStack sta favorendo la resilence e che potrei fare una richiesta di pull in GitHub.

È ancora così? E qualcuno l'ha già fatto, salvandomi il disturbo? In caso contrario, ho un programma molto serrato, quindi se qualcuno ha qualche codice o suggerimenti su come creare un flag di opzione per far sì che ServiceStack influisca sugli errori di deserializzazione, per favore rispondi qui, in modo da poterlo fare più velocemente.

+0

Ho visto il tuo post originale, sono d'accordo che si dovrebbe almeno avere la possibilità di trasformare rigorosa convalida JSON su. Ottengo gli stessi risultati passando al serializzatore Newtonsoft. Come una delle mie università ha sottolineato, se usiamo la serializzazione resiliente, stiamo tornando indietro nello stesso modo in cui è possibile analizzare il file html della spazzatura senza errori laddove consenta agli sviluppatori sciatti. – Bronumski

+0

Questo sembra un bug. Hai depositato [un problema per questo] (https://github.com/ServiceStack/Issues/issues/new)? – jlyonsmith

risposta

0

C# è un po 'schizzinoso quando si tratta di JSON. Di seguito sarebbe valido! Nota non ho array di oggetti anonimi come elemento predefinito.

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

Se ho generato un POCO da questo ho

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; } 
} 

io personalmente uso metodo di estensione a stringa

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; 
     } 
    } 
} 

Questo mi avrebbe permesso di scrivere:

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 
-1

Io uso solo lo Newtonsoft.JsonT JsonConvert.DeserializeObject<T>(string value) e genera un'eccezione;

Se uso il object JsonConvert.DeserializeObject(string value) questo crea l'oggetto giusto, semplicemente posizionando il mancante }]

ho scoperto che questo è una libreria molto affidabile e veloce.

1

Questo si risolve in ServiceStack.Text v4 + che di default non popolano le collezioni incomplete, ad esempio:

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); 

O se preferite può gettare in caso di errore:

JsConfig.ThrowOnDeserializationError = true; 

Assert.Throws<SerializationException>(() => 
    json.FromJson<Poco[]>()); 
0

ho provato questo ha gettato l'eccezione quando mi sono perso il} alla fine.

In C#, il formato per JSON è {"nome", "valore"} non [{"nome", "valore"}].

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); 

Quando si esegue questo, si otterrà l'errore in quanto manca un}.

utilizzando:

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

L'oggetto è bene deserializzato.

si può vedere il JSON di questo oggetto da:

string s = JsonConvert.SerializeObject(m); 
Problemi correlati