ASP.NET MVC 入门介绍

参考文章 ASP.NET MVC Overview.

  1. MVC模式

  MVC模式是一种软件架构模式。它把软件系统分为三个部分:模型(Model),视图(View)和控制器(Controller)。MVC模式最早由Trygve Reenskaug在1974年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk
明的一种软件设计模式。MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此
模式通过对复杂度的简化,使程序结构更加直观。软件系统通过对自身基本部份分离的同时也赋予了各个基本部分应有的功能。

  模型(Model)
“数据模型”(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“模型”有对数据直接访问的权力,例如对数据库的访问。“模
型”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作。但是模型中数据的变化一般会通过一种刷新机制被公布。为了实现这种
机制,那些用于监视此模型的视图必须事先在此模型上注册,从而,视图可以了解在数据模型上发生的改变.

  视图(View) 视图层能够实现数据有目的的显示(理论上,这不是必需的)。在视图中一般没有程序上的逻辑。为了实现视图上的刷新功能,视图需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。

  控制器(Controller) 控制器起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据模型上的改变。

  在最初的JSP网页中,像数据库查询语句这样的数据层代码和像HTML这样的表示层代码混在一起。经验比较丰富的开发者会将数据从表示层分离开来,但这通常不是很容易做到的,它需要精心地计划和不断的尝试。MVC从根本上强制性地将它们分开。尽管构造MVC应用程序需要一些额外的工作,但是它带给我们的好处是毋庸置疑的。

  首先,多个视图能共享一个模型。如今,同一个Web应用程序会提供多种用户界面,例如用户希望既能够通过浏览器来收发电子邮件,还希望通过手机来访问电子邮箱,这就要求Web网站同时能提供Internet界面和WAP界面。在MVC设计模式中,模型响应用户请求并返回响应数据,视图负责格式化数据并把它们呈现给用户,业务逻辑和表示层分离,同一个模型可以被不同的视图重用,所以大大提高了代码的可重用性。

  其次,控制器是自包含(self-contained)指高独立内聚的对象,与模型和视图保持相对独立,所以可以方便的改变应用程序的数据层和业务规则。例如,把数据库从MySQL移植到Oracle,或者把RDBMS数据源改变成LDAP数据源,只需改变控制器即可。一旦正确地实现了控制器,不管数据来自数据库还是LDAP服务器,视图都会正确地显示它们。由于MVC模式的三个模块相互独立,改变其中一个不会影响其他两个,所以依据这种设计思想能构造良好的少互扰性的构件。

  此外,控制器提高了应用程序的灵活性和可配置性。控制器可以用来连接不同的模型和视图去完成用户的需求,也可以构造应用程序提供强有力的手段。给定一些可重用的模型和视图,控制器可以根据用户的需求选择适当的模型机型处理,然后选择适当的的视图将处理结果显示给用户。

  2. Hello world 之 ASP.NET MVC 3

  如果还没有开发环境,先在这里下载Visual Studio 2010和mvc3. 新建一个MVC3项目,选择Razor模板引擎。VS已经建好了基本的目录结构和两个默认的页面。

 
 

查看下文件的代码,可以看到Controllers中的类是处理一些逻辑过程,最终返回View用来生成页面。Model中的代码表示的是数据和一些基
本的验证规则,View通过Model中的数据来填充。运行下程序,可以看到一个基本的网站。MVC网站的运行过程是这样的:

  1. 当第一个请求从客户端发起的时候,首先执行的是Global.asax中的Application_Start()方法来完成一些初始化工作,其中重要的一步是RegisterRoutes方法,这个方法指定了如何将url映射到具体的方法上,稍后详解。

  2. 根据第一步中指定的映射表生成一个RouteData对象,利用这个对象来创建一个RequestContext对象。

  3. MvcRouteHandler创建一个MvcHandler,并将RequestContext对象传给MvcHandler。

  4. MvcHandler对象利用RequestContext对象确定一个IControllerFactory对象来创建Controller对象。

  5. MvcHandler对象调用Controller对象的Execute()方法。

  6. Controller的ControolerActionInvoker对象决定调用controller的哪个具体的action方法。

  7. Action方法接受用户参数,执行方法,返回一个Result类型的对象。

  右击Controller文件夹,新建一空Controller,命名为HelloWorld,将代码改为如下:


public class HelloWorldController : Controller
{
   public string Index()
   {
       return "Hello world";
   }

public string Hello()
   {
       return "Hello everyone";
   }

public string Hello2(string name)
   {
       return "Hello to you " + name;
   }
}

  运行网站,在浏览器中分别访问
/Helloworld,/Helloworld/hello,/HelloWorld/Hello?name=jack,可以看到相应的字符串显示。这
个例子展示了url是如何映射到具体的方法上的。通常,我们并不直接在Controller中返回字符串,而是返回一个View,再新建一个
HelloController,不修改代码,直接在浏览器中访问/hello:

  

这是因为我们新建了Controller但没创建相应的View,ASP.NET会按照一定的路径去寻找View文件。在Index方法上右击,选择新建View:

  

然后会弹出如下对话框:

  

在此填入View的名字,选择视图引擎,每一种视图引擎支持一种视图语法,MVC3支持多种模板语法,可以通过不同的视图引擎来扩展实现。ASP.NET MVC早先使用的视图引擎是和asp.net的webform一样的。Razor引擎是MVC3新加入的引擎,还有一些开源的引擎可以用,例如NDjango就实现了类型Django的模板语法。在这个例子中选择Razor引擎。最下面可以选择一个MasterPage,这个和webform的母版页的概念是一样的,使用默认的_viewstart页面就可以。

  在新建的视图文件中写下一行html代码:


@{
   ViewBag.Title = "Index";
}
<h2>Hello My First View</h2>

  运行网站,访问/hello页面:

  

其中ViewBag是一个dynamic类型的对象,可以用来在controller和页面之间传递数据。将Controller的代码改为:


public ActionResult Index()
{
   ViewBag.Count = 4;
   return View();
}

  视图页面的代码改为:


@{
   ViewBag.Title = "Index";
}

<h2 >Hello My First View </h2 >
<ul >
@for (int i = 0; i  < ViewBag.Count; i++)
{
    <li >Hello @i </li >
}
</ul >

  

接下来来实现一个基本的增删改的功能。假设我们要对电影的基本信息进行管理,首先需要定义一个Model类型,新建一个Model,代码如下:


namespace HelloWorld.Models
{
   public class Movie
   {
       public int ID { get; set; }
       public string Title { get; set; }
       public DateTime ReleaseDate { get; set; }
       public string Genre { get; set; }
       public decimal Price { get; set; }
   }

public class MovieDBContext : DbContext
   {
       public DbSet<movie> Movies { get; set; }
   }
}

  接下来,我们新建一个Movie的Controller,使用EntityFramework来存取数据,如下配置:

  

点击Add后,可以看到一个具备基本功能的Controller已经建好。在View中,相应的CRUD页面也已经有了。我们还需要配置下数据库连接,在web.config中添加连接串的信息:

  

此时数据库和Movie表都还没有,不过没有关系,我们使用的 Entity Framework 4 的 Code First Development,它只需要一个平凡的类就可以了,EF会帮你完成创建数据库和数据库表的工作。运行网站,效果如下:

  

打开SQL Sever,可以看到Movie表:

  

如果Model文件发生了变化,例如添加了一个字段:


public class Movie
{
  public int ID { get; set; }        
  public string Title { get; set; }
  public DateTime ReleaseDate { get; set; }
  public string Genre { get; set; }
  public decimal Price { get; set; }
  public string Rating { get; set; }
}

  再运行下程序,就会发生错误:

 

 错误消息提示说数据库在model建立之后已经发生了变化,要解决有两种方案,一是调用Database.SetInitializer方法来自动重建
数据库,二是手动修改数据库表。第一种方法虽然简单但是会导致已有的数据丢失,他会重建整个数据库。但是在开发初期非常适合使用。在这里先采用第一种方
案。具体方法是,在model中新建一个类继承自DropCreateDatabaseIfModelChanges类。在其中可以加上可选的初始化数据的代码,代码如下:


using System;
using System.Collections.Generic;
using System.Data.Entity;

namespace HelloWorld.Models
{
   public class MovieInitializer : DropCreateDatabaseIfModelChanges<moviedbcontext>
   {
       protected override void Seed(MovieDBContext context)
       {
           var movies = new List<movie> {  
                new Movie { Title = "When Harry Met Sally",  
                            ReleaseDate=DateTime.Parse("1989-1-11"),  
                            Genre="Romantic Comedy",
                            Rating="R",
                            Price=7.99M},
                    new Movie { Title = "Ghostbusters ",  
                            ReleaseDate=DateTime.Parse("1984-3-13"),  
                            Genre="Comedy",
                             Rating="R",
                            Price=8.99M},
            };
           movies.ForEach(d => context.Movies.Add(d));
       }
   }
}</moviedbcontext>

  然后在Global.asax中将这个对象注册下:


protected void Application_Start()
{
  System.Data.Entity.Database.SetInitializer(new HelloWorld.Models.MovieInitializer());
  //其余不变
}

  再运行下程序,有可能会遇到这个错误:

  "This operation requires a connection to the ‘master‘ database.
Unable to create a connection to the ‘master‘ database because the
original database connection has been opened and credentials have been
removed from the connection string. Supply an unopened connection."

  我在这里找到了解决方法。需要把链接字符串中的Persist Security Info=true加上。然后程序就能正常运行了。运行之后,View页面并不会自动跟着改变,需要手动修改。修改完成后,看一下编辑页面:

  

这时候可以更新Rating字段。编辑页面还自带验证功能,不过是英文的,下面我们会改进这个验证功能。

上文,我们来完善验证功能。在System.ComponentModel.DataAnnotations命名空间中,已经有了一些基本的属性类来实现验证功能,只要把这些属性加到Model的字段上就可以了。具体的属性类可以查MSDN, 下面给出一个例子:


public class Movie
{
   [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int ID { get; set; }
   [StringLength(10,MinimumLength=2,ErrorMessage="必须是2~10个字符长"),Required,Display(Name="名称")]
   public string Title { get; set; }
   [Display(Name="发布日期")]
   public DateTime ReleaseDate { get; set; }
   public string Genre { get; set; }
   [Range(1,100,ErrorMessage="必须是1~100")]
   public decimal Price { get; set; }    
   public string Rating { get; set; }
}

  再运行下程序,就可以看到效果:

  当然,默认的验证往往并不足够,可以尝试下将日期改为201-01-1,点击Create,就会引发异常。我们可以增加自定义的验证属性来满足
验证要求。下面我们来实现一个DateAttribute属性来实现日期格式和日期范围的检查。新建一个动态链接库Biz.Web,添加
System.ComponentModel.DataAnnotations引用,新建一个类如下:


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.SqlClient;

namespace Biz.Web
{
   [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
   public class DateAttribute:ValidationAttribute
   {
       public DateAttribute()
       {
           //set default max and min time according to sqlserver datetime type
           MinDate = new DateTime(1753, 1, 1).ToString();
           MaxDate = new DateTime(9999, 12, 31).ToString();
       }

public string MinDate
       {
           get;
           set;
       }

public string MaxDate
       {
           get;
           set;
       }

private DateTime minDate, maxDate;
       //indicate if the format of the input is really a datetime
       private bool isFormatError=true;

public override bool IsValid(object value)
       {
           //ignore it if no value
           if (value == null || string.IsNullOrEmpty(value.ToString()))
               return true;
           //begin check
           string s = value.ToString();
           minDate = DateTime.Parse(MinDate);
           maxDate = DateTime.Parse(MaxDate);
           bool result = true;
           try
           {
               DateTime date = DateTime.Parse(s);
               isFormatError = false;
               if (date > maxDate || date < minDate)
                   result = false;
           }
           catch (Exception)
           {
               result = false;
           }
           return result;
       }

public override string FormatErrorMessage(string name)
       {
           if (isFormatError)
               return "请输入合法的日期";
           return base.FormatErrorMessage(name);
       }
   }
}

  主要实现IsValid方法,如有需要也可以实现FormatErrorMessage方法。要注意属性的参数只能是有限的几种类型,参考这里。写好以后,把HelloWorld项目添加Biz.Web引用,然后就可以使用了,例如:


[Display(Name="发布日期"),Date(MaxDate="2012-01-01",ErrorMessage="2012地球灭亡啦")]
public DateTime ReleaseDate { get; set; }

  看下效果:

  

当然,这种方式有许多限制,主要是属性参数的限制,只能是基本类型,而且只能是常量。更复杂的验证规则的添加请看这里:

  Implement Remote Validation in ASP.NET MVC.

  下面为lndex页面加上一些筛选功能。通过给Index传递参数来实现筛选,在页面添加一个selectbox来筛选Genre字段,把MovieController的方法改成:


public ViewResult Index(string movieGenre)
{
     var genre = (from s in db.Movies
                  orderby s.Genre
                  select s.Genre).Distinct();
     ViewBag.MovieGenre = new SelectList(genre);  //给前台准备下拉列表的数据。
     if (!string.IsNullOrEmpty(movieGenre))
     {
         //筛选
         var movies = from s in db.Movies where s.Genre == movieGenre select s;
         return View(movies);
     }
     return View(db.Movies.ToList());
}

  在View页面,添加一个Form,里面放上一个选择框和一个按钮,代码如下:


@using (Html.BeginForm("Index", "Movie", FormMethod.Get))
{
   <p>Genre: @Html.DropDownList("MovieGenre","全部")  <input type="submit" value="筛选" /></p>
}

  效果如下:

时间: 2024-10-04 21:25:51

ASP.NET MVC 入门介绍的相关文章

ASP.NET MVC 入门介绍 (上)

1. MVC模式 MVC模式是一种软件架构模式.它把软件系统分为三个部分:模型(Model),视图(View)和控制器(Controller).MVC模式最早由Trygve Reenskaug在1974年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发 明的一种软件设计模式.MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能.除此之外,此 模式通过对复杂度的简化,使程序结构更加直观.软件

学习 ASP.NET MVC 入门介绍

方法一: 基础知识要求: C# 学习信息 T-SQL 学习资料 HTML/CSS/JavaScript 学习资料 延伸推荐学习: BootStrap 学习资料 这是一种 HTML/CSS 统一语法标准的框架,你可以选择喜欢的模板. ASP.NET MVC 学习资料: MVC官方入门教程中文版 书籍: <Asp.net mvc 5 高级编程> 方法二: 极客学院 这里有大量的 ASP.NET MVC 的视频教程,并且有合适的学习规划.

ASP.NET MVC 入门8、ModelState与数据验证

数据验证包括服务器端验证和客户端的验证, 本文介绍的MVC数据库端的数据验证实现. 客户端的数制验证可以使用JQuery的验证插件来实现. Html.ValidationMessage()的时候,就是从ViewData.ModelState中检测是否有指定的KEY,如果存在,就提示错误信息. ValidationMessage(modelName) 指定控件的验证错误信息; ValidationSummary() 表单所有控件的验证错误信息. 验证未通过, 目标控件和验证错误信息HTML标签,都

ASP.NET MVC 入门系列教程

ASP.NET MVC 入门1.简介 ASP.NET MVC 入门2.项目的目录结构与核心的DLL ASP.NET MVC 入门3.Routing ASP.NET MVC 入门4.Controller与Action ASP.NET MVC 入门5.View与ViewData ASP.NET MVC 入门6.TempData ASP.NET MVC 入门7.Hellper与数据的提交与绑定 ASP.NET MVC 入门8.ModelState与数据验证 ASP.NET MVC 入门9.Action

26、ASP.NET MVC入门到精通——后台管理区域及分离、Js压缩、css、jquery扩展

本系列目录:ASP.NET MVC4入门到精通系列目录汇总 有好一段时间没更新博文了,最近在忙两件事:1.看书,学习中...2.为公司年会节目做准备,由于许久没有练习双截棍了,难免生疏,所以现在临时抱佛脚.深圳最近的天气反常,许多人感冒了,我也成为其中之一,大家注意身体... 这一篇,我来简单的讲一下接下来项目中会用到的一些杂七杂八的技术. 区域及分离 在15.ASP.NET MVC入门到精通——MVC-路由中,我已经简要说明了区域的分离. 1.右键单击Web项目,“添加”——“区域”,区域名,

Asp.net MVC入门视频教程

编程开发 > Asp.net视频教程 > Asp.net MVC入门视频教程 > 1.传统web处理方式和mvc处理方式 上传日期:2014-08-16 10:02:45  相关摘要:  - 怎么一创建传统补间就成了上下移动的了 - web 服务器 第一次进入站点速度慢是什么问题?? - EF中怎么处理像Sql多表连接的问题? 2.mvc项目会自动导入mvc程序集 上传日期:2014-08-16 10:14:51  相关摘要:  - Asp.net mvc 可以不用js吗 - 项目发布的

ASP.NET MVC 入门1、简介

什么是MVC模式 MVC(Model-View-Controller,模型—视图—控制器模式)用于表示一种软件架构模式.它把软件系统分为三个基本部分:模型(Model),视图(View)和控制器(Controller). 那么MVC模式和我们熟悉的WebForm模式有什么不同呢?他的各个部分又是怎样分工的呢? 我们先来看一下普通的WebForm模式下,我们请求一个例如http://www.51mvc.com/blog/index.aspx的URL,那么我们的WebForm程序会到网站根目录下去寻

ASP.NET MVC 入门4、Controller与Action

原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/04/1303672.html Controller是MVC中比较重要的一部分.几乎所有的业务逻辑都是在这里进行处理的,并且从Model中取出数据.在ASP.NET MVC Preview5中,将原来的Controller类一分为二,分为了Controller类和ControllerBase类.Controller类继承自ControllerBase类,而ControllerBase实现是了

ASP.NET MVC 入门2、项目的目录结构与核心的DLL

原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/03/1303521.html 我们新建一个ASP.NET MVC的Web Application后,默认的情况下,项目的目录结构如下: App_Data :这个目录跟我们一般的ASP.NET website是一样的,用于存放数据. Content :这个目录是建议用来存放一下资源文件的.例如CSS.JS.图片等等.当然你不愿意的话,完全可以不放到这里来. Controllers :这个目录