例如,我有一些课程:
class User
{
int Id {get; set;}
string Name {get; set;}
}
class Venue
{
int Id {get; set;}
string Adress {get; set;}
}
class Message
{
string Text {get; set;}
int FromId {get; set;}
}
我从网络上获取json:
[%user% => {id: 1, name: "Alex"}, %user% => {id: 5, name: "John"}]
我可以解析它:
var myObjects = JsonConvert.DeserializeObject<Dictionary<string, User>>(json);
但是如果有json:
[%user% => {id: 1, name: "Alex"}, %venue% => {id: 465, adress: "Thomas at 68th Street"}, %message% => {text: "hello", fromId: 78}]
我可以通过键%user%= User,%venue%= Venue等来定义类型。
但是我怎么解析呢?
提前致谢!
更新
我当前的解决方案:
private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
};
string myJson = "{\"%user%\":{\"id\" : 5, \"name\" : \"John\"}, \"%venue%\":{\"id\" : \"5f56de\", \"adress\": \"Thomas at 68th Street\"}}";
Dictionary<string, object> dict =
JsonConvert.DeserializeObject<Dictionary<string, object>>
(myJson, _jsonSettings);
Dictionary<string, object> d = new Dictionary<string, object>();
foreach(var o in dict)
{
string json = (string)o.Value.ToString();
switch (o.Key)
{
case "%user%":
{
var v = JsonConvert.DeserializeObject<User>(json);
d.Add(o.Key, v);
break;
}
case "%venue%":
{
var v = JsonConvert.DeserializeObject<Venue>(json);
d.Add(o.Key, v);
break;
}
case "%message%":
{
var v = JsonConvert.DeserializeObject<Message>(json);
d.Add(o.Key, v);
break;
}
}
}
最佳答案
如果您正在使用Json.Net(又名Newtonsoft.Json),则可以创建一个自定义JsonConverter对象。该对象将允许自定义解析json。因此,鉴于以下课程
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Venue
{
public string Id { get; set; }
public string Address { get; set; }
}
public class Message
{
public string Text { get; set; }
[JsonProperty("fromId")]
public string FromId { get; set; }
}
您可以将这些包含在另一个分配了JsonConverter的类中
[JsonConverter(typeof(PostJsonConverter))]
public class Post
{
public User User { get; set; }
public Venue Venue { get; set; }
public Message Message { get; set; }
}
JsonConvter类是一个抽象类,其中包含三个您需要覆盖的方法。您将要实现ReadJson方法。如果不需要编写json,则无需在WriteJson方法中执行任何操作。
public class PostJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// not implemented
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// it must be an object being passed in, if not something went wrong!
if (reader.TokenType != JsonToken.StartObject) throw new InvalidOperationException();
var postToken = JToken.ReadFrom(reader);
var userToken = postToken["%user%"];
var venueToken = postToken["%venue%"];
var messageToken = postToken["%message%"];
return new Post
{
User = userToken == null ? null : userToken.ToObject<User>(),
Venue = venueToken == null ? null : venueToken.ToObject<Venue>(),
Message = messageToken == null ? null : messageToken.ToObject<Message>(),
};
}
public override bool CanConvert(Type objectType)
{
return true;
}
}
从常规转换转换此转换不需要任何额外的工作,因为我们已经为该类提供了JsonConverterAttribute。
string myJson = "{\"%user%\":{\"id\" : 5, \"name\" : \"John\"}, \"%venue%\":{\"id\" : \"5f56de\", \"address\": \"Thomas at 68th Street\"}}";
Post post = JsonConvert.DeserializeObject<Post>(myJson);