反序列化字典<字符串,T> [英] Deserialize Dictionary<string, T>

查看:166
本文介绍了反序列化字典<字符串,T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我有一些类:

  class User 
{
int Id {得到; set;}
string Name {get; set;}
}

class Venue
{
int Id {get; set;}
string Adress {get; set;}
}

类消息
{
string Text {get; set;}
int FromId {get; set;}
}

我从web获取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,%venue%= Venue等。



但我该如何解析呢?



提前感谢!



UPDATE



我当前的解决方案:

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

字典< string,object> dict =
JsonConvert.DeserializeObject< Dictionary< string,object>>
(myJson,_jsonSettings);

字典< 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> );
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); $ b $ d d.Add(o.Key,v);
break;
}
}
}


解决方案>

如果你使用Json.Net(aka Newtonsoft.Json),你可以创建一个自定义的JsonConverter对象。这个对象允许自定义解析json。因此,给定以下类

  public class User 
{
public int Id {get;组; }
public string Name {get;组; }
}

public class Venue
{
public string Id {get;组; }
public string Address {get;组; }
}

public class Message
{
public string Text {get;组; }
[JsonProperty(fromId)]
public string FromId {get;组; }
}

您可以在另一个类中包含分配了JsonConverter

  [JsonConverter(typeof(PostJsonConverter))] 
public class Post
{
public User User {得到;组; }
public Venue Venue {get;组; }
public Message Message {get;组; }
}

JsonConvter类是一个抽象类,需要覆盖三个方法。您将需要实现ReadJson方法。如果你不需要写json,那么在WriteJson方法中不需要做任何事情。

  public class PostJsonConverter:JsonConverter 
{
public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
{
//未实现
}

public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
{
//它必须是正在传入的对象,如果没有发生错误!
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\ \name\:\John \},\%venue%\:{\id\:\5f56de\,\address\ :\Thomas at 68th Street\}}; 
Post post = JsonConvert.DeserializeObject< Post>(myJson);


For example, I have a some classes:

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

I take the json from web:

  [%user% => {id: 1, name: "Alex"}, %user% => {id: 5, name: "John"}]

I can parse it :

var myObjects = JsonConvert.DeserializeObject<Dictionary<string, User>>(json);

But if have a json:

  [%user% => {id: 1, name: "Alex"}, %venue% => {id: 465, adress: "Thomas at 68th Street"}, %message% => {text: "hello", fromId: 78}]

I can define type by key %user% = User, %venue% = Venue, etc..

But how can I parse it?

Thanks in advance!

UPDATE

My current solution:

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

解决方案

If you are using Json.Net (aka Newtonsoft.Json) you can create a custom JsonConverter object. This object would allows for custom parsing of the json. So, given the following classes

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

You could contain those within another class that is assigned a JsonConverter

[JsonConverter(typeof(PostJsonConverter))]
public class Post
{
    public User User { get; set; }
    public Venue Venue { get; set; }
    public Message Message { get; set; }
}

The JsonConvter class is an abstract class with three methods you need to overwrite. You'll want to implement the ReadJson method. If you do not need to write json, then no need to do anything in the WriteJson method.

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

No extra work is needed to convert this from normal conversion because we've given the class the JsonConverterAttribute.

string myJson = "{\"%user%\":{\"id\" : 5, \"name\" : \"John\"}, \"%venue%\":{\"id\" : \"5f56de\", \"address\": \"Thomas at 68th Street\"}}";
Post post = JsonConvert.DeserializeObject<Post>(myJson);

这篇关于反序列化字典&LT;字符串,T&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆