c# - 加载类动态获取属性值,其中一个是类
问题描述
首先,当然我已经搜索了大约两天,但如果可能的话,我无法让它工作。
这有点帮助: Get property value from C# dynamic object by string (reflection?) 还有这个: C# Iterate through Class properties
背景信息:该类是使用来自 TMDB 的 JSON 字符串生成的。API 密钥是免费的,因此如果您想查看原始 json,请获取密钥并使用: https ://api.themoviedb.org/3/tv/456?api_key=YOURKEY&append_to_response=season/1,season/2,season /3&language=en-US 我有 20 个赛季,但在这里缩短了。一次只允许 20 个。是的,我可以一次获得一个赛季并进行 27 次 API 调用,但 2 次更好。获得一个赛季就可以了,不需要任何帮助。
这是使用 VS2015 特殊粘贴生成的 json 类的一部分,并进行了一些调整:
namespace TvDb.Tv
{
class MultiSeasons
{
public Season[] seasons { get; set; }
public Season1 season1 { get; set; }
public Season2 season2 { get; set; }
public Season3 season3 { get; set; }
//and so on
}
public class Season1 : CommonProperties { }
public class Season2 : CommonProperties { }
public class Season3 : CommonProperties { }
//and so on
public class CommonProperties
{
public string _id { get; set; }
public string air_date { get; set; }
public Episode[] episodes { get; set; }
public string name { get; set; }
public string overview { get; set; }
public string poster_path { get; set; }
public int season_number { get; set; }
}
public class Season
{
public string air_date { get; set; }
public int episode_count { get; set; }
public int id { get; set; }
public string name { get; set; }
public string overview { get; set; }
public string poster_path { get; set; }
public int season_number { get; set; }
}
public class Episode
{
public string air_date { get; set; }
public int episode_number { get; set; }
public int id { get; set; }
public string name { get; set; }
public string overview { get; set; }
public string production_code { get; set; }
public int season_number { get; set; }
public string still_path { get; set; }
public float vote_average { get; set; }
public int vote_count { get; set; }
}
}
我可以通过反序列化 json 获得所需的信息,但可以看出,我知道动态获取类可以更好地编写。我只是似乎找不到方法......
string json = "It's stored in a file for testing";
//the json from TMDB returns wrong to name or find classes
//such as season/1, season/2, etc.
json = json.Replace("season/", "season");
MultiSeasons ser = JsonConvert.DeserializeObject<MultiSeasons>(json);
DataTable dt = new DataTable();
//columns added here
//int numOfSeasons = ser.number_of_seasons;
//Type type = Type.GetType("TvDb.Tv.Series, TvDb");
string str = "TvDb.Tv.Season1" + ", " + "TvDb";
//dynamic d =
Type type = Type.GetType(str);
string st = "";
if (type != null)
{
var cls = Utilities.Classes.PropertyReader.getProperties(type);
//PropertyReader site https://answers.unity.com/questions/1092425/how-to-get-a-list-of-variables-in-a-class.html
for (int i = 0; i < cls.Length; i++)
{
if(cls[i].name == "episodes")
{
//Episode e =
}
var nameOfProperty = cls[i].name;
var propertyInfo = cls.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(cls, null);
//st += cls.GetType().GetProperty(cls[i].name).GetValue(cls, null);
//st += cls[i].name.ToString() + Environment.NewLine;
}
}
DataRow dr;
//write 50 seperate foreach statements? I don't think so !!!!!!!!
if (ser.season1 != null)
{
foreach (var r in ser.season1.episodes)
{
dr = dt.NewRow();
dr["id"] = ser.id;
dr["firstAired"] = r.air_date;
dr["season"] = r.season_number;
//and so on
dt.Rows.Add(dr);
}
}
if (ser.season2 != null)
{
foreach (var r in ser.season2.episodes)
{
dr = dt.NewRow();
dr["id"] = ser.id;
dr["firstAired"] = r.air_date;
dr["season"] = r.season_number;
//and so on
dt.Rows.Add(dr);
}
}
任何意见表示赞赏或指向我错过的帖子。
编辑:对于那些想要查看 json 的人,我找到了查看它的地方......
解决方案
这将完成工作 - 如果某些事情没有按预期工作,请随时提供反馈。
我首先想使用 JsonPath 查询来查找匹配的子项 - 但它似乎不支持属性名称的通配符。至少我没有找到任何文件。
因此,我们遍历所有子属性以找到以“season/”开头的那些——从性能的角度来看,这应该没问题,因为 JsonPath 可能会做同样的事情,并且在现代系统中使用少量数据并不重要无论如何。
static IReadOnlyList<SeasonDetails> GetSeasons(string json)
{
List<SeasonDetails> seasons = new List<SeasonDetails>();
JObject jObject = JObject.Parse(json);
foreach (var child in jObject.Children<JProperty>())
{
if (!child.Name.StartsWith("season/"))
{
continue;
}
seasons.Add(child.Value.ToObject<SeasonDetails>());
}
return seasons;
}
public class SeasonDetails
{
public string _id { get; set; }
public string air_date { get; set; }
public Episode[] episodes { get; set; }
public string name { get; set; }
public string overview { get; set; }
public string poster_path { get; set; }
public int season_number { get; set; }
}
public class Episode
{
public string air_date { get; set; }
public int episode_number { get; set; }
public int id { get; set; }
public string name { get; set; }
public string overview { get; set; }
public string production_code { get; set; }
public int season_number { get; set; }
public string still_path { get; set; }
public float vote_average { get; set; }
public int vote_count { get; set; }
}
之后,您可以通过遍历季节列表来执行您的逻辑:
foreach(SeasonDetails season in seasons) {
// Fill your datatable.
}
推荐阅读
- ubuntu - Electron dialog.showOpenDialog() 关闭 Ubuntu 18.10 上的应用程序
- r - 如何根据 R 中的其他两列分组来标准化列中的值?
- asynchronous - 如何返回递归获取的结果?
- r - 距离矩阵到按位置排序的距离重组向量
- java - JGit 需要身份验证,但命令行上的 git 不需要
- regex - 使用 htaccess 将“丑陋”的 URL 重定向到新的 URL
- reactjs - 无法在反应中将表单值提交给不同的组件
- php - 使用 PHP 和 IMAP 获取 gmail 部分的列表
- ubuntu - 如何通过 nginx 调整图像大小
- amazon-web-services - 从 lambda 函数同步调用阶跃函数