例如,我有一些课程:

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

10-08 07:56