Monthly Archives: 十二月 2010

ASP.NET MVC 3: Razor中的@:和语法

[原文发表地址] http://weblogs.asp.net/scottgu/archive/2010/12/15/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax.aspx [原文发表时间] December 15, 2010 11:48 PM 这是我正在写的博文系列中的另一篇,涵盖ASP.NET MVC 3的一些新功能: Razor中的新@模型关键字(10月19日) Razor中的层(10月22日) 用Razor实现服务器端注释(11月12日) Razor的@:和<syntax>语法(今天) 本文将讨论新版Razor里视图引擎中支持的两个有用的语法功能:@:和<text>语法。 用Razor实现流畅编程 ASP.NET MVC 3配有一个新的名为“Razor”的视图引擎选项(除了已有的.aspx视图引擎)。您可以在我发表的介绍Razor的博客上了解更多关于Razor的信息,比如我们为什么要引进它以及 它所支持的语法。 Razor尽量减少编写一个视图模板需要敲入的字符数,实现快速流畅的编程工作流。与大部分模板的语法不同,你不必在HTML中为了明确地标记出服务模块的开始和结束而中断编程。Razor解析器足够聪明,能从你的代码中推断出来。这使其简洁,富有表现力的语法输入干净,快速,有趣。 例如下面的代码片段迭代一列商品(product): 当运行时它产生的结果如下: Razor用来隐式鉴别一个代码段什么时候结束的一个方法是寻找代表内容块开始的标记或元素内容。例如,在上面的代码段中Razor自动地把foreach循环里面的<li></li>模块当作一个HTML内容块,因为它看到开始的<li>标记序列并且知道这在C#中是无效的。 这个独特的技术——使用标记来识别代码中的内容块——是使Razor在涉及HTML生成的情况下简洁高效的一个重要因素。 用@明确表示内容的起始 然而不是所有的内容块都是以标记元开始,在有些案例中,Razor解析器不能隐式检测出内容块。 这就需要Razor通过在代码块中使用“@:字符序列”来显式指明内容块的开始。@:序列表明该行后面的内容应该被视为内容块: 举个更实际的例子。下面的代码段显示在商品脱销的时候,我们如何在商品名旁边输出信息“(已售完!)”: 由于我没有将消息“已售完!”嵌套在HTML标签元素内,Razor不能隐式判断@if块中的内容是否是一个内容块的开始。我们用“@:字符序列”来明确地指出我们代码段里的这行应被当作是内容块。 在@:内容块中使用代码碎块(Code Nugget) 除了输出静态内容,你也可以使代码碎块嵌入以@:字符序列开始的内容块中。 例如,在下面的代码段中我们有两个@:字符序列: 注意我们在第二个@:序列中如何发送内容块中的单品(Unit)数目的(例如“只剩下3了!”)。我们通过在内容行中嵌入一个@p.UnitsInStock代码碎块来实现。 多行内容 Razor使在HTML元素中包装多行内容变得简单。例如,下面我们的@if容器中的内容块被包装在一个HTML<p>元素中,这会使得Razor把它当作内容: 对于在那些没有被外部HTML元素包装的多行内容情形,你可以使用多个@: 序列: 另外 ,Razor允许你用一个<text>元素 来显式标识内容: <text>标签是一个 Razor 特殊处理的元素。Razor将<text>块的内部内容视为内容块,不呈现包含那些内容的<text>标签(这意味着只呈现<text>内部内容,不呈现标签本身)。这使呈现没有被HTML元素包装的多行内容块变得方便。 如果你想要更简洁的@: 序列,<text>元素也能根据需要用来标识单行内容: 上面的代码将呈现出和我们早期看过的@:版本相同的输出。Razor会自动地从输出结果中省略掉<text>包装部件,只是呈现出<text>里面的内容。 总结 Razor启用一种简洁的模式化语法,实现非常流畅的编码工作流。  Razor能灵活地通过检测<tag>元素来识别内容块的起始, 从而让Razor方法在有HTML生成的场景中很有效,也使你不用明显地标注95% 的 if/else [...]

Posted in 未分类 | Leave a comment

用EF Code First和ASP.Net MVC3进行类级别模型验证

[原文发表地址] Class-Level Model Validation with EF Code First and ASP.NET MVC 3 [原文发表时间] December 10, 2010 1:05 AM 本周早些时候数据组发布了实体框架代码优先(EF Code-First)库新的CTP5版本。 我几天前的博客中谈到CTP5版中所引入的一些新改进。支持对模型上数据批注属性(Data Annotation Validation attributes)的自动强制验证是其中之一。它让你很容易地在模型层实现属性层验证逻辑。 你能应用验证属性attribute)—— 如.NET 4内置的[Required],[Range]—— [RegularExpression] 到你的模型类中,从而保证存储到数据库之前模型属性的有效性得到验证。你也能生成你自己的定制验证属性像这个比较酷的[CreditCard]validator)并将他们通过EF Code First自动强制实施。这是一个在你的模型中验证属性值的简单方法。我在我之前的博客展示了这种操作的一些示例代码。 使用IValidatableObject实施类级别模型验证 数据注释属性供了一种简单的方法来验证你的模型类中的单个属性值。 有些人问道:是否EF Code First也支持在模型对象上应用类级别验证方法,只管验证规则而不需要涉及很多属性值? 答案是肯定的——你有一个很简单的方法来实现:在你的模型类中实现IValidatableObject接口。 IValidatableObject.Validate()方法 下面是一个在Product模型类中使用IvalidatableObject接口(包含于.NET4的System.ComponentModel.DataAnnotaions命名空间内)实现两个定制验证规则的示例。这两个规则保证: 如果产品(product)处于断货状态,新单品(Unit)不能被订购 如果库存超过100 Unit,新单品(Unit)不能被订购 我们将通过实现我们的Product 类中的IValidatableObject接口和它的Validate()方法来强制实施这些商业规则,像这样: IValidatableObject.Validate()方法能应用涉及多个属性的验证规则,并返回多方个验证错误。每个返回的验证结果都提供一个错误消息和一个导致验证冲突的候选属性名称列表(这对显示UI内的错误信息非常有用)。 强制自动验证 在实现了IvalidatableObject接口的模型对象被保存的时候,EF Code First(自CTP5起)现在会自动调用Validate()方法。你无需写任何代码来实现它——现在这个是默认支持的。 这个新支持意味着下面违反了上面所说的一条商业规则的代码将在我们调用Northwind.DBContext的“SaveChanges()“方法的时候自动抛出一个异常(并中止事务)。   除了相应地处理验证异常之外,EF Code First还允许你主动检查验证错误。自CTP5开始, 你能调用DbContext基类的GetValidationErrors()方法来返回一列被处理模型对象中的验证错误。 [...]

Posted in 未分类 | Leave a comment

实体框架代码优先CTP5发布

[原文发表地址] Announcing Entity Framework Code-First (CTP5 release) [原文发表时间] December 08, 2010 1:39 AM 本周数据组发布了新实体框架代码优先(EF Code-First)库的CTP5版本。 EF Code-First提供了一个很好的以代码为中心的开发工作流程来处理数据。它使你能: 开发不需要打开设计器或定义XML映射文件; 只需编写 “普通传统类”来定义模型对象而无需定义基类; 使用“配置约定”方式保持与数据库的持久化映射,无需任何显式配置; 选择性地覆盖常规映射,用流畅(Fluent)代码API完全定制持久化映射。 我是实体框架代码优先的超级粉丝,还在今年夏天写了几个相关的帖子: 用实体框架4实现代码优先的开发(7月16日) 实体框架代码优先: 自定义数据库模式映射(7月23日) 在现有数据库上运用实体框架代码优先(8月3日) 相对CTP4,今天的新CTP5发布版提供了几个重要改进, 并且它将是最终版本前的最后一个预览版。我们将会在明年(2011)第一季度发布实体框架代码优先的最终版。它能与所有的.NET 应用类型兼容(包括ASP.NET网页和ASP.NET MVC项目)。 安装EF Code First: 你可以选择以下两种方法中的任一种来安装并使用实体框架代码优先: 方法1:下载和运行一个安装程序。装好后就可以在你的项目中引用其中的EntityFramework.dll程序集。 或: 方法2:使用Visual Studio内的NuGet Package Manager在项目中下载和安装EF code First。这只需要很简单地打开Visual Studio中的NuGet Package Manager Console(视图-> 其他窗口-> Package Manager Console),然后输入 “Install-Package EFCodeFirst”:   在Package [...]

Posted in 未分类 | Leave a comment

关于ASP.NET MVC 3 RC2的更新(和其中一个缺陷的替代解决方案)

[原文发表地址] Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it) [原文发表时间] Tuesday, December 14, 2010 4:53 PM 上周我们发布了ASP.NET MVC 3的RC2 版本,我博客这里写了很多细节。 我们发布候选发布版的一个原因是要 帮助找到那些最后的“难以发现的”缺陷。到目前为止,我们还没有收到很多RC2版上问题的报告(这是个好消息),尽管我们发现一些元数据缓存缺陷,表现为至少两种情况: 操作处理方法中可为空的参数存在着问题:对有可为空参数的控制器处理方法(像int? 型或是一个可以为空的次级属性的复杂类型),即使是请求包含参数的一个有效值的情况下,可空的参数结果总是是空的。 [AllowHtml] 在模型绑定中不允许HTML:即使用一个[AllowHtml]属性修饰一个模型属性(用来关闭HTML注入防护功能),在HTML内容传送给它的时候, 模型绑定仍然会失败。  这两个问题都是由于我们在RC2后期很晚的时候急于引进缓存优化造成的。我们将会在ASP.NET MVC 3终极版本中解决这个问题。你可以用下面的解决方案暂时避开这个问题。 现在可用的替代解决方案 你可以通过向应用程序中的Global.asax 类里的Application_Start()事件处理器中添加一行代码在当前的ASP.NT MVC 3 RC2版本中处理上面的问题:   上面的代码为使用     DataAnnotationsModelMetadataProvider类型设置了ModelMetaDataProviders.Current属性。这使ASP.NET MVC 3去使用元数据的提供程序,这个提供程序没有我们在RC2版本后期加入的过于积极的缓存逻辑,从而防止出现导致上面这些问题的缓存问题。  你不需要改变你应用程序中的任何其他代码。一旦你做了这样的改变,上面的问题就解决了。如果ASP.NET MVC 3的终极版发布,你的程序中不必有这行代码(尽管有这行代码的话也不会有任何问题)。 希望这对您有帮助,同时也希望您能向我们继续提供反馈。 Scott 除了发表博客,我现在也用Twitter保持快速更新并共享链接。请关注我: twitter.com/scottgu

Posted in 未分类 | Leave a comment