MVC强烈打字到ViewPage本身

时间:2013-11-11 04:19:44

标签: c# asp.net-mvc strong-typing asp.net-mvc-viewmodel

我看到很多关于强烈输入View模型数据的帖子。

我有兴趣以某种方式强烈输入View本身。

我担心,如果视图的模型类型发生更改,或者视图本身的名称/位置发生更改,则返回View(xyz)的控制器操作可能会在运行时崩溃。在我看来,MVC框架的松散耦合在这个特定领域过于苛刻,在RAD环境中变得适得其反。 (没有立即通知违规变化)

如果View()调用由于缺少.cshtml文件或不可映射的模型类型而无效,是否有办法触发编译时错误?

2 个答案:

答案 0 :(得分:5)

这个讨论是关于对象的早期和晚期绑定以及每个场景的固有优势。

早期绑定对象在编译时是已知的,但必须是有限集。它们不会产生与它们不存在的运行时错误,因为它们不会丢失,但是该集合是有限且不可变的。

在编译时不知道后期绑定对象 - 它们在运行时是已知的,并且可以是理论上无限的集合。后期绑定对象通常表示非常量 - 在应用程序运行时发生变化的事物。例如,像Unity或Ninject这样的依赖注入框架将从配置文件中进行后期绑定,以允许您注入几乎任何对象。如果Unity或Ninject要编译时验证注入的对象,那就意味着这些对象是早期绑定的,框架必须知道 ALL 可能的类型才能得到解决......如果你介绍了一个新类型,你需要重新编译框架才能接受它!

简而言之,后期绑定提供了灵活性,以适应未知的...例如您的MVC视图,Microsoft在发布框架时不知道这些视图。

MVC视图后期绑定的原因是它们不是一组固定的东西。相反,它们在运行时从许多来源(例如文件系统和内存对象)绑定,并且每个人的MVC项目将具有不同的视图。如果MVC在编译时验证视图,则必须在执行之前知道整个视图集。编译器将验证文件是否存在(在项目中正确引用),但不是控制器的ViewResults正确引用了文件。这样做的原因是它使您能够做大量的事情,包括动态地提供视图/数据。并非所有视图都来自磁盘...例如,没有什么能阻止您从MemoryStream中返回FileResult的字节数。作为另一个示例,您可以在数据库中拥有整个视图集,并安装自定义ViewEngine以直接从数据库记录中进行渲染。

ViewResult还支持非基于文件的其他类型的数据,例如返回二进制序列(图像或文件),XML,JSON等。 JSON通常在运行时从内存中的对象创建,因此编译时验证不会有用。

文件I / O也很慢,并且在初始加载后,视图通常会缓存在内存中。如果应用程序必须知道它在编译时在内存中缓存了什么,那么缓存就不会非常灵活或有用。

所以最终没有,没有 easy 方法来做到这一点。您可以编写一些不符合单元测试的单元测试:它们将执行每个Controller ActionMethods,然后调用ViewEngine来呈现视图并捕获任何未找到的文件错误。如果没有实质性的努力,那就差不多了。

可以预编译视图,以使视图中的错误成为编译时错误。默认情况下,当您的MVC应用程序运行并首次访问它们时,视图是JIT(即时编译)。如果您直接在记事本或其他文本编辑器中修改.csproj文件,您会看到<MvcBuildViews>设置为false - 只需将其设置为true,但要知道这会增加你的编译时间。

答案 1 :(得分:0)

如果您的模型如下:

public class MyModel
{
    public int MyInt = 0;
}

但您的观点执行以下操作:

@this.Model.MyOtherProperty

这将生成编译时错误(查看页面时)。如果视图尝试访问不存在的属性,则会发生错误。