Korzystanie Z JsonConvert.DeserializeObject do deserializacji Json do klasy C# POCO
Oto moja prostaUser
klasa POCO:
/// <summary>
/// The User class represents a Coderwall User.
/// </summary>
public class User
{
/// <summary>
/// A User's username. eg: "sergiotapia, mrkibbles, matumbo"
/// </summary>
public string Username { get; set; }
/// <summary>
/// A User's name. eg: "Sergio Tapia, John Cosack, Lucy McMillan"
/// </summary>
public string Name { get; set; }
/// <summary>
/// A User's location. eh: "Bolivia, USA, France, Italy"
/// </summary>
public string Location { get; set; }
public int Endorsements { get; set; } //Todo.
public string Team { get; set; } //Todo.
/// <summary>
/// A collection of the User's linked accounts.
/// </summary>
public List<Account> Accounts { get; set; }
/// <summary>
/// A collection of the User's awarded badges.
/// </summary>
public List<Badge> Badges { get; set; }
}
I metoda, której używam do deserializacji odpowiedzi JSON do obiektu User
(to rzeczywiste wywołanie JSON jest tutaj):
private User LoadUserFromJson(string response)
{
var outObject = JsonConvert.DeserializeObject<User>(response);
return outObject;
}
Wywołanie wyjątku:
Nie można deserializować bieżącego obiektu JSON (np. {"name": "value"}) do typu "System.Kolekcje.Ogólne.Lista " 1[CoderwallDotNet.Api.Modelki.Konto]" ponieważ typ wymaga tablicy JSON (np. [1,2,3]) do deserializacji prawidłowo.
Aby naprawić ten błąd, Zmień JSON na tablicę JSON (np. [1,2,3]) lub zmienić deserializowany Typ tak, aby był normalnym Typu. NET (np. nie prymitywny typ jak integer, Nie zbiór typu jak tablica lub Lista), które mogą być deserializowane z JSON obiekt. JsonObjectAttribute można również dodać do typu, aby go wymusić deserializacji z obiektu JSON. / Align = "left" / github", linia 1, pozycja 129.
Nigdy nie pracowałem z tym DeserializeObject metoda wcześniej, utknąłem tutaj.
Upewniłem się, że nazwy właściwości w klasie POCO są takie same jak nazwy w odpowiedzi JSON.
Co mogę spróbować deserializować JSON do tej klasy POCO?
7 answers
Oto działający przykład.
Punkty kluczowe to:
- Deklaracja
Accounts
- użycie atrybutu
JsonProperty
.
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString("http://coderwall.com/mdeiters.json");
var user = JsonConvert.DeserializeObject<User>(json);
}
-
public class User
{
/// <summary>
/// A User's username. eg: "sergiotapia, mrkibbles, matumbo"
/// </summary>
[JsonProperty("username")]
public string Username { get; set; }
/// <summary>
/// A User's name. eg: "Sergio Tapia, John Cosack, Lucy McMillan"
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// A User's location. eh: "Bolivia, USA, France, Italy"
/// </summary>
[JsonProperty("location")]
public string Location { get; set; }
[JsonProperty("endorsements")]
public int Endorsements { get; set; } //Todo.
[JsonProperty("team")]
public string Team { get; set; } //Todo.
/// <summary>
/// A collection of the User's linked accounts.
/// </summary>
[JsonProperty("accounts")]
public Account Accounts { get; set; }
/// <summary>
/// A collection of the User's awarded badges.
/// </summary>
[JsonProperty("badges")]
public List<Badge> Badges { get; set; }
}
public class Account
{
public string github;
}
public class Badge
{
[JsonProperty("name")]
public string Name;
[JsonProperty("description")]
public string Description;
[JsonProperty("created")]
public string Created;
[JsonProperty("badge")]
public string BadgeUrl;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-20 20:12:34
Można utworzyć JsonConverter
. Zobacz Tutaj aby uzyskać przykład podobny do twojego pytania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:32
Innym i bardziej usprawnionym podejściem do deserializacji łańcucha JSON z obudową wielbłąda do obiektu poco z obudową Pascala jest użycie CamelCasePropertyNamesContractResolver.
To część Newtonsoftu.Json.Przestrzeń nazw serializacji. Takie podejście zakłada, że jedyna różnica między obiektem JSON a POCO leży w obudowie nazw właściwości. Jeśli nazwy właściwości są pisane inaczej, musisz użyć atrybutów JsonProperty do mapowania nazwy nieruchomości.using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
. . .
private User LoadUserFromJson(string response)
{
JsonSerializerSettings serSettings = new JsonSerializerSettings();
serSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
User outObject = JsonConvert.DeserializeObject<User>(jsonValue, serSettings);
return outObject;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-19 22:05:46
Właściwość konta jest zdefiniowana następująco:
"accounts":{"github":"sergiotapia"}
Twój POCO stwierdza to:
public List<Account> Accounts { get; set; }
Spróbuj użyć tego Json:
"accounts":[{"github":"sergiotapia"}]
Tablica elementów (które będą mapowane do listy) jest zawsze zamknięta w nawiasach kwadratowych.
Edit: konto Poco będzie coś takiego:
class Account {
public string github { get; set; }
}
I może inne właściwości.
Edit 2: aby nie mieć tablicy użyj właściwości w następujący sposób:
public Account Accounts { get; set; }
Z czymś takim jak próbka zajęcia, które zamieściłem w pierwszej edycji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-20 18:59:41
to fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the
deserialized type so that it is a normal .NET type (e.g. not a primitive type like
integer, not a collection type like an array or List) that can be deserialized from a
JSON object.`
Cała wiadomość wskazuje, że możliwe jest serializowanie do obiektu List, ale wejście musi być listą JSON. Oznacza to, że Twój JSON musi zawierać
"accounts" : [{<AccountObjectData}, {<AccountObjectData>}...],
Gdzie dane AccountObject to JSON reprezentujący obiekt Account lub obiekt Badge
Wydaje się, że obecnie jest to
"accounts":{"github":"sergiotapia"}
Gdzie accounts jest obiektem JSON (oznaczonym nawiasami klamrowymi), a nie tablicą obiektów JSON (tablice są oznaczone nawiasami), co jest tym, czego chcesz. Try
"accounts" : [{"github":"sergiotapia"}]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-20 19:09:03
Zgodnie z przyjętą odpowiedzią, jeśli masz próbkę tekstu JSON, możesz ją podłączyć do tego konwertera , wybrać opcje i wygenerować kod C#.
Jeśli nie znasz typu w czasie wykonywania, ten temat wygląda jakby pasował.
Dynamicznie deserializuj json do dowolnego obiektu przekazanego. c #
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:04
Nie o to mi chodziło. Co zrobić, jeśli masz typ generyczny, który jest znany tylko w czasie wykonywania?
public MyDTO toObject() {
try {
var methodInfo = MethodBase.GetCurrentMethod();
if (methodInfo.DeclaringType != null) {
var fullName = methodInfo.DeclaringType.FullName + "." + this.dtoName;
Type type = Type.GetType(fullName);
if (type != null) {
var obj = JsonConvert.DeserializeObject(payload);
//var obj = JsonConvert.DeserializeObject<type.MemberType.GetType()>(payload); // <--- type ?????
...
}
}
// Example for java.. Convert this to C#
return JSONUtil.fromJSON(payload, Class.forName(dtoName, false, getClass().getClassLoader()));
} catch (Exception ex) {
throw new ReflectInsightException(MethodBase.GetCurrentMethod().Name, ex);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-26 18:41:48