我正在尝试从REST API反序列化xml输出。反序列化后,我需要检查响应是否有有效数据。
public class Response
{
public UserWrapper Users { get; set; }
public MovieWrapper Movies { get; set; }
}
public class UserWrapper
{
[XmlElement("User")]
public User[] UserList { get; set; }
}
public class MovieWrapper
{
[XmlElement("Movie")]
public Movie[] MovieList { get; set; }
}
public static bool isValidUserResponse(this Response response)
{
return response.Users != null && response.Users.UserList != null
}
public static bool isValidMovieResponse(this Response response)
{
return response.Movies!= null && response.Movies.MovieList != null
}
XML响应结构
<Response>
<Users>
<User>...</User>
<User>...</User>
<User>...</User>
</Users>
</Response>
<Response>
<Movies>
<Movie>...</Movie>
<Movie>...</Movie>
<Movie>...</Movie>
</Movies>
</Response>
如何将isValidUserResponse()和isValidMovieResponse()作为单一通用方法?
答案 0 :(得分:3)
你不能仅仅使用泛型 - 至少,不容易。你可以写一些类似的东西:
public static void IsValidResponse<T>(this Response response,
Func<Response, T> firstPropertyFetcher,
Func<T, object> secondPropertyFetcher) where T : class
{
T property = firstPropertyFetcher(response);
return property != null && secondPropertyFetcher(property) != null;
}
并将其命名为:
response.IsValidResponse(r => r.Users, u => u.UserList);
response.IsValidResponse(r => r.Movies, u => u.MovieList);
......但我不确定那是否更清洁。
或者你可以使用反射来检查Response
中的所有属性并查找具有“目标”类型的属性,并验证这些......但它有点难看。< / p>
您是否需要单独验证响应的每个部分?如果没有,您可以考虑为每个班级提供自己的IsValid
方法。
或者,我相信有一些一般的开源验证项目可以帮助你 - 但我没有任何经验。
答案 1 :(得分:2)
public class Response
{
public UserWrapper Users { get; set; }
public MovieWrapper Movies { get; set; }
public Response()
{
Users = new UserWrapper();
Movies = new MovieWrapper();
}
public bool IsValid<T>() where T : IList
{
var property = this.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).First(p => p.PropertyType.Equals(typeof(T)));
var collection = property.GetValue(this) as IList;
return collection.Count > 0;
}
}
public class User
{
// ...
}
public class Movie
{
// ...
}
public class UserWrapper : List<User>
{
// ...
}
public class MovieWrapper : List<Movie>
{
// ...
}
然后我们得到:
static void Main(string[] args)
{
var res = new Response();
res.Users.Add(new User());
Console.WriteLine(res.IsValid<UserWrapper>().ToString()); // "true"
Console.WriteLine(res.IsValid<MovieWrapper>().ToString()); // "false"
}
所以这就是发生的事情:this.GetType()
给我们Response
类型对象,它存储有关它的所有元数据;我们获取属于该实例的所有公共属性,并且我们查找第一个具有返回类型(PropertyType
)的公共属性,该类型与我们正在寻找的类型相同:T
类型。
我们使用property
从实例(property.GetValue(this)
)获取相关集合,然后我们只计算它。
请注意,如果您有两个相同类型的属性 - 此模式将无效。