MVC笔记 MVC注意事项及优化

2023-05-16

一、 学习MVC注意事项

1. 了解不同的项目类型

      从ASP.NET 2.0开始,vs针对网站开发区分了两种项目类型,一种是'项目'(Website Project),另一种是'网址'(Web Application Project)。两者最大的差别在于'项目'采用动态编译的架构运作。如:中只要编辑并存储了'App_Code'目录下的类或强类型数据集,就会使整个网站项目在后台重新编译,有时甚至会阻碍在vs中进行操作,若项目规模变大,就很容易拖慢开发速度。而MVC要求项目类型最好是'网址',可以利用自动化辅助功能开发。

2. 初学者常犯的错误

      对于习惯'项目'的人来说,当程序被修改保存后,即可直接切换至浏览器进行测试。但由于MVC需以'网址'的项目类型来开发,所以当程序被修改之后,都要先手动生成项目,才能将修改的结果编译进'bin'目录下组建中,这样才可以切换到浏览器测试,否则所做的修改都不会反映到页面上。

3. 小心使用Request对象和Response对象

      虽然在Controller中可以访问Request对象,但对于从客户端传来的QueryString或Form数据,建议不要通过Request对象取得,以免MVC项目难以维护。

     Response对象也是早期ASP和ASP.NET Web Forms中常用的对象,在controller中建议尽量不要使用。当然,使用它来响应页面内容更要不得。

     不过有规定就例外,只是提醒尽量不要用,并非不能用。如自行开发CAPTCHA图片验证功能时,可能需要通过Response对象响应经过动态运算的图片。

4. 不要在视图中编写过多的程序逻辑

       在开发MVC视图时,一定要尽可能的简化逻辑。不要将过多的商业逻辑写在代码里。

 

二、改良MVC项目

1. 使用视图数据模型

    上一篇中的留言板中,因为先前在 MvcGuestbook.edmx文件创建的'留言板'数据模型包含了5个字段,但是'id'与'建立时间'这两个字段在存储留言中用不到。这样,通过动作窗口接收数据时会有一定的安全风险。所以一些开发,针对一些有特殊目的的窗口或字段,会采用自定义模型的方式来定义。

TIP : 通过'Entity Framework'生成的'Model.留言板'类当成ViewModel使用,若save动作设定的参数类型为'Model.留言板',而且直接将接收到的对象保存到数据库中的话,原本预期只会收到3个参数,但黑客如果知道其他字段的名称(例如创建时间),就可能会多输入一个Form数据,进而复制进你的数据库,并调过字段的默认值。这样,数据库就被注入数据了。

      此类数据模型大多专用于视图中,也称为视图数据模型,即ViewModel。下面是ViewModel的创建过程。

      首先,在'Models'目录下新建一个数据类型(也就是一般的C#类),并将其命名为'GuestbookForm.cs',如图:

       由于留下足迹窗口中只有3个字段,所以在此类中要定义3个属性。具体如下:


1 namespace MvcApplication1.Models
2 {
3     public class GuestbookForm
4     {
5         public string name { get; set; }
6         public string Email { get; set; }
7         public string content { get; set; }
8     }
9 }  

       修改'/Views/Guestbook/Write.aspx'页面的"<% @page...%>"语句,将Inherits属性修改成强制类型,并将ViewPage的属性改为输入MvcApplication1.Models.GuestbookForml类,示例如下。注意,控制器的"return View();"语句不需要修改。


Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.GuestbookForm>"  

      接下来修改原程序中 '<%=Html.Label("name") %>'或'<%=Html.TextBox("name") %>'为MVC2.0新建的强制类型HTML辅助方法,如图,在此过程中还可以利用IntelliSense来编写程序,而且不必担心把字段名称写错。

NOTE: "Html.LabelFor(x=>x.name)"语句中的"x=>x.name"又称为Lambda表达式,是C#3.0/4.0提供的一种机制。

      至于最后输出到浏览器的页面,还是跟之前一模一样。

      接下来我们修改Save()动作。先回忆一下原来的声明,具体如下:


public ActionResult Save(string name,string Email,string content)  

     将以上代码修改如下:


public ActionResult Save(Models.GuestbookForm data)  

     我们将原来的3个参数改成只剩下一个,使用的一样是之前提到过的Model Binder机制。使用这个机制,将自动通过QueryString()方法或Form()方法传来的参数找到对应的强制类型中的属性。只要名称对上了,该机制就会把数据放入该对象的属性中。

      此时,Write视图和Save动作已经在无形中联系起来了,而且使用的是同一个数据模型。这种为了视图而另外定义的数据模型称为视图数据模型(ViewModel),修改完成的程序代码如下:


 1 [HttpPost]
 2         public ActionResult Save(Models.GuestbookForm data)
 3         {
 4             MvcApplication1.Models.GuestbookEntities db = new Models.GuestbookEntities();
 5 
 6             db.AddTo 留言板(new Models.留言板()
 7             {
 8                name =data.name,
 9                Email=data.Email,
10                content=data.content,
11                dtime=DateTime.Now
12 
13             });
14             
15             db.SaveChanges();
16             ViewData["name"] = data.name;
17             ViewData["Email"] = data.Email;
18             ViewData["content"] = data.content;
19 
20             return View();
21         }  

      这段程序代码跟之前差不多,只是参数变少了。但Write视图与Save地址共享用一个ViewModel及用强制类型的方式开发项目有着非常高的价值。如果日后数据库字段名称被修改了,通过VS2010内置的重构机制,将能更有效的针对整个项目进行字段名称的替换。

三、使用窗口验证功能

      好比避免之前留言为空就直接提交到数据库的情况。MVC内置了数据验证机制,只要搭配ViewModel及NET 5 SP1,或者.NET 4.0提供的Data Annotations的函数库,就能定义数据验证规则,同时实现客户端的验证与服务器端的验证了。

      要让GuestbookForm这个ViewModel在使用时能验证'姓名'与'内容'字段为必填项,而且希望当用户输入E-mail数据时能验证其格式,可以通过Data Annotations函数库的声明设定将这些功能应用在ViewModel上。以下是应用Data Annotations函数库的程序代码,可以看出,这里只是多加载了System.ComponentModel.DataAnnotations命名空间和新建了几个属性(Attribute)而已。暂时看不懂,没关系,先看看名字。猜猜用途。

 


 1 using System.ComponentModel.DataAnnotations;
 2 
 3 namespace MvcApplication1.Models
 4 {
 5     public class GuestbookForm
 6     {
 7         [Required]
 8         public string name { get; set; }
 9         [DataType(DataType.EmailAddress)]
10         [RegularExpression(@"^[a-z0-9\._%+-]+@[a-z0-9\.-]+\.([a-z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)$")]
11         public string Email { get; set; }
12         [Required]
13         public string content { get; set; }
14     }
15 }  

 

      利用ModelState.IsValid 验证,可以通过数据模型绑定进来的数据是否符合ViewModel字段验证的要求,如果验证失败,ModelState.IsValid验证就会返回"false"值,并转到"留下足迹"页面,如下:


 1  [HttpPost]
 2         public ActionResult Save(Models.GuestbookForm data)
 3         {
 4 
 5             if (!ModelState.IsValid)
 6             {
 7                 return RedirectToAction("Write");
 8             }
 9             MvcApplication1.Models.GuestbookEntities db = new Models.GuestbookEntities();
10 
11             db.AddTo 留言板(new Models.留言板()  

至此,我们已经完成了服务器验证的设置工作,接着来看MVC是如何让实现"客户端JavaScript验证"机制的,一共有一下3个步骤。

       Step01:打开"/View/Shared/Site.Master"文件,在"<head>…</head>"标记之间添加以下3个项目内置的javascript文件。


    <script src="http://www.cnblogs.com/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
    <script src="http://www.cnblogs.com/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
    <script src="http://www.cnblogs.com/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>  

       Step02:在"<%using (Html.BeginForm("save",RouteData.Values["controller"].ToString())) {%>"语句之前加入以下声明,以启用客户端验证功能。


 <%=Html.EnableClientValidation(); %>  

      TIP:若在一个页面中有两个或者两个以上的窗口需要进行验证," <%=Html.EnableClientValidation(); %>"语句必须出现在第一个Html.BeginForm声明之前,否则验证将无法执行。

      若要使用" <%=Html.EnableClientValidation(); %>"语句验证功能,必须使用Html.BeginForm声明窗口,用户自行编写的<form>标签无法正常使用此功能。

       Step03: 添加字段验证失败时要显示的错误提示信息。

        首先,添加所有验证失败结果的Html.ValidationSummary()方法,示例如下:


 <%=Html.ValidationSummary() %>  

        为每个字段加上ValidationMessageFor()方法,以显示验证失败的错误提示,示例如下:


 1       <%=Html.LabelFor(x => x.name) %>
 2       <%=Html.TextBoxFor(x => x.name) %>
 3       <%=Html.ValidationMessageFor(x=>x.name) %>
 4       <br />
 5       <%=Html.LabelFor(x=>x.content) %>
 6       <%=Html.TextBoxFor(x=>x.content)%>
 7       <%=Html.ValidationMessageFor(x=>x.content) %>
 8       <br />
 9       <%=Html.LabelFor(x=>x.Email) %>
10       <%=Html.TextBoxFor(x=>x.Email)%>
11       <%=Html.ValidationMessageFor(x=>x.Email) %>
12       <br />  

       完成以上3步,调试即可开始测试。

       HTML4.01标准规定的命名规则如下:

  • 首字必须是英文字母(A~Z、a~z)。
  • 首字后面可以是英文字母(A~Z、a~z)、数字(0~9)、减号(-)、下划线(_)、冒号(:)、小数点(.)。

      若有中文名称,可以选中右键然后选取"重建"——"重新命名"选项,或将键盘光标移至该属性名称处,再按下【F2】功能键,都能快速更改属性名称。如图:

四、避免用户重复发送信息

      目前留言板中后会停留在"储存留言"页面,如果此时用户按下了浏览器的"刷新"按钮,将导致窗口重复发送信息,那么在数据库中就会有两条重复的数据。为解决这个问题,PRG(Post-Redirect-Get)样式的概念,是许多网站经常使用的技巧之一。当遇到需要传送的窗口数据的情况下,会先通过HTTP POST请求送出数据;在处理完数据之后,立即转向(Redirect)另一个网址;最后通过HTTP GET请求取得跳转后的页面。在此,修改Save动作,让Save动作不再显示结果页面,而是直接转向Result动作。步骤如下:

      Step01: 删除下列程序代码。

 


1             ViewData["name"] = data.name;
2             ViewData["Email"] = data.Email;
3             ViewData["content"] = data.content;
4 
5             return View();  

 

      Step02: 在删除的程序代码处插入如下语句:


 return RedirectToAction("Result");  

      Step03: 删除"/Views/Guestbook/Save.aspx"页面。

      Step04: 新建Result动作,示例如下:


      public ActionResult Result()
        {
            return View();
        }  

       若要之前Save动作接收到的GuestbookForm类的数据传递给Result视图,以显示用户输入的摘要,这是就必须使用TempData机制来传递这种只会用到"1次"的数据。

      TempData是一个Directory对象,它与ViewData很像,但非常特殊。所有存储在TempData中的数据只能被参考一次,用过之后数据就会被清空。可以利用TempData的特性,将Save动作接收到的GuestbookForm类的数据传递给Result动作。修改Save动作的程序代码,如下:


 TempData["LastPostGuestbookFormData"] = data;  

      Step05: 修改Result动作,程序代码如下:


1      public ActionResult Result()
2         {
3             if (TempData["LastPostGuestbookFormData"] == null)
4             {
5                 return RedirectToAction("Index");
6             }
7             var model = (Models.GuestbookForm)TempData["LastPostGuestbookFormData"];
8             return View(model);
9         }  

      Step06: 新建Result动作视图。新建一个强类型视图,并选取适当的视图数据类型和视图内容之后,即可选取"Details"选项来显示单笔数据,如图:

       通过"视图内容"选项可以创建大部分的程序代码,只稍加修改,就可以得到我们需要的网页,示例如下:


 1 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.GuestbookForm>" %>
 2 
 3 <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 4     留言成功
 5 </asp:Content>
 6 <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
 7     <h2>留言成功</h2>
 8     <fieldset>
 9         <legend>Fields</legend>
10              
11         <div class="display-label">name</div>
12         <div class="display-field"><%: Model.name %></div>      
13         <div class="display-label">Email</div>
14         <div class="display-field"><%: Model.Email %></div>      
15         <div class="display-label">content</div>
16         <div class="display-field"><%: Model.content %></div>
17         
18     </fieldset>
19     <p>
20         <%: Html.ActionLink("Edit", "Edit", new { /* id=Model.PrimaryKey */ }) %> |
21         <%: Html.ActionLink("回到留言清单", "Index") %>
22     </p>
23 
24 </asp:Content>  

      再次运行,打开浏览器进行测试,留言成功后就会跳转到"http://localhost:1309/Guestbook/Result"页面,并显示上一页中GuestbookForm类的内容。如图:

      如果此时我们按下"刷新"按钮,由于"TempData["LastPostGuestbookFormData"]"语句已被删除,所以网页就会指向"http://localhost:1309/Guestbook"显示"留下足迹"的页面。

 

     

 

转载于:https://www.cnblogs.com/Eleanore/archive/2012/11/21/2780467.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVC笔记 MVC注意事项及优化 的相关文章

  • @Transactional注解失效场景之——同类中方法调用,事务失效

    文章目录 一 亲身案例 二 改进方式 三 原理分析 该篇博客为总结自己曾写下的Bug 一 亲身案例 当时的场景为 在controller层获取一笔交易单的信息 前台传给controller层为Map类型的键值对 然后controller层直
  • .NET MVC标签扩展(checkbox,radio)

    NET MVC里面自动绑定form表单功能 如 Html TextBox Name Html Hidden hide 名称会自动与后台就行绑定ViewBag Name ViewBag hide 很实用 但是感觉不足的就是 Html Chec
  • 手写Spring框架(三)

    这部分目标是MVC 主要完成3个重要组件 HandlerMapping 保存URL映射关系 HandlerAdapter 动态参数适配器 ViewResolvers 视图转换器 模板引擎 SpringMVC核心组件执行流程 相对应的 用以下
  • dao层代码

    dao层 数据接口层 方法层 介于业务逻辑层和数据库之间 进行数据的访问和操作 在实际业务处理过程中 往往需要进行多次数据库的访问 这些访问性质往往是相同的 采用Dao层可以将对数据库访问进行封装 避免经行重复性数据库访问开发操作 同时降低
  • 如何在 CentOS/RHEL 7 上安装 Laravel 8

    Laravel是一个开源 PHP 框架 旨在更快地使用 PHP 开发 MVC Web 应用程序 本文将帮助您在 CentOS RHEL 7 系统上安装 Laravel 8 PHP 框架 第 1 步 设置 Yum 存储库 首先 您需要在系统中
  • 网站发布一般步骤以及解决方法

    1 在D盘 随便一个地方 新建文件夹 2 在vs项目中点击发布弹出对话框 3 配置文件选择自定义 4 下一步 Publish method 选择file system 5 target location选择第一步创建的文件夹 6 下一步 f
  • 在Spring中配置多个View解析器

    1 简介 在Spring中 提供了View Resolver来使用模型中可用的数据来解析视图 而无需与JSP Velocity或Thymeleaf等View技术紧密绑定 Spring可以根据需要轻松灵活地配置一个或多个View Resolv
  • 控制台get的两种提交方式

    本次学习需要打开Visual Studio 2015简称 VS 开发工具 其他的版本也可以使用 打开进入页面创建项目 创建的项目命名为控制台get提交的两种方式 之后我们在软件默认的位置 保存的位置可以进行更改 之后就到更改的位置中查找 中
  • qml基础学习 模型视图(一)

    文章目录 一 理解qml模型和视图 二 效果展示 三 源码分析 1 GridView增删 2 列表 3 卡牌效果 四 相关文章 一 理解qml模型和视图 qt的发展是迅速的 虽然在每一个release版本中或多或少都有bug 但是作为一个庞
  • spring mvc中log4j的配置与使用

    原文地址 http rockelixir iteye com blog 1902352 如果使用spring插件创建一个spring template project 它会默认带log4j 只要改下log4j的配置就可以使用了 如果自己创建
  • MVC知识整理

    MVC基础知识整理 ASP NETMVC框架 这里以MVC5为例 涉及到知识有 Model View Controller的使用 Area和Global的理解 路由配置 数据传递的方式 AOP思想的体现 4大过滤器 各种Result Raz
  • MVC 向页面传值方式总结

    总结发现ASP NET MVC中Controller向View传值的方式共有6种 分别是 ViewBag ViewData TempData 向普通View页面传一个Model对象 向强类型页面传传一个Model对象 用一个ViewMode
  • Bootstrap弹出模态框的运用

    作者 张铭标 撰写时间 2019年 6月3日 Bootstrap模态框主要分为三部分 modal header modal body modal footer 在使用之前需要引入一些插件 bootstrap bundle js jquery
  • SpringMVC 框架详解

    目录 1 什么是 Spring MVC 1 1 什么是MVC 1 2 MVC 和 Spring MVC 的关系 2 第一个SpringMVC程序 2 1 RequestMapping 注解 2 2 ResponseBody 注解 2 3 g
  • 三层架构、MVC、前后分离的一些知识

    三层架构 MVC 前后分离的一些知识 三层架构模型 MVC模式 三层架构与 MVC 架构区别 前后端分离开发时的变化 一个前后端分离项目的分层 前端 MVVM 后端 Service层 Model层 Mapper映射 BLL业务逻辑层 DAL
  • JSP&EL表达式&MVC&三层结构综合案例

    文章目录 JSP 1 JSP 概述 2 JSP 快速入门 2 1 搭建环境 2 2 导入 JSP 依赖 2 3 创建 jsp 页面 2 4 编写代码 2 5 测试 3 JSP 原理 4 JSP 脚本 4 1 JSP 脚本分类 4 2 案例
  • 软件系统架构有哪几种?

    互联网飞速发展的当下 有一种极其重要的门类也随之应运而生 那就是软件工程 而软件工程中 又有非常重要的一环 那就是软件架构 这也是各个互联网公司无论大小都必备的一个系统基础 那么什么是软件架构呢 事实上 架构在软件发明时的 N 多年以前 就
  • 关于我写了三万字博客后悔了好久这件事之第二个三万字GUI(swing)

    目录 简介 使用Swing的优势 Swing的特征 Swing基本组件的用法 Swing组件层次 AWT组件的Swing实现 简单了解swing JFrame 弹窗 标签 面板 按钮 3 6 列表 3 7 文本框 JTree TreeMod
  • 简述关于ASP.NET MVC与.NET CORE 的区别

    简述关于ASP NET MVC与 NET CORE的区别 1 关于ASP NET 关于MVC 刚开始接触这个技术的时候我经常不理解他们的名字 我相信许多学ASP NET开发人员开始接触MVC应该也和我一样产生很多为什么 也会误认为认为MVC
  • vue +C# mvc 坑

    1 把input标签放入到form表单中后 再将input中的值新增到数据库后 界面会刷新 解决 删除form 标签 原因待查

随机推荐