我有一个用C#编写的ASP.NET MVC应用程序。我的应用程序有一个非常具体的一次性扩展方法。目前,我的扩展方法看起来像这样
public static MvcHtmlString CreateControl<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, IEnumerable<SelectListItem> items, object htmlAttributes = null)
{
var name = ExpressionHelper.GetExpressionText(expression);
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var model = htmlHelper.ViewData.Model;
...
int i = 0;
i = i + 1;
}
我在显示int i = 0;
的行上设置断点在Visual Studio的“监视”窗口中,我可以在model
中看到值列表。 model
有一个名为“MyValue”的属性。虽然我可以在“监视”窗口中看到它,但我无法弄清楚如何从我的代码中获取“MyValue”的值。 model
是TModel
。我似乎无法对它进行类型转换。另外,我没有看到辅助函数或任何东西。
如何从TModel
对象获取属性值?
答案 0 :(得分:3)
模型是
TModel
TModel
不是类型 - 它是泛型参数。您的扩展方法是通用的,这意味着它可以使用任何类型的模型运行。编译器无法在编译时知道模型具有哪些属性,因此在编译时无法在没有反射,强制转换或动态的情况下访问它们,所有这些都不是运行时安全的。
我的应用有一个非常具体的一次性扩展方法
不,该方法是泛型。它可以与任何类型的模型一起使用。如果您希望它特定于一种模型类型,则不要对模型类型进行泛化化:
V----- specific type ----------------V
public static MvcHtmlString CreateControl<TValue>(this HtmlHelper<MyModel> htmlHelper, Expression<Func<MyModel, TValue>> expression, IEnumerable<SelectListItem> items, object htmlAttributes = null)
{
var name = ExpressionHelper.GetExpressionText(expression);
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var model = htmlHelper.ViewData.Model;
...
int i = 0;
i = i + 1;
}
答案 1 :(得分:1)
您似乎有一个类型TModel
,要求它每次都具有相同的属性。我会让所有这些类型实现一个接口并添加一个这样的约束:
public interface IMyModel
{
MyValue { get; set; }
}
现在添加约束:
public static MvcHtmlString CreateControl<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, IEnumerable<SelectListItem> items, object htmlAttributes = null)
where TModel : IMyModel
{
var myModel = (IMyModel)htmlHelper.ViewData.Model;
//Now you can read the property:
var value = myModel.MyValue;
}