短片
使用反射将string prop = "part1.first_name";
之类的内容转换为System.Reflection.PropertyInfo
的最佳方式是什么,以便我可以使用GetValue和SetValue函数?
LONG VERSION
我正在使用ASP .NET MVC为我的组织构建调查问卷。它很长,因此分为几个不同的页面。因为我们得到诸如“你能把这个问题转移到那个页面,将这个问题转移到另一个页面”这样的请求并不少见,“我需要构建它以使初级程序员能够非常灵活地进行更改。”
我的模型是一个复杂的类(它有五个成员类,它们主要具有原始类型的属性)。
因此,我通过执行Model.part1.first_name
或Model.part2.birth_date
等操作来访问它。
由于在所有页面上都使用了相同的模型,但并非每个页面上都存在所有问题,因此我有ActionAttributes,它基本上清除了表单上提交的所有属性,除了对于那个页面上显示的那些(因此有人不能在表单中注入隐藏字段并将值保留在数据库中)。
我想确保我只保存有效的字段值,并且不让用户进入下一页,直到当前的一个完全没问题,但我还要保存所在的值有效,即使不允许用户继续操作。
为此,我有一个函数,它接受我的模型类的两个实例,对ModelStateDictionary的引用,以及一个string[]
字段名称,如“part1.first_name”和“part2.birth_date”。该函数需要将第一个(即表单提交的)对象中没有验证错误的字符串数组中列出的所有值复制到第二个(即从db加载)对象。
如上所述,使用反射将“part1.first_name”之类的内容转换为System.Reflection.PropertyInfo
或OR的最佳方法是,有更好的方法来实现此目的吗?
答案 0 :(得分:2)
var infoParts = prop.Split('.');
var myType = Type.GetType(infoParts[0]);
var myPropertyInfo = myType.GetProperty(infoParts[1]);
假设“part1”是你的类型。虽然这是非常有限的,并且非常依赖于字符串格式正确且类型在当前范围内。
答案 1 :(得分:0)
我可能会使用数据来区别对待。我会在数据库中保留每个问题所属的步骤。为了呈现该步骤,我将选择与该步骤匹配的问题,并且具有包含问题ID /问题对列表的模型。回发时,每个输入都将通过问题ID进行标识。要进行验证,只需将问题ID集与该步骤的预期ID进行比较。这样,更改哪个问题在哪个步骤中只更改数据库中的数据。
如果你最终走上这条路,你需要将字符串分成几部分,然后递归或迭代地在每一步找到对象的属性。
PropertyInfo property = null;
Type type = questionModel.GetType();
object value = questionModel;
object previousObj = null;
foreach (var part in questionId.Split('.'))
{
property = type.GetProperty(part);
previousObj = value;
value = property.GetValue(value,null);
type = value.GetType();
}
// here, if all goes well, property should contain the correct PropertyInfo and
// value should contain that property's value...and previousObj should contain
// the object that the property references, without which it won't do you much good.