将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);
如您所见,没有其他包
上述就是C#学习教程:将Json反序列化为对象和子对象以进行返回分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/999610.html