好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ASP.NETMVC3 pro系列翻译

ASP.NETMVC3 pro系列翻译

asp.netMVC的出现,让前台和后台都得到了一种回归,编程基础扎实的同学学MVC或许要比webform要轻松N倍,你不在为麻烦的控件配置而焦虑,这里只有纯净的前后台代码。 刚刚开始学习MVC,所以就加上自己的理解,翻译一些比较好的书籍和同学们一起来分享MVC3的精彩内容。如果有不合适的地方,大家可以指正和指导下我,我会马上修改。英文的资料看起来很容易但是要是用来写成文字,发现远远超过了读三章的时间,今天我几乎写了3.5个小时的博客到后面有点小浮躁,不知道翻译有没有出入,如有不妥大家都可以指正。

你的第一个MVC应用程序

   领悟一个软件开发框架 的最佳方式 是 深入内部并 使用它 。 在 这 本章中,您 将使用 ASP.NET   MVC 框架 创建一个 简单的数据输入 应用程序 。 我们要 一步步的让你 看到 如何 构建 一个 ASP.NET   MVC 应用 程序 。 为了简单易懂 ,我们将 跳过 一些 技术细节 的时刻 ,但 不要担心, 如果 你是 初识 MVC, 你会发现很多 让你 感兴趣的 。 在这里我们应用 但没有过多的 解释(这章的重点不是原理) ,在后面 我们 提供各个参考 的章节 , 在 这里 你可以找到 所有的细节 。

创建一个新的ASP.NET  MVC 项目

我们 将开始 在Visual Studio中 创建一个新的 MVC 项目 。 从 “文件” 中选择“新建 项目 ” 菜单打开 “ 新建项目 ” 对话框 。 如果您选择 的 网页模板 ,你会看到 MVC 3 安装 程序 ASP.NET   MVC 3   Web应用程序 创建 一个新的项目 , 如图3-1所示 。

图3-1 。 在Visual Studio中的 MVC 3 项目模板

  设置 的新项目 P名称为artyInvites , 并 单击 “确定” 按钮 继续 。 你会看到 一个对话框, 如图3-2所示 , 要求您 选择 三种不同类型的 MVC 项目模板。

     如果 仅仅是最低要求的文件和文件夹的MVC 3 应用程序你可以选择 创建一个 Empty项目。Internet应用程序“选项创建一个小的示例应用程序,您可以在他的基础上修改和建立自己的应用程序。它包括用户注册和认证,导航和一致的视觉风格。 Intranet应用程序选项是类似于Internet应用程序,但其设计中使用了对用户进行身份验证域/  Active Directory基础结构 的环境。在本章中,我们将让事情变得简单易懂。选择“Empty ” 选项,取消选中的HTML5语义标记选项,并 单击“确定” 以创建新的项目。

   注意 : 在 图3-2中 的 模板选项 中 , 你可以看到 一个下拉 菜单 ,在这里你可以指定需要的视图引擎 。 正如我们在 第1章 , MVC 3 包含一个 新的 Razor视图引擎 和改进的ASPX 视图引擎, 这是我们 将在 本书中群不全部使用Rozor 。 我们建议 你和我们一样这么选择 。 但是 , 如果你想 使用常规的 ASP.NET 视图引擎(又 称为 ASPX引擎 ) , 您也可以选择 它 。
  一旦 在Visual Studio创建 的项目, 你会在VS的“ 解决方案资源管理器” 窗口看到 一些 文件和文件夹结构 。 这是默认的 MVC 3 项目 的 结构 。 您 可以尝试运行
现在应用程序 从 “调试”菜单 中 选择 “ 开始 调试 ” ( 如果 提示您启用 调试时, 只要按一下 “确定”按钮 )。 您可以 看到 图3-3 中 的结果 。 应为我们开始 使用了Empty 项目模板, 应用程序不包含 任何内容 , 所以 我们可以看到 一个404 Not Found 错误 。

图3-3。 试图运行 一个空项目
  当你 完成后, 一定要 停止调试 , 关闭显示 错误 浏览器 窗口(当然也可以不关闭下次生成项目后刷新浏览器) , 回到Visual Studio , 并 从 “调试”菜单 中 选择 “ 停止 调试 。 在 MVC 架构 中 添加 一个控制器 , 由 控制器 处理 传入的请求 。 在 ASP.NET   MVC 中 , 控制器 简单 的 C# 类 ( 通常 继承 自 System.Web.Mvc.Controller 的 ,这是asp.netMVC 内置 控制器 基类)。 每个公共 方法被称为 控制器 的action方法 ,这意味着你 可以 通过 一些 URL 从Web调用和 执行一项操作(action) 。   MVC约定 是把
所有的控制器放在名为Controllers的 文件夹中 ,这 是我们创建 项目 时,由 Visual Studio创建 的 控制器 。 你并不 需要遵循 本约定 或其他大多数 MVC约定 , 但 我们 建议你这样操作 , 并不是简单的 因为这将有助于 你理解 这本书 中的例子 。

   右键单击 Controllers文件夹 中 的 Visual Studio解决方案 资源 管理 器 窗口,并 从 弹出的 菜单 中 选择“添加” ,然后 控制器 , 添加一个控制器到 我们的项目 中, 如图3-4所示 。

图3-4。添加控制器的MVC项目
  当出现 “ 添加控制器 ” 对话框时,将名称设置为HomeController的,如图3-5所示。 这又是一个约定:我们给控制器的名称应该是描述性和以Controller结尾 。

图3-5 。 设置 为控制器 的名称
  Scaffolding options中给 我们 预制了 控制器 使用 常见 功能 的 模板 。 我们不打算 使用 此功能 ,因此要确保在 “模板”菜单 中选择Empty controller , 如图所示。     注意 :如果 你没有看到 ,因为它是 在 图3-5 所示 的 “ 添加控制器 ” 对话框 中 , 你 可能 忘了 安装 工具更新 MVC 3 。 有关详细信息, 请 参阅 第2章 。

  单击 “添加 ” 按钮 , 创建一个控制器 。Visual Studio 将在Controller文件夹中 创建一个新的名为 HomeController.cs 的 C# 代码 文件 , 打开它进行编辑时, 你可以看到, 这个 被称为 HomeController的类 , 它是在 System.Web.Mvc命名空间下定义的 。 编辑 这个文件 中的代码 ,如下 3-1。

Listing 3-1. 修改 HomeController 类

 using   System.Web.Mvc; 
 
  namespace   PartyInvites.Controllers { 
 
          public   class   HomeController : Controller { 
           public   string   Index() { 
              return   "  Hello, world  "  ; 
        } 
    } 
} 
  

  当然这不足以 令人兴奋的 , 但对刚刚学习MVC的童鞋 , 这是一个很好 的开端 。 我们 创建了一个 名为为Index 的 action方法 ,它会返回 字符串“Hello, world” 。 再次 运行 该项目( 由 从Visual   Studio的“调试 ” 菜单 中 选择“启动 调试) 。 浏览器将显示 的结果。 如图3-6所示 。

图3-6 浏览器输出结果

了解路由
  除了 模型 ,视图和 控制器 ,MVC 应用程序也使用 ASP.NET 路由 系统 , 决定如何将 URL 映射到 特定 的控制器和action中 。
  当Visual Studio 创建 的MVC项目 , 它会添加一些 默认路由, 您可以 使用 下面的任何一个URL请求 , 他们 将被引导到 了HomeController 的 Index action :

?  / 
?  /Home 
?  /Home/Index

当 浏览器 请求 http://yoursite/ 的 或 http://yoursite/Home ,将调用 HomeController的Index 方法 。 输出 字符串“Hello , world ” 。 这 是一个很好的 遵循MVC 约定 的 例子 。 在这种情况下 , 我们将 有 一个名叫 HomeController的控制器 ,这将是 我们的 MVC 应用 程序 的起点 。 有 一个名叫 HomeController的 ,这将是 我们的 MVC 应用 程序 的起点 。 假设我们 遵循了这一 约定 Visual Studio会创建 一个新的项目 的 缺省路由 , 我们 的 UR LS 前面的列表中 得到支持 。 如果我们 没有依循 惯例 , 我们 将需要手动修改 的路由 指向 需要的 控制器 。 对于这个简单 的 例子 中 ,默认的配置 就够了 。

提示 :您 可以 通过打开 的Global.asax.cs文件 查看和 编辑您的 路由配置 。 在第7章中 ,您将设置 自定义 路由 表 项 ,并在 第11章 中 , 你 会学到 更多关于 路由可以 做 什么 。

渲染网页
 前面的例子不是输出HTML而是简单的字符串“Hello, world” 。 我们需要创建一个视图浏览器请求,响应HTML。
创建和渲染视图
我们需要做的第一件事情就是修改我们的索引中的操作方法,如清单3-2所示。
清单3-2。修改控制器渲染视图

 using   System.Web.Mvc; 
 
  namespace   PartyInvites.Controllers { 
 
      public   class   HomeController : Controller { 
 
          public    ViewResult  Index() { 
              return    View();  
        } 
    } 
} 
  

  在 清单3-2 以粗体显示 。 当我们 返回一个ViewResult 对象 从一个action 方法 , 我们 我们 通过 调用视图 的方法 创建 的ViewResult
(不带任何参数 )发出指令让 MVC 渲染视图 。 这将使 MVC为该action 呈现 的默认视图 。 如果您运行的 应用程序 , 你可以看到 MVC 框架 试图找到 一个默认的视图 显示 的错误信息如 图3-7 中 所示 。

如图3-7所示。  MVC 框架试图找到一个默认的视图
    错误消息是最有帮助的。它不仅解释无法为某个action方法找到一个MVC视图, 这又是一个很好的MVC约定 “ : view与action方法的命名约定。我们的action方法称为Index, 你可以从图3-7中看到的MVC正试图在“视图 ” 文件夹中找到不同的文件所有相同 名称。
  创建一个视图,用鼠标右键单击在HomeController.cs代码文件的操作方法(无论是在 方法的名称或内部的方法体),从弹出的菜单中选择 “ 添加视图 ” 。这将打开 添加视图“对话框,如图3-8所示。

     取消选中“ 使用布局或母版页。我们不使用布局,在这个例子中,但我们会看到他们 在第5章中使用。点击“添加”按钮,Visual Studio将在 View/ Home创建一个新的视图文件 Index.cshtml。如果你回头看看图3-7中的错误信息,你会看到,被搜查的路径之一与 我们刚创建的文件相匹配。
     提示: CSHTML的文件扩展名表明他是一个由Razor视图引擎处理的。老版本的MVC 依靠ASPX视图引擎,视图文件.aspx扩展名。
    打开Index.cshtml文件进行编辑。这个文件主要包含HTML。 其中有一段代码块如下:

 @{ 
    Layout  =  null  ; 
}  

   这是一个将被Razor视图引擎解释的代码块 。它只是告诉Razor视图引擎,我们选择不使用母版页。

如图Index.cshtml文件在清单3-3中所示

 @{ 
    Layout = null; 
} 
 
  <!  DOCTYPE html  >  
 
 <  html  >  
 <  head  >  
     <  title  > Index </  title  >  
 </  head  >  
 <  body  >  
     <  div  >   
        Hello, world (from the view)         
      </  div  >  
 </  body  >  
 </  html  >  

   添加一些简单的信息 。 选择“开始” ,从“调试”菜单中进行调试运行并测试应用程序。您应该会看到类似图3-9。

  当我们第一次 创建Index 的action方法,他除了输出简单的字符串返回给浏览器什么都没干 。 现在, 该 方法返回一个 ViewResult类型的对象 ,指示 MVC 渲染视图 ,并返回 HTML 。 我们没有并没有指定 MVC 视图应该 怎么做,所以 它 使用 的命名约定 自动匹配 。相应的View具有和controller文件夹中的action方法一样的名称—— ~/Views/Home/Index.cshtml. 我们可以让action方法 返回 其他结果( 除了 字符串 的ViewResult 对象) 。 例如, 如果我们返回 RedirectResult , 浏览器 重定向到 另一个 URL 。 如果我们 返回 HttpUnauthorizedResult , 我们 强制用户 登录 。 他们都 继承自 ActionResult类 。 action result 体系 让我们 封装和复用 常见的相应操作更加方便 。 我们将 通过 这本书告诉 你 更多关于他们 复杂的 使用 。 添加动态输出
  当然,对于整个Web应用程序 平台 的 构建 和 动态显示 输出来看 , 在 MVC, 准备响应 数据是 控制器的 工作 , 呈现 HTML则是 视图的 工作 。 数据 从控制器 传递 到视图 。
数据从控制器 传递 到视图 的 方法之一 是 通过 使用 ViewBag 对象 。 这是一个 Controller基类的成员 。   ViewBag 是一个动态对象 ,你可以 指定 任意的属性 , 并使这些值 呈现在 任何视图 中 。 清单3-4 演示
以这种方式 通过 一些简单的动态 数据 。

  Listing 3-4. Setting Some View Data 
   using   System; 
  using   System.Web.Mvc; 
 
  namespace   PartyInvites.Controllers { 
 
      public   class   HomeController : Controller { 
 
          public   ViewResult Index() { 
 
              int  hour =  DateTime.Now.Hour; 
            ViewBag.Greeting  = hour <  12  ?  "  Good morning  "  :  "  Good afternoon  "  ; 
              return   View(); 
        } 
    } 
} 
  

  以粗体显示的语句我们提供的数据的视图。 如清单3-5所示。

   Listing 3-5. Retrieving a ViewBag Data Value   
@{ 
    Layout = null; 
} 
 
  <!  DOCTYPE html  >  
 
 <  html  >  
 <  head  >  
     <  title  > Index </  title  >  
 </  head  >  
 <  body  >  
     <  div  >    
       @ViewBag.Greeting, world (from the view) 
       </  div  >  
 </  body  >  
 </  html  >  
 

     清单3-5 是一个Razor代码块,检索 保存在 的ViewBag的greeting属性。该属性名称没有什么特别的之处,你可以更换任何自定义属性名称(它的作用是相同的)。当然,你可以在视图中以相同的方式获取多个数据值的。

提示 : 我们并不需要终止Razor代码块。我们以@字符开始,然后添加我们的C#代码。这是Razor一个很好的特性。这样更具可读性,我们不在需要使用烦人的 < %和%>标记。

    如果我们再次运行该项目,我们可以看到我们的第一个动态的MVC输出,如图3-10所示。

创建一个简单的数据录入应用程序

    在本章的剩余部分,我们将通过建立一个简单的数据输入应用程序探讨更基本的MVC功能。在本节我们将加快进度。我们的目标是展示MVC的应用, 所以我们跳过一些的解释是后台是如何工作的的话题。但是不要担心,在后面的章节中,我们将再次深入这些话题。

设置场景

我们会想象,一个朋友已经决定举办一个除夕派对,她要我们创建了一个网站,让她受邀者使用电子邮件回复。她要求四个主要特点:

显示有关晚会的一个主页 提交RSVP的表单 验证RSVP的格式,之后将显示一个感谢页面 完成后回函电子邮件

在下面的章节中,我们将建立在已经创建的MVC项目中,我们在本章开始添加这些功能。通过运用我们在前面的内容中,我们可以添加一些HTML到我们现有的视图来描述party的细节,如清单3-6所示。

 

   Listing 3-6. Displaying Details of the Party 
  @{ 
    Layout = null; 
} 
 
  <!  DOCTYPE html  >  
 
 <  html  >  
 <  head  >  
     <  title  > Index </  title  >  
 </  head  >  
 <  body  >  
     <  div  >   
       @ViewBag.Greeting, world (from the view) 
         <  p  > We're going to have an exciting party. <  br   />   
       (To do: sell it better. Add pictures or something.) 
         </  p  >  
     </  div  >  
 </  body  >  
 </  html  >  
 

   您运行的应用程序,你会看到party的细节,如图3-11所示。

设计一个数据模型
在MVC中,M代表的是模型,它是应用程序最重要的的一部分。该模型是将 真实世界的对象,过程和规则抽象的定义在程序域中 , 通常被称为一个域模型,该模型包含了C#对象 已知的域对象),使我们可以在应用程序和方法中 对它们进行操作,并通过一些方式可以将其信息回馈给客户端 。一个精心设计的模型是一个设计良好的MVC应用程序的开始,现在我们把重点放在 添加控制器和视图。 我们并不需要为PartyInvites应用程序添加一个复杂的模型,这里我们只是用一个简单的名为GuestResponse域模型我们将使用用于负责存储,验证,并确认RSVP。

添加一个模型类
MVC 的约定是 , 一个模型 的类 被放置在 ?/   Models文件夹 。 在 “ 解决方案资源管理器 ” 窗口 中 右键单击“ 模型 , 并 选择”添加 类 从 弹出的 菜单。 设置文件名 GuestResponse.cs , 并 单击 “添加 ” 按钮 来创建类 。按照 清单 3-7 编辑 类的 内容 。

提示  您可能已经 注意到 , WillAttend 属性 是 一个可为空 的 布尔值, 这意味着它 可能是true , false, 或者为null。 “ 添加验证 ” 我们将在 后面的章节中 解释 “ 添加验证 ” 的 理由 。
链接操作方法
我们的应用程序 包括了 RSVP表单 , 所以 我们需要添加 一个链接到它 从 我们的 Index.cshtml 视图 , 如 清单 3-8 所示 。

     Listing 3-8. Adding a Link to the RSVP Form 
  @{ 
    Layout = null; 
} 
 
  <!  DOCTYPE html  >  
 
 <  html  >  
 <  head  >  
     <  title  > Index </  title  >  
 </  head  >  
 <  body  >  
     <  div  >   
       @ViewBag.Greeting, world (from the view) 
         <  p  > We're going to have an exciting party. <  br   />   
     (To do: sell it better. Add pictures or something.) 
         </  p  >   
       @Html.ActionLink("RSVP Now", "RsvpForm") 
      </  div  >  
 </  body  >  
 </  html  >  

   Html.ActionLink是一个HTML辅助方法。MVC框架集中方便的选择辅助方法的渲染HTML链接,文本输入框,复选框, 甚至是自定义的控件。  ActionLink方法 有两个参数:第一个是要显示的文本 的链接,第二个是要执行的action。 当用户点击的链接,您可以看到在图3-12中添加的链接效果。我们将 在第15和第16章中讲解HTML辅助方法。

  当你的 鼠标放 在浏览器中 的 链接上时 ,你会看到 该链接指向 ttp://yourserver/Home/RsvpForm 。 Html.ActionLink方法 检查 我们的 应用程序的 URL
路由配置 和执行HomeControls中的名为ResvpForm的action。 注意,不同于 传统的 ASP.NET 应用 程序 ,MVC 的 URL 不 对应于 物理 的 文件 。 每个action 方法都有其 自己的URL, MVC 使用 ASP.NET 路由 系统把这些urls指向 创建 的action方法. 如果 您单击的链接 , 你会看到一个 404 Not Found错误. 因为 我们还没有创建 的action方法
对应 的/Home/RsvpForm 中 的 URL 。 为此,我们要给 HomeController类 添加一个 名为 RsvpForm的方法 , 如 清单 3-9 所示 。

 Listing  3 - 9  . Adding a New Action Method to the Controller 
   using   System; 
  using   System.Web.Mvc; 
 
  namespace   PartyInvites.Controllers { 
 
      public   class   HomeController : Controller { 
           public   ViewResult Index() { 
 
              int  hour =  DateTime.Now.Hour; 
            ViewData[  "  greeting  " ] = hour <  12  ?  "  Good morning  "  :  "  Good afternoon  "  ; 
              return   View(); 
        } 
 
          public   ViewResult RsvpForm() { 
              return   View(); 
        } 
    } 
}  

添加一个强类型的视图
  我们给 RsvpForm 方法 添加 的视图 , 但我们会 做 一些调整 ,我们 要创建 一个 强类型的视图 。 一个 强类型的视图 的目的是 渲染 一个 特定的域 类型,如果 我们 指定 的类型 , 我们 使用 ( 在这个例子中是 GuestResponse ) , MVC 可以提供一些 有用 的 快捷 方式 ,使其更容易 。
   注意  在 做其他事情 之前 ,请确保 您 的 MVC 项目被编译 。 如果 您已经创建了 GuestResponse 类,但 没有编译 ,MVC 将无法 创建一个 强类型的视图 对应这种类型 。
从Visual Studio 生成“菜单 中 选择 ” 生成解决方案 编译 您的应用程序 。
  右键单击 里面 的 RsvpForm 方法 , 并 从 弹出的 菜单 中 选择 “ 添加视图 ” 。 在 “ 添加视图 ” 对话框 中 , 选中 “ 创建一个 强类型的视图 选项,并 从 下拉 菜单 中选择 GuestResponse 。 取消选中“ 使用 布局 或母版页 ,并确保 选择 Razor 引擎布局 模板 “ 选项 设置为空 ,如图 如图3-13所示。

  单击 “添加 ” 按钮 , 创建新的视图 。 Visual  Studio将打开 RvspForm.cshtml 文件 , 你会看到 ,它是一个 一个@ model Roazr格式开头 的 HTML 文件 。 正如你将看到
当前这已经是 一个强类型的 视图, 它 提供 的很多的便利 。
建立 表格
  现在, 我们已经创建了 强类型的视图 ,我们可以在 RsvpForm.cshtml文件中 编写 一个HTML表单 用于 编辑 GuestResponse 对象 。如下 清单 3-10。

   Listing 3-10.  Creating a Form View 
@model PartyInvites.Models.GuestResponse 
 
@{ 
    Layout = null; 
} 
 
  <!  DOCTYPE html  >  
 
 <  html  >  
 <  head  >  
     <  title  > RsvpForm </  title  >  
 </  head  >  
 <  body  >   
    @using (Html.BeginForm()) { 
          <  p  > Your name: @Html.TextBoxFor(x => x.Name)  </  p  >  
         <  p  > Your email: @Html.TextBoxFor(x => x.Email) </  p  >  
         <  p  > Your phone: @Html.TextBoxFor(x => x.Phone) </  p  >  
         <  p  >   
            Will you attend? 
            @Html.DropDownListFor(x => x.WillAttend, new[] { 
                new SelectListItem() {Text = "Yes, I'll be there", Value = bool.TrueString}, 
                new SelectListItem() {Text = "No, I can't come", Value = bool.FalseString} 
            }, "Choose an option") 
          </  p  >  
         <  input   type  ="submit"   value  ="Submit RSVP"   />   
    } 
  </  body  >  
 </  html  >    

 

   对于GuestResponse模型类的每个属性,我们使用一个HTML辅助方法渲染一个合适的HTML input标签 。这些方法会让你选择输入元素的属性,涉及到
使用lambda表达式,例如:
@  Html.TextBoxFor (X =>  x.Phone )
  不要担心,如果你不熟悉C#lambda表达式。我们在第5章中提供了一个概述。
  HTML辅助方法生成的HTML生成一个input 元素, 设置它的type为text,并设置id和name属性为Phone,而这些都是以的域模型的属性名为准,如下
属性,如下所示:
<input  id="Phone"   name="Phone"   type="text"   value=""
 
这个方便的特性依赖于此处的RsvpForom方法对象的视图是强类型的,我们已经告诉过MVC,操作的是 GuestResponse类型,我们要渲染这个View。
另一种替换lambda表达式的方法是使用一个名称相同的字符串类型的属性, 例如:
@  Html.TextBox (“电子邮件 ” )

我们发现, 我们 的lambda表达式 技术可以防止 输错 的模型名称 和相应的属性。 Visual Studio会 弹出智能提示 让 我们挑选 的合适的并自动完成关联 , 如图3-14所示 。

    另一种方便的辅助方法是Html.BeginForm,生成一个HTML表单元素并配置回发的操作方法。因为我们还没有传递任何参数给该方法,它会认为我们要回发到相同的URL。一个使用它的绝招是用C#using 声明包装它,例如:

 @using (Html.BeginForm())

{  

   ...form contents go here...

}

    通常情况下,这样的应用时,使用的语句确保一个 超出范围对象被及时释放。它常用于数据库操作中,例如,在完成一个查询以确保他们 尽快关闭,(这里的using关键字不同于讲一个外部类用一个命名空间引入到一个类的作用域中的using),而不是丢弃对象, HtmlBeginForm helper在HTML表单元素超出的范围自动将其释放。这意味着该 Html.BeginForm辅助方法创建的表格元素,像这样两个部分:

<form action="/Home/RsvpForm" method="post">

    形式内容到这里...

</ FORM>

  不要担心,如果你不熟悉C#对象的处理。这里的关键是演示如何创建使用HTML辅助方法的一种形式。

提示   ASP.NET   WebForm 只支持一个 服务器端的控件 , 通常注明为 <form   runat="server"> , 这是一个 视图状态数据 和 回传 逻辑的容器 。 MVC则不需要 这种的 形式 。我们只需要使用 使用 普通的HTML标签 , 你可以在 一个视图中 素心所欲的使用 。而不必担心 没有 视图状态(ViewState)或 其他 隐藏的表单元素 的id值 分配 错位 。 当您运行 的 应用 程序 ,然后单击“ 现在 的 RSVP 链接 , 你可以看到 的形式 在 RsvpForm 视图 。 图3-15显示了 结果。

  请注意: 这不是一本关于CSS网页设计。在大多数情况下,我们将要创建的例子,它的外观可以被描述为乡巴佬(虽然我们喜欢这个词的经典之作,但不是轻蔑)。MVC视图生成非常干净和纯洁的HTML,你可以完全控制他们被分配到的布局元素和类,所以你可以使用设计工具或现成的模板,让你的MVC项目漂亮。

 处理表单

  我们没有告诉MVC的形式发送到服务器时,我们想要做的是什么。就目前情况来看,点击 “Submit RSVP “ 按钮,会清除任何你输入到表单中的值。这是因为,表单回发后只是调用了Home controller中的RsvpFrom方法,告诉MVC再次查看视图.

   注意  当 输入的数据 再次呈现 视图时 丢失 , 你可能会 感到失望 。 如果真是这样, 你宁可使用 ASP.NET WebForm 开发应用程序,因为他有 自动保存 数据 的功能。 现在, 我们将向您展示 MVC 如何实现 同样的效果 。 接收和处理 提交的表单数据 , 我们 要做 一个聪明 的 事情 。 我们将再添加一个 RsvpForm 的action方法 :
  ? 响应HTTP   GET请求 方法 : GET请求是 什么 浏览器 问题 通常 每次有人 点击一个链接 。 这个 版本的操作 会 负责 显示初始 的 空白表格 ,当有人 第一次访问 / Home/         RsvpForm 。
  ? 响应 HTTP   POST 请求 的方法 : 默认情况下, 表单 呈现H tml.BeginForm()方法 提交 一个 POST 请求 的 浏览器 。 这个版本的 action 将 负责 接收 提交的数据 ,并决定 如何处理。

  将GET和POST请求在单独的C#方法处理有助于保持我们的代码整洁,因为这两个方法有不同的责任。这两个action方法调用相同的URL,但MVC会调用适当的方法。
清单3-11。增加一个action方法来支持POST请求

 

 using   System; 
  using   System.Web.Mvc; 
  using   PartyInvites.Models; 
 
  namespace   PartyInvites.Controllers { 
 
      public   class   HomeController : Controller { 
 
          public   ViewResult Index() { 
 
              int  hour =  DateTime.Now.Hour; 
            ViewData[  "  greeting  " ] = hour <  12  ?  "  Good morning  "  :  "  Good afternoon  "  ; 
              return   View(); 
        } 
         [HttpGet] 
          public   ViewResult RsvpForm() { 
              return   View(); 
        } 
 
        [HttpPost] 
          public   ViewResult RsvpForm(GuestResponse guestResponse) { 
              //   TODO: Email guestResponse to the part organizer  
             return  View( "  Thanks  "  , guestResponse); 
        } 
    } 
} 
  

    我们已经添加了的HTTPGET特性,RsvpForm的action方法。这是告诉MVC,这种方法只能用于GET请求。然后,我们添加了一个重载的方法RsvpForm,其中需要一个GuestResponse类型的参数用应用HttpPost特性。告诉MVC新的方法将处理POST请求。请注意,我们导入了PartyInvites.Models命名空间。所以下面代码中无需类的全限定名。

使用模型绑定
  第一个重载的RsvpForm的action方法,使用之前相同的View。它产生的形式如图3-15所示。第二个重载是更有趣,因为传入了参数,但考虑到
该action方法将作为HTTP  POST 请求的响应被调用,但是GuestResponse类型是一个C#类,怎么怎么进行关联呢?

  答案是绑定Model,这是MVC一个非常有用的功能,即输入的数据进行解析被用来填充的域模型类型的属性的键/值对。这个过程和使用HTML辅助方法相反的,也就是说,当创建的表单数据发送给客户端,我们生成的HTML输入元素的id和name属性的值来自在模型类的属性名。与此相反,与模型的结合,输入元素的名称是
用于设置模型类的一个实例的属性值,然后将其传递给处理的POST请求的action方法。
  模型绑定是一个强大的和可定制的功能,让我们不再面的琐碎的与HTTP请求,而是让我们的面向C#对象,(不用在处理的Request.Form[]的Request.QueryString[]值。)  GuestResponse 对象作为参数被传递action方法中自动去填充表单字段的数据。在第17章中我们将深入到模型的bind的细节也包括如何自定义。。。

渲染视图

  第二个重载的在RsvpForm的action方法,还演示了如何响应一个请求,渲染特定视图。如下面的语句:
  return View("Thanks", guestResponse);

   它通知 MVC查找和渲染名为“Thanks”的视图,并传入我们的GuestResponse对象。创建的视图,右键单击里面的其中一个RsvpForm 方法,并从弹出的菜单中选择 “ 添加视图 ” 。设置名称为“Thanks”.

如图3-16所示。

     我们将创建另外一个强类型的视图,因此在 “ 添加视图 ” 对话框中,我们选择的视图模型必须与传递给视图中使用的View方法的类一致,所以必须从Modles class下拉列表中选择GuestResponse。确保选择母版页 “ 选项没有被选中,视图内容设置为空。 单击“添加” 创建新的视图。MVC创建了一个新的视图文件,~/Views/Home/Thanks.cshtml.编辑新的视图,如 Listing 3-12 。

 Listing 3-12.  The Thanks View 
@model PartyInvites.Models.GuestResponse 
 
@{ 
    Layout = null; 
} 
 
  <!  DOCTYPE html  >  
 
 <  html  >  
 <  head  >  
     <  title  > Thanks </  title  >  
 </  head  >  
 <  body  >  
     <  div  >  
         <  h1  > Thank you, @Model.Name! </  h1  >   
        @if (Model.WillAttend == true) { 
            @:It's great that you're coming. The drinks are already in the fridge! 
        } else { 
            @:Sorry to hear that you can't make it, but thanks for letting us know. 
        }     
      </  div  >  
 </  body  >  
 </  html  >  

  Thanks View使用Razor显示基于GuestResponse类的属性值的内容,通过RsvpForm的action方法访问视图。@model运算符指定View的域模型的是强类型的类型。要访问域对象的属性值,我们使用Model.PropertyName。例如,得到的Name属性的值,我们使用,Model.Name。不要担心,如果的Razor语法不熟悉 - 我们将在第5章解释它 现在,我们已经创建了Thanks View启动应用程序 Visual Studio中,单击“RSVP”链接,之后添加一些数据,并单击“SubmitRSVP“按钮。你会
看到如图3-17所示的结果(虽然它可能会有所不同,如果你的名字是不是Joe,或者你选择 不能参加)。

 

添加验证
     现在我们为应用程序添加验证。如果我们不这样做,我们的用户可以输入垃圾数据,甚至提交一个空的表单。在MVC应用程序中,验证通常应用在域模型中,而不是在用户 接口。这意味着,我们在同一个地方定义我们的验证标准,它在任何地方生效。 ASP.NET   MVC 支持声明System.ComponentModel.DataAnnotations命名空间的属性定义的验证规则。

清单3-13显示了如何将这些特性应用于到的GuestResponse的模型类。

  上面用粗体显示了验证规则。  MVC 检测验证属性,并使用它们来 来验证数据模型的绑定过程。请注意,我们导入了 包含验证类的 命名空间。
  提示 如前所述,我们使用了一个可为空的布尔的WillAttend属性。所以我们可以应用 必要的验证属性。如果我们用一个普通的布尔值,该值可能是我们通过模型绑定 唯一的true或false的,我们将不用去告诉如果用户怎么样选择一个值。可空布尔有三个 可能的值:true,false和null。空值将被使用,如果用户还没有选择的一个值,这 所需的属性来报告验证错误。 我们 在我们的控制器类 可以使用ModelState.IsValid属性检查验证状态 。

清单3-14显示了如何做到这一点

  如果没有验证错误,我们告诉MVC渲染Thanks视图。如果有验证错误,我们重新呈现的RsvpForm之前的视图,并将错误显示给用户我们需要显示给用户,验证错误,我们可以使用Html.ValidationSummary辅助方法,如清单3-15所示。

如果有 没有错误 , Html.ValidationSummary 的 方法 创建一个隐藏的  MVC 的占位符 ,并添加 验证 属性 定义 错误消息 。 你 可以看到这 显示 在 图3-18 。

注意 :如果 您使用过 ASP.NET   WebForm , 你就会知道, “服务器控件, WebForm 通过 序列化到 __VIEWSTATE的 隐藏的表单字段 的 值 保持状态 。   ASP.NET   MVC 模型绑定
不同于Web Form 的服务器控件 , 回发, 视图状态 的 概念 。   ASP.NET   MVC 不 注入 隐藏 的__VIEWSTATE 字段 到您的 渲染 HTML 页面 。
高亮显示验证

     HTML helper方法是创建文本框 ,下拉框和其他元素的HTML的辅助方法,它有一个非常方便的功能,可用于与模型绑定。同样的机制,可以保留的数据表单中输入的用户也可以 用于突出显示 个别字段失败验证检查。

  当一个模型 类的属性 未通过验证, HTML辅助方法 会产生 轻微 不同的 HTML。 举个例子 ,这里的 HTML是 调用 Html.TextBoxFor ( X = >   x.Name 的 ) 产生的
如果没有验证错误将是如下代码 :

 <  input   data-val  ="true"   data-val-required  ="Please enter your name"   id  ="Name"   name  ="Name"    
type  ="text"   value  =""   />  
 

  当用户 没有提供一个 值(这是 一个 验证错误 , 因为 我们调用了 GuestResponse 模型类Name属性 的 Required验证约束 )你会看到代码略有不同:

 <  input   class  ="  input-validation-error  "   data-val  ="true"   data-val-required  ="Please enter your  
name"   id  ="Name"   name  ="Name"   type  ="text"   value  =""   />  
 

   我们 加粗以 突出显示 的不同之处 。这个helper方法添加一个CSS类,称为 input-validation-error 。不同的辅助方法适用于不同的CSS类,但它们都可以在~/Content/Site.css的样式表中找到。怎么引入该样式表,是这样的:

 <link rel="Stylesheet" href="@Href("~/Content/Site.css")" type="text/css"/>  

   提示 :如果 你 已经使用了 ASPX 视图引擎 , 您 可以 使用 指定路径 直接使用 符号(?) (如 :HREF =“?/ 内容 / 的Site.css 的 ” ) , 并 依靠 视图引擎 转换 到 一个 URL ,浏览器 可以按照 (如  href="~/Content/Site.css" ) 。 Razor视图引擎 采用不同的方法 。 它要求 使用 HREF 运算符 将URL (如 : HREF   href="@Href("~/Content/Site.css")" ) 。 在第5章中 , 你可以找到 更详细的介绍。

  现在,当用户 提交数据 , 将导致验证错误 , 他 会看到 一个更加 明显方式展示 问题的根源 , 如图3-19所示 。

完成示例
  我们的应用程序中 的 最后 一个 要求 是 我们的朋友, 使用 电子邮件 完成给 组织者的 回函 。 我们可以通过 添加action 方法并 使用 . NET 框架 中e-mail类 来创建和 发送 电子邮件 的 信息 做到这些, 不过这里 ,我们将 使用webmail 的 辅助方法 。 这 不 是 MVC框架 的 一部分 ,但它确实 让 我们完成这个 例子 中 的细节 ,而不用 设立 其他的 发送电子邮件形式 。
请注意  我们使用了webmail 的 辅助方法 ,因为它让 我们 发送 电子邮件 消息 的变得不费吹灰自理 。 然而 , 通常情况下, 我们 宁愿 把这个 功能 的放在一个action方法中 。 在第4章中描述了 MVC 架构模式时 , 我们将解释 为什么 。

清单 3-16  Using the WebMail Helper 

 @model PartyInvites.Models.GuestResponse 
 
@{ 
    Layout  =  null  ; 
} 
 
 <!DOCTYPE html> 
 
<html> 
<head> 
    <title>Thanks</title> 
</head> 
<body>  
 
    @{ 
          try   { 
            WebMail.SmtpServer  =  "  smtp.example.com  "  ; 
            WebMail.SmtpPort  =  587  ; 
            WebMail.EnableSsl  =  true  ; 
            WebMail.UserName  =  "  mySmtpUsername  "  ; 
            WebMail.Password  =  "  mySmtpPassword  "  ; 
            WebMail.From  =  "  rsvps@example.com  "  ; 
 
            WebMail.Send(  "  party-host@example.com  " ,  "  RSVP Notification  "  , 
                Model.Name  +  "   is   "  + ((Model.WillAttend ??  false ) ?  ""  :  "  not  "  )  
                     +  "  attending  "  ); 
             
        }   catch   (Exception) { 
            @: <b>Sorry - we couldn '  t send the email to confirm your RSVP.</b>   
         } 
    } 
 
     <div> 
        <h1>Thank you, @Model.Name!</h1>  
        @if (Model.WillAttend  ==  true  ) { 
            @:It  '  s great that you  ' re coming. The drinks are already  in  the fridge!  
        }   else  {             @:Sorry to hear that you can '  t make it, but thanks for letting us know.  
         }     
     </div> 
</body> 
</html> 
 

   我们增加了一个Razor代码块,使用 WebMail 的辅助方法 配置电子邮件服务器,包括服务器名称,服务器是否需要SSL连接,和帐户详细信息。
一旦我们配置了所有的细节,我们就可以使用WebMail.Send的方法来发送电子邮件。这里我们使用在try ... catch块,如果不发送电子邮件不成功也可以提醒用户。 一个更好的 方法是如果 不能发送 的 电子邮件 消息 将 显示一个单独的 错误 视图而不是在同一个View中显示各用户 , 但 我们希望保持 我们的第一个 MVC 应用 程序 中 的简单易懂(所以暂时不这么做)。

总结
在本章中, 我们 创建了一个新 的 MVC 项目 , 并 用它来 构建一个简单的 MVC 数据输入应用程序 ,让你 一睹 MVC 框架结构 和方法的魅力 。 我们跳过了 一些关键的功能 (包括 Razor语法 ,路由 和自动测试 ) , 但 在后面的章节中 , 我们 会回头来 深入 这些主题 。 在下一章中 ,我们将探讨 的 MVC 架构 ,设计模式 和 技术 ,并 贯穿全书 。

 

分类:  asp.netMVC ,  ASP.net历程系列

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于ASP.NETMVC3 pro系列翻译的详细内容...

  阅读:50次