将Json反序列化为对象和子对象以进行返回

还不太熟悉JSON,并且遇到了一个对我来说不明显的问题。

我正在查询的api返回一个标准的响应对象,其中处理的命令/ api请求的结果嵌入在json中的数据对象中。

因此,对于API上的所有请求,响应如下所示,数据组件的变化取决于所请求的内容。

ObjectType1响应

{ "data": { "person" : { "id" : 21, "name" : "Json can be annoying at times" } }, "message" : "", "result" : "success" } 

或者关于api的其他请求将返回以下列表

ObjectType2响应

 { "data": { "1234" : { "id": 1234, "title" : "Terminator" }, "3245" : { "id" : 3245, "name" : "Terminator 2" } }, "message" : "", "result" : "success" } 

我想有一个自定义的JsonConverter将响应拉出到一个对象中

 public class MyResponse { [JsonProperty(PropertyName = "data")] public string Data { get; set; } [JsonProperty(PropertyName = "message")] public string Message { get; set; } [JsonProperty(PropertyName = "status")] public string Status { get; set; } } 

要么

 public class MyResponse : class T { public T Data { get; set; } public string Message { get; set; } public string Status { get; set; } } 

然后从那里我可以在generics方法中对状态/消息进行操作,然后将json字符串返回给我库中的调用方法。 从中可以根据请求正确处理返回的json字符串。

任何想法如何将数据的子对象反序列化为字符串甚至更好,如果我传递方法一个generics类型T我怎么能将json反序列化为两个对象。

编辑

对于那些希望做类似事情的人,请在下面发表答案

干杯

感谢那些提供一些帮助的人,但我最终得出了我想要的答案,它将我的对象反序列化为通过generics提供的正确类型。

这是我的MyCustomResponse对象

 public class MyCustomResponse { [JsonProperty(PropertyName = "data")] public object Data { get; set; } [JsonProperty(PropertyName = "message")] public string Message { get; set; } [JsonProperty(PropertyName = "result")] public string Result { get; set; } } 

自定义JsonConverter最终结束了,我在json字符串“data”中查找属性,然后将其转换为T类型的对象

 public class MyCustomResponseConverter : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(MyCustomResponse)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { object instance = objectType.GetConstructor(Type.EmptyTypes).Invoke(null); PropertyInfo[] props = objectType.GetProperties(); JObject jo = JObject.Load(reader); foreach ( JProperty jp in jo.Properties() ) { PropertyInfo prop = props.FirstOrDefault(pi => pi.CanWrite && string.Equals(pi.Name, jp.Name, StringComparison.OrdinalIgnoreCase)); if ( prop != null ) { // Convert data object to what was passed in at T if ( jp.Name == "data" ) prop.SetValue(instance, jo.SelectToken("data").ToObject(typeof(T))); else prop.SetValue(instance, jp.Value.ToObject(prop.PropertyType, serializer)); } } return instance; } public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } 

为了使用上面的内容,我创建了一个类似于以下内容的Generic方法,允许我传递命令来运行,额外的查询字符串以及Type以将’Data’对象转换为:

 private async Task GenericApiRequestAsync(string command, string query) { HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Uri uri = new Uri(string.Format("{0}/api/{1}/?cmd={2}{3}", apiUrl, apiKey, command, query)); try { HttpResponseMessage response = await client.GetAsync(uri); response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(); // Convert responseContent via MyCustomResponseConverter var myCustomResponse = await Task.Factory.StartNew(() => JsonConvert.DeserializeObject() )); return (T)myCustomResponse.Data; } catch(Exception ex) { ... } } 

然后,为了使用实际的GenericApiRequestAsync方法,我只需将它的命令,查询和类型传递给要转换成的Data对象,无论它是什么。

 public async Task GetPersonAsync(int id) { return await GenericApiRequestAsync("person.byid", string.Format("&id={0}", id)); } public async Task> GetObjectType2ListAsync(string name) { return await GenericApiRequestAsync>("show.byname", string.Format("&name={0}", name)); } 

结束了一个简单的解决方案,但很复杂。 它消除了在最终对象中第二次处理数据对象的需要。

希望这个解决方案可以帮助那些遇到类似JSON结构的人,如果有人看到更简单的方法来实现转换器,我很乐意接受任何输入。

干杯

有关JSON对象的序列化/反序列化,请查看Json.NET 。 您可以将其包含为Nuget包,并使用内置方法,如JsonConvert.SerializeObject(Object object)JsonConvert.DeserializeObject(string value, Type type)

您可以通过使用JsonProperty属性修饰模型来控制JSON属性的名称。 例如:

 public class MyResponse { [JsonProperty(PropertyName = "data")] public string Data { get; set; } [JsonProperty(PropertyName = "message")] public string Message { get; set; } [JsonProperty(PropertyName = "status")] public string Status { get; set; } } 

两个实体:

 public class Response { public Dictionary data { get; set; } public string message { get; set; } public string result { get; set; } } public class Data { public int id { get; set; } public string title { get; set; } } 

响应代码是:

  JavaScriptSerializer serializer = new JavaScriptSerializer(); Response response = (Response) serializer.Deserialize(jsonString); 

如您所见,没有其他包