当前位置: 首页 > 编程日记 > 正文

MVC系列1-MVC基础

终于决定写一个系列的文章了,最开始其实是准备写一下WPF的,因为我这两年一直在做WPF,对WPF的喜爱自然是无以言表。但是由于我所在的地区对WPF的普及不是很广泛,所以,被迫又开始做起来web,但是我又不想在传统的web froms上工作。固而开始研究MVC。在看完了一本入门级的MVC书籍之后,我又转而开始爱上MVC。它轻量,简洁,扩展性和对html的深度控制这些特性会打破ASP.NET的开发模式。但是,也不是说MVC就能解决一切问题。它就是所有的编程模式中最好的,它也会有它的一些不足。可是我们想想,世界上有什么东西又会是完美的呢?对于我们程序员而言,语言,IDE就是我们工具。只要用着顺手,能写出高效的代码就行了。管它谁人说那种语言好还是不好呢。废话说得有点多,我更新这个系列的文章是为了对自己学习的一个总结,并且分享给尚在学习阶段的兄弟。在园子里写得比我好的大牛很多。所以,欢迎指正错误与不足。

既然这是介绍MVC,那我们就来说说什么是MVC。传统的MVC其实是一种理念。旨在分离关注点。及把我们的系统按照不同的关注点分离开来。这样系统以各自的关注点分离开来。整个系统的可维护性,扩展性都会大大的提高。整个系统的层次结构也会更加的清晰。我们这里所谈的MVC其实是ASP.NET MVC。ASP.NET MVC其实是一种框架。以ASP.NET为平台的框架,也就是说,其实它其实还是运行在ASP.NET运行时上的,微软根据MVC的理念,在ASP.NET上封装了一套遵循了MVC理念的框架。我们的程序在理论上大部分的时候是在处理数据,而数据的处理方式是遵循特定行业的特定业务逻辑。以界面来展示数据。那么至少从这里我们可以抽象出一下几个关注点

  • 界面
  • 界面逻辑
  • 业务逻辑
  • 数据

在这个时刻,我们至少是可以总结出以上的关注点,遵循分离关注点的原则,我们至少要把这些关注点给分离开来。

  在这里,我们是把数据和业务逻辑放在了一起。因为从领域编程的角度,数据也好,业务逻辑也好。他们都是属于某些特定领域的。比如金融领域,航空领域。所以这里他们是可以放在一起的,其中还会包括一些其他的,比如验证,属性标注等等。

我们看上面的一张图可以看到。关注点被分离。MVC的全称是Model-View-Controler。这里不正是我们关注的分离点吗

从这里我们可以总结以下的概念

视图:一个动态生成HTML页面的模板
  模型:模型是描述程序设计人员感兴趣问题域的一些类,这些类通常封装存储在数据库中的数据,以及操作这些数据和执行特定域业务逻辑的代码。在ASP.NET MVC中,模型就像是一个使用了某个工具的数据访问层,包括实体框架。
  控制器:一个协调视图和模型之间关系的特殊类。它响应用户输入,与模型进行对话,并决定呈现哪个视图。

   我们现在来具体的解读他们之间的联系和各组件之间是怎么通讯和协作的,首先,我们来看View,View的作用很直接,就是现实用户的数据,获取用户的交互。也就是获取输入然后经过处理展现数据。上面一句话提到了“经过处理”,这里就又有了另外的一个问题,经过什么处理,什么东西来处理。其实就是我们的Controler。它获取用户的输入,经过自己的处理逻辑然后将数据处理操作交给Model进行处理。Model处理了业务逻辑,完成数据之后会有两种操作,一是由Controler处理界面逻辑,更新数据,然后View展现数据。第二种方式是处理完数据,由数据直接反应更改到View。这个时候是不经过Controler处理界面逻辑的,他们之间的关系是一个三角关系。可以从下面的一张图来看出他们之间的关系。

  从上图我们可以看到M-V-C之间的通讯。这些都只是理论层面上的,从代码层面我们现在还没有看到代码的执行过程。下面我们来看一个最简单的MVC程序,执行的深层原理我们以后再讲,这一章我们只是看一个最简单的程序,看看MVC的执行过程。
  首先,我们需要创建项目,打开VS,新建一个MVC空项目。这里顺便多说一句为什么是空项目。因为这样VS不会帮我们创建范例代码。如果不选择空程序,VS会帮我们创建一些范例代码来让我们了解MVC。


我们这里选择空模板,视图引擎我们选择Razor。视图引擎指的是我们操作界面的方式。比如怎么利用数据组合html。这里我们不用深究Razor,以后的章节会讲到Razor。测试项目我们这里暂时就不创建,因为我们单单就是一个示例程序,不需要那么复杂。创建项目之后我们可以看到如下的文件夹结构。

这里我们解释一下各个文件夹的用途

  • App_Data:存放应用程序的数据文件,比如数据库文件,XML等等。
  • App_Start:存放应用程序启动时需要的些类,这里是路由和路由注册的类(路由的概念以后会讲到)
  • Controlers:Controler类的存放目录
  • Models:Model的存放目录
  • Views:View的存放目录
  • Global.asax:全局处理,包含应用程序启动时需要执行的代码,这里是使用App_Start里面的一类来注册路由
  • packages.config:NuGet包管理(暂时不需要了解,以后会讲到)
  • web.config :这个大家都很熟悉了,网站的配置文件

按照一般的文件夹结构应该是还会有Content这个文件夹,至少在VS2010里是有这个文件件夹的,但是我这里的VS2012是没有这个文件夹的。这个文件夹存放的是网站的一般资源文件,比如js脚本,图片,CSS文件等等,如果没有我们可以手动添加一个,或者添加一些我们自己的文件夹。好了,项目我们是新建出来了,那么,我们该怎么开始呢?我们前面讲到了MVC实际就是Model-Controler-View。我们就从这里开始。首先我们新建一个Contrler,命名为HoneControler。具体的步骤是我们可以右键点击Controllers文件夹,添加Controller。
  我们可以看到如下的界面,这里我们一切留空,除了命名。模板我们以后再来深入的了解。这里我们只是简单的看看MVC怎么执行的。点击确定之后我们可以看到如下的代码

namespace FirstMVC.Controllers
{public class HomeController : Controller{//// GET: /Home/public ActionResult Index(){return View();}}
}
View Code

下一步我们修改生成的代码,我们把返回类型改为string,然后返回一个字符串

namespace FirstMVC.Controllers
{public class HomeController : Controller{//// GET: /Home/public string Index(){return "Welcome, MVC";}}
}
View Code

下面我们就可以直接启动项目了,我们可以看到路径是http://localhost:3222/之类的。我们在Index中返回的字符串直接输出到浏览器。这里我们就完成了一个最简单的MVC。但是这个例子是不够来解释我们MVC的整体执行过程的。我们在这个例子的基础上扩展来说明执行过程。这里,我们一步一步的来完成我们完成的数据读取的示例。
  我们添加一个方法到我们的HomeController,方法名为ShowMessage。

        public ActionResult ShowMessage(){return View();}
View Code

这里需要先解释这几句代码,这里定义了一个返回值为ActionView的方法。ActionView是 一个抽象类型,是指操作(这里是ShowMessage方法)的结果,我们这里的结果就是返回一个View,也就是我们的视图。可以看到我们直接返回了View()。这里我们需要再解释一个概念-约定优先于配置
约定优先于配置:在以前的很多时候,我们在想要自定义应用程序中的一些行为时我们会使用配置文件,或者使用配置文件来制定应用程序中的一些特定行为。约定优先于配置是后来提出的一种概念。它的理念是大家一致遵守一种约定以取代配置对程序的特定行为的指定。这里我们的约定就是

  • 控制器类以Controller结尾
  • 在View文件夹下有一个与控制器同名的文件夹存在
  • View文件夹下与Controller同名的文件夹下的视图(.cshtml-一种新的类型)的名称与控制器中Action(方法)名称相同。

所以,这里当我们直接Retrue View()的时候,解释引擎会直接找到View----Home----ShowMessage视图。所以下面,我们需要添加一个与ShowMessage方法对应的View。我们可以右键点击ShowMessage方法。选择添加视图。就会生成对应的视图。

@{Layout = null;
}<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width" /><title>ShowMessage</title>
</head>
<body><div><h1>This is ShowMesage Page!</h1></div>
</body>
</html>
View Code

到这里我们的控制器和视图已经定义完成。打开浏览器输入http://localhost:3222/Home/ShowMessage我们可以看到我们在ShowMessage.CSHTML中的h1标签的内容。这里需要注意一点,URL的端口请于自己机器具体端口相关。好了,到了这里,我们要解释程序的执行过程了。

当URL进入通道后,运行时会感觉URL配置来获取Controller,Action和参数,URL路由的配置在RouteCongfig类中,代码如下

    public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
View Code

我们可以看到这里定义了路由规则url: "{controller}/{action}/{id}"不同的部件以“/”隔开。所以这里划分我们的URL,Home就是控制器的名称,ShowMessage就是Action的名称,参数我们这里没有。所以根据划分得到的URL,下面的执行步骤就是实例化HomeController调用ShowMessage方法,而ShowMessage方法返回的是ShowMessageView。所以,我们就可以在浏览器中看到ShowMessageView了。
 在URL路由规则中,有一行代码defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },这里指定的是默认值,也就是当我们的URL没有指定Controller,Action,参数时的默认值。回到上面我们最开始的URLhttp://localhost:3222/。这里,我们没有指定Controller,Action。所以运行时会使用默认的路由配置来填充URL。这里就会指向http://localhost:3222/Home/Index。

我们使用了一个示例解释了MVC的执行过程,但是这里可以看到,我们的示例完全只使用了C和V,没有使用Model。所以,我们继续完善我们的示例,加入数据操作,在Model文件夹下新建一个实体类Person。

public class Person{private int _personId;public int PersonId{get { return _personId; }set { _personId = value; }}private string _firstName;public string FirstName{get { return _firstName; }set { _firstName = value; }}private string _lastName;public string LastName{get { return _lastName; }set { _lastName = value; }}public Person(){this.PersonId = 1;this.FirstName = "Edrick";this.LastName = "Liu";}}
View Code

在HomeController中添加一个新的Action,名称为ShowPerson,添加完Action之后添加对应的View,我们要使用这个View来显示Person的数据。

    public class HomeController : Controller{//// GET: /Home/public string Index(){return "Welcome, MVC";}public ActionResult ShowMessage(){ return View();}public ActionResult ShowPerson(){Person person = new Person();ViewBag.Person = person;return View();}}
View Code

ShowPerson View代码如下

@{Layout = null;
}<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width" /><title>ShowPerson</title>
</head>
<body><div><p>@ViewBag.Person.PersonId</p><p>@ViewBag.Person.FirstName</p><p>@ViewBag.Person.LastName</p></div>
</body>
</html>
View Code

在HomeController中,我们实例化了Person并且在实例化的时候插入了数据。并且把person装入ViewBag中以供视图使用。这里也就是使用Controller建立了View和Model的联系,但是这种联系是弱类型的。并不是直接建立在View和Model之间的。这里我们先只了解ViewBag实际是一个数据集合。以后会详细的解释ViewBag。

最后,在浏览器中键入地址http://localhost:3222/Home/ShowPerson 可以看到我们的person数据。这样我们就完成了一个典型的MVC程序。当然也是最简单的,我们先只需要了解什么是MVC,MVC是怎么执行的等等。以后的章节我们会详细解析每一个模块。

转载于:https://www.cnblogs.com/ColeLiu/p/MVC.html

相关文章:

洛谷 P1816 忠诚

题目描述 老管家是一个聪明能干的人。他为财主工作了整整10年&#xff0c;财主为了让自已账目更加清楚。要求管家每天记k次账&#xff0c;由于管家聪明能干&#xff0c;因而管家总是让财主十分满意。但是由于一些人的挑拨&#xff0c;财主还是对管家产生了怀疑。于是他决定用一…

电子学会青少年编程等级考试Python案例08

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 案例&#xff1a;绘制兔子时钟 代码 import turtlet turtle.Pen()# 表盘 t.p…

Python组合数据类型之序列类型

单元概述 主要解决问题&#xff1a;让程序更好地处理一组数据 三类重要组合数据类型&#xff1a;集合类型、序列类型和字典类型 学完本章&#xff0c;我们能够在头脑中建立集合、序列和字典的模式来表达对一组数据的表达和处理 1. 定义 序列是具有先后关系的一组元素 -序列是…

hdu-3071 Gcd Lcm game---质因数分解+状态压缩+线段树

题目链接&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid3071 题目大意&#xff1a; 给定一个长度为n的序列m次操作&#xff0c;操作的种类一共有三种 查询 L :查询一个区间的所有的数的最小公倍数modpG :查询一个区间的所有的数的最大公约数modp修改 C :将给定位置…

一个比较保守的404页面

<HTML><HEAD><TITLE>您访问的页面不存在 请转到首页进入</TITLE> <META http-equivContent-Type content"text/html; charsetGB2312"> <META http-equivrefresh content"5;URL /"> <STYLE typetext/css></S…

【组队学习】【34期】组队学习内容详情

第34期 Datawhale 组队学习活动马上就要开始啦&#xff01; 02月09日&#xff08;星期三&#xff09;&#xff0c;宣发&#xff0c;2月组队学习计划&#xff01;。02月12日&#xff08;星期六&#xff09;&#xff0c;进入学习群、开营仪式。 本次组队学习的内容为&#xff1a…

Python组合数据类型之字典类型

单元概述 主要解决问题&#xff1a;让程序更好地处理一组数据 三类重要组合数据类型&#xff1a;集合类型、序列类型和字典类型 学完本章&#xff0c;我们能够在头脑中建立集合、序列和字典的模式来表达对一组数据的表达和处理 1. 定义 首先理解“映射”的概念 -映射是一种键…

maven 插件:Tomcat7

配置 Tocmat 用户 > vim $TOMCAT_PATH%/conf/tomcat-users.xml <tomcat-users><role rolename"manager-gui"/><role rolename"manager-script"/><user username"tomcat" password"linuxmint" roles"mana…

电子学会 软件编程(图形化)二级训练营

电子学会 软件编程&#xff08;图形化&#xff09;二级训练营 试题来源 青少年软件编程&#xff08;Scratch&#xff09;等级考试试卷&#xff08;二级&#xff09;【2019.09】青少年软件编程&#xff08;Scratch&#xff09;等级考试试卷&#xff08;二级&#xff09;【2019…

MacOS无法登录App Store修复

MacOS无法登录App Store修复 2017-03-10 21:13:39 by&#xff1a;SemiconductorKING 先上图&#xff1a; 惨红色的提示信息&#xff0c;把你拒之App Store门外&#xff0c;但是对之放弃、不与之斗争不是我们的节奏&#xff0c;请看破敌攻略&#xff1a; 1.查看你的“关于本机”…

Python文件的使用

本章导言 什么是数据格式化 前言&#xff1a; -学完本章&#xff0c;看待数据会有一种规范/格式化的视角 -方法论:从Python角度理解文件和数据表示 -实践能力:学会编写带有文件输入输出的程序 1. 文件的使用 文件的类型 -文件是数据的抽象和集合&#xff0c;可理解为存储在…

datagridview 点击列标题排序

开发winform中&#xff0c;平时经常用到数据列表&#xff0c;我们大多选用datagridview&#xff0c;但是此控件本身没有排序的功能。参阅网上资料。留下标记&#xff0c;以后备用。 datagridview的数据显示一般是通过数据绑定来实现&#xff0c; 即&#xff1a;this.datagridvi…

围绕圆心形旋转

2019独角兽企业重金招聘Python工程师标准>>> 实现了围绕圆心旋转功能 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Roation : MonoBehaviour {public float range 10;void Update () {float x Mathf.Sin(Mathf.…

【组队学习】【34期】阿里云天池在线编程训练营

阿里云天池在线编程训练营 航路开辟者&#xff1a;陈信达、杨世超、赵子一、马燕鹏领航员&#xff1a;武帅、初晓宇、叶前坤、邱广坤、朱松青航海士&#xff1a;宁彦吉、肖桐、汪超、陈信达、杨世超、赵子一、武帅、初晓宇、叶前坤、邱广坤、朱松青、马燕鹏 基本信息 学习平…

Python一维二维数据的格式化和处理

本章导言 什么是数据格式化 前言&#xff1a; -学完本章&#xff0c;看待数据会有一种规范/格式化的视角 -方法论:从Python角度理解文件和数据表示 -实践能力:学会编写带有文件输入输出的程序 1. 数据组织的维度 维度&#xff1a;一组数据的组织形式-线性还是二维或更高维…

让你的网站提速:图片优化网站推荐

页面的加载时间是每一个设计师都担心的数据&#xff0c;或者至少是每个设计师都应该担心的问题。图片的大小肯定是一个需要留意的问题。这就是为什么在这里写了几个有助于优化页面中的图片的小技巧&#xff0c;这些小技巧将有助于大家解决这个问题&#xff0c;这些小技巧也可以…

JAVA对图片的任意角度旋转,以及镜像操作

package relevantTest;/* * 该代码实现了对图像的水平镜像变换&#xff0c;垂直镜像变换&#xff0c;任意角度旋转&#xff0c;jtf的实时监控&#xff0c;以及对图像的缩放变换&#xff0c;以及按钮的若隐若现效果。 * 在对图像进行任意角度旋转时最好是在原始图片未进行任何操…

【组队学习】【34期】百度飞桨AI达人创造营

百度飞桨AI达人创造营 航路开辟者&#xff1a;百度飞桨领航员&#xff1a;六一航海士&#xff1a;阿水、颜鑫、宋泽山、刘洋、张文恺 基本信息 内容属性&#xff1a;合作课程练习平台&#xff1a;https://aistudio.baidu.com/aistudio/course/introduce/25259?ad-frompdg-1…

安装Python第三方库的三个方法

方法一: (cmd命令行) pip 方法【主要方法&#xff0c;适用于99%的情况】【依赖网络状况】 在命令行输入pip -h 可查看该命令帮助信息 常用pip命令 ① pip install <第三方库名> 安装指定第三方库 参数 -U :update对已经安装的进行版本更新 ② pip uninstall <第三方…

java 基础---继承

继承 一&#xff0c;概述 a) 使用extends关键字可以让一个类继承另一个类&#xff0c;继承的类为子类&#xff0c;被继承的类是父类&#xff0c;子类会自动继承父类的所有方法和属性。 b) 继承使得类和类之间产生了关系 c) 子类可以使用super调用父类成员…

建立CentOS 6.9 的Yum本地源

1、建立一个本地Yum的软件仓库1mkdir /media/cdrom2、把CentOS6.9光盘装载到/media/cdrom1mount /dev/cdrom /media/cdrom3、安装createrepo1 rpm -ivh /media/cdrom/Packages/createrepo-[按tab键] deltarpm-[按tab键] python-deltarpm-[按tab键] createrepo-0.9.9-26.…

【组队学习】【34期】零基础学python编程思维

零基础学python编程思维 航路开辟者&#xff1a;邓林权领航员&#xff1a;沈一航海士&#xff1a;覃嘉俊、马子阳、左凯文 基本信息 开源内容&#xff1a;https://linklearner.com/datawhale-homepage/index.html#/learn/detail/6内容属性&#xff1a;公测课程内容说明&…

Python wordcloud库使用说明

1. 介绍 wordcloud是优秀的词云展示第三方库 -词云以词语为基本单位&#xff0c;更加直观和艺术地展示文本 通过词云&#xff0c;我们可以快速提取大段文本的重要信息 2. 安装 (cmd命令行) pip install wordcloud 3. 使用 w wordcloud.WordCloud()代表一个文本对应的词云…

resin-pro-4.0.34 服務器在windows环境下的配置

resin-pro-4.0.34 服務器在windows环境下的配置(轉載请注明作者:icelong) 到caucho網站上http://www.caucho.com/download/下載resin-pro-4.0.34 Windows下載zip版&#xff0c;Linux下載tgz版 Install JDK 1.4 or later. On Unix, set the JAVA_HOME variable or link /usr/jav…

【组队学习】【34期】Python(一级)

Python&#xff08;一级&#xff09; 航路开辟者&#xff1a;王思齐、马燕鹏领航员&#xff1a;马燕鹏航海士&#xff1a;马燕鹏 基本信息 开源内容&#xff1a;https://github.com/datawhalechina/team-learning-program/tree/master/PythonTest内容属性&#xff1a;公测课…

matlab处理txt文件数据

read_txtfile.,m clear close all clc %load函数一般将用来导入纯数字的文件&#xff0c;可以是文本格式的文件或者是matlab保存的mat格式的文件 positionload(坐标点.txt); %将.txt数据读入到matlab工作空间[m,n]size(position); %获得数据矩阵的大小 j1; sumx0; sumy0; …

Python os库的使用

1. 基本介绍 os提供通用的、基本的操作系统交互功能 os库是Python的标准库&#xff0c;提供几百个处理函数 常用有路径操作、进程管理、环境参数等几类 路径操作&#xff1a;os.path子库&#xff0c;处理文件路径及信息 进程管理&#xff1a;启动系统中其他程序 环境参数&…

(U3D)Time的使用

Time类包含了一个重要的类变量deltaTime&#xff0c;它表示距上一次调用Update或FixedUpdate所用的时间。 因此通过它可以让游戏对象按照一个常速进行旋转&#xff0c;而不是依赖于它的帧频&#xff1a; function Update() { tranform.Rotate(0, 5 * Time.deltaTime, 0); } …

【组队学习】【34期】Scratch(二级)

Scratch&#xff08;二级&#xff09; 航路开辟者&#xff1a;王思齐、马燕鹏领航员&#xff1a;马燕鹏航海士&#xff1a;马燕鹏 基本信息 开源内容&#xff1a;https://github.com/datawhalechina/team-learning-program/tree/master/Scratch内容属性&#xff1a;公测课程…

文件操作示例脚本 tcl

linux 下&#xff0c;经常会对用到文件操作&#xff0c;下面是一个用 tcl 写的文件操作示例脚本&#xff1a; 其中 set f01 [open "fix.tcl" w] 命令表示 打开或者新建一个文件“fix.tcl”&#xff0c;并将其 file ID 设置为 f01&#xff0c;后续就以这个 file ID 来…