【发布时间】:2015-07-23 16:49:11
【问题描述】:
我正在尝试在强类型视图上创建 HtmlHelper 方法,其中视图模型是通用的。但是有一个并发症。我想简化我的语法,以便我可以在我的视图模型上指定属性的成员表达式。请考虑以下内容。
public interface ViewModel<T>
{
T Model { get; set; }
}
public class DocViewModel : ViewModel<Document>
{
public IEnumerable<string> Options { get; set; }
public Document Model { get; set; }
}
public class Document
{
public string Name { get; set; }
public string Value { get; set; }
}
现在,我可以轻松地创建一个引用视图模型本身的助手,并像这样使用它:
@model DocViewModel
<div>
@Html.DoSomething(vm => vm.Options);
@Html.DoSomethingElse(vm => vm.Model.Name);
@Html.DoSomethingYetAgain(vm => vm.Model.Value);
</div>
但我希望能够在模型上简单地传递一个表达式,如下所示:
@model DocViewModel
<div>
@Html.DoSomething(vm => vm.Options);
@Html.DoSomethingElse(vm => vm.Name);
@Html.DoSomethingYetAgain(vm => vm.Value);
</div>
现在,如果我在调用中显式引用类型参数,我可以编写帮助程序:
@model DocViewModel
<div>
@Html.DoSomething<Document>(vm => vm.Name);
</div>
但这有点违背了我追求的目的。似乎我应该能够编写一个 HtmlHelper,它可以利用视图在 DocViewModel 上是强类型的这一事实,它本身就是一个 ViewModel,并且 @Html() 返回
HtmlHelper<DocViewModel> //HtmlHelper<ViewModel<Document>>
以便隐式知道 Document 表示的类型参数,以便我可以编写
public static string DoSomethingElse<TModel, TProperty>(this HtmlHelper<ViewModel<TModel>> helper, Expression<Func<TModel, TProperty>> expression)
{
return "Whatever";
}
但无法完成该转换。那么有什么办法可以做到这一点吗?还是我只能忍受丑陋的语法?
编辑:将对“KoViewModel”的错误引用更改为“ViewModel”
再次编辑:另外,使 ViewModel 通用的目的是我可以声明任何其他类型的 ViewModel:
public class ProgramViewModel : ViewModel<Program>
{
//other stuff
public Program Model { get; set; }
}
public class Program
{
public string Something { get; set; }
//other properties I want to reference
}
在另一个方面:
@model ProgramViewModel
<div>
@Html.DoSomethingElse(vm => vm.Something)
</div>
再次,我希望能够取消引用视图的视图模型以及视图模型的 Model 属性的属性,而不必在我的方法调用中显式引用类型。
我上面定义的方法的问题是HtmlHelper和HtmlHelper之间显然不能进行隐式转换,以至于编译器无法解析视图中的@Html调用如上图(“不包含定义”)对于并且没有扩展方法等等等等”)。当然,到处都是显式强制转换可以使这项工作奏效,但这是我要避免的。
【问题讨论】:
-
您必须在使用泛型时指定类型
<T> -
在什么上指定
?该视图的类型为 WebViewPage 。 DocViewModel 是 KoViewModel ,所以我认为有一种方法可以将 T 隐式解析为 Document。 -
我怀疑它无法识别
TProperty的类型。在这种情况下,通常第二级泛型会有所帮助,例如Html.DoSomthingForModel().ForProperty(vm -> vm.Name)... 确切的错误可以帮助诊断问题(不依赖自定义类的独立示例也很好)。
标签: c# asp.net-mvc-3 generics viewmodel html-helper