我正在使用Newtonsoft.JSON。我不知道传递给这个方法的对象的类型,或者检索到这个方法,所以我试图在一个我不知道它的类型的对象上使用DeserializeObject
。
这可能吗?如果是这样,怎么样? 这是我的代码。
public static List<T> GetObject<T>(string cacheKey, IEnumerable<T> obj)
{
using (HttpClient client = new HttpClient())
{
var response = client.GetAsync("http://localhost:53805/api/NonPersisted/Get/" + cacheKey).Result;
obj = JsonConvert.DeserializeObject<obj.GetType>(response.Content.ToString());
return obj.ToList();
}
}
我首先尝试使用
obj = JsonConvert.DeserializeObject<List<T>>(response.Content.ToString());
这不起作用,很明显,它无法解析。
获取对象的类型不会构建,它会显示obj is a variable but used like a type
。
修改
您似乎可以使用通用List<T>
而不知道JsonConvert.DeserializeObject<>
的类型。真正的错误是response.Content
只返回了类型。你需要......
obj = JsonConvert.DeserializeObject<List<T>>(response.Content.ReadAsStringAsync().Result);
答案 0 :(得分:4)
您可以在不使用参数GetObject
的情况下使IEnumerable<T> obj
方法通用。
以下解决方案我建议您假设您知道从URL返回的JSON值的格式。
例如,URL返回包含项目数组的JSON,每个项目都有两个属性firstName
和lastName
。
var response = "[{\"firstName\":\"Melanie\",\"lastName\":\"Acevedo\"},
{\"firstName\":\"Rich\",\"lastName\":\"Garrett\"},
{\"firstName\":\"Dominguez\",\"lastName\":\"Rose\"},
{\"firstName\":\"Louisa\",\"lastName\":\"Howell\"},
{\"firstName\":\"Stone\",\"lastName\":\"Bean\"},
{\"firstName\":\"Karen\",\"lastName\":\"Buckley\"}]";
我可以编写GetObject
方法如下。
public static List<T> GetObject<T>()
{
var response = "
[{\"firstName\":\"Melanie\",\"lastName\":\"Acevedo\"},
{\"firstName\":\"Rich\",\"lastName\":\"Garrett\"},
{\"firstName\":\"Dominguez\",\"lastName\":\"Rose\"},
{\"firstName\":\"Louisa\",\"lastName\":\"Howell\"},
{\"firstName\":\"Stone\",\"lastName\":\"Bean\"},
{\"firstName\":\"Karen\",\"lastName\":\"Buckley\"}]";
var obj = JsonConvert.DeserializeObject<List<T>>(response);
return obj.ToList();
}
上述方法中的T
可以是具有firstName
和lastName
属性的任何类型。例如
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public double Salary { get; set; }
}
我可以通过传递GetObject
或Person
来调用Employee
方法,并将JSON字符串反序列化为这些类的对象集合,如下所示。
var persons = GetObject<Person>();
foreach (var item in persons)
{
Console.WriteLine($"{item.FirstName} {item.LastName}");
}
var employees = GetObject<Employee>();
foreach (var item in employees)
{
Console.WriteLine($"{item.FirstName} {item.LastName}");
}
总的来说,我想说的是,如果JSON的格式知道将JsonConvert.Deserialize<T>
传递给适当的类型应该没有任何问题。
如果传入的JSON代表一个集合并且尝试将其反序列化为一个简单的类将失败,反之亦然也将无效。
因此,对于您的问题,如果您知道JSON将成为一个集合,那么使用JsonConvert.Deserialize<List<T>>
不应该给您带来任何问题,因为T
具有可以设置JSON值的属性
我希望这可以帮助您解决问题。
答案 1 :(得分:1)
我现在无法对此进行测试,但我认为以下内容可行。我发现JSON.NET在反序列化时不喜欢List<T>
,我通常会通过使用数组来解决这个问题。
static HttpClient _httpClient = new HttpClient();
public static async Task<T[]> GetObject<T>(string cacheKey)
{
HttpResponseMessage response = await _httpClient .GetAsync("http://localhost:53805/api/NonPersisted/Get/" + cacheKey);
return JsonConvert.DeserializeObject<T[]>(response.Content.ToString());
}
我冒昧地删除了using
的{{1}}语句,并将其作为静态成员。我还更改了运行HttpClient
的方法,您可以轻松地将其更改回来,但正如我在评论中提到的,您可能希望避免使用async
并使用WebClient。
答案 2 :(得分:0)
如果您不知道类型T,我认为您不能致电Deserialize<T>(..)
。
我唯一能想到的就是获取对象:
public static Object GetObject(string cacheKey)
{
using (HttpClient client = new HttpClient())
{
var response = client.GetAsync("http://localhost:53805/api/NonPersisted/Get/" + cacheKey).Result;
var obj = JsonConvert.DeserializeObject(response.Content.ToString());
return obj;
}
}
答案 3 :(得分:0)
您可以通过将类型传递到函数中而无需强行键入它。 例如:
Type type = obj.GetType();
JsonConvert.DeserializeObject(json, type);