MVC:简单的来说就是Model层(实体层)、View层(视图层)、Controllers层(控制器)
相比以前的三层架构,这种开发模式耦合性更低。所谓耦合性:就是各个功能模块处理各自的操作,互不干扰,独立性更加高,数据处理维护也就相对的方便。这是我的一个理解。
创建一个MVC项目后,里面有几个文件需要解释一下。
1.App_Start(配置文件夹)
它里面有三个.cs类 第一个是BundelConfig.cs,打包器(打包专用)的配置文件,里面主要是一些CSS,js文件
第二个是FilterConfig.cs,过滤器
最后一个是RouteConfig.cs,路由配置,自动配置了controller和action,通过controller来找到对应的action
2.Controller和view文件夹
简单的来说就是每创建一个控制器,在view文件夹下会有对应的与控制器同名的文件夹。
在控制器中存在一个ActionResult方法,方法名与其对应的view下面有一个同名的.cshtml页面,
我们可以通过调用不同的Action方法,来显示不同的页面内容。
总的来说,它的执行过程是这样的。由地址栏访问控制器-->通过Model过滤校验-->在view中显示。
View文件夹下面还有一个Shared文件这个文件下面有一个_Layout.cshtml它是一个完整的页面。
如果知道三层中的母版页,就会理解它的作用。实际上_Layout就是一个母版页。它通过@RenderBody来替换(相当于内容页)的主体内容。
在Shared文件夹外面还有一个单独的_ViewSatrt.cshtml。在这个里面就一句话
如果需要单独作为一个页面处理,不需要母版页,可以在内容页加上这样一行代码
注:在配置文件web.config中,找到
注:ASP.NET IIS管道问题
在MVC执行过程中,控制器对应的Action方法在调用时,是不需要开发人员手动去实例化的,
原因就是ASP.NET的框架自动处理了这些问题
MVC中的几个内置对象
1.Request
Request,简单来说就是请求的意思。服务器接收客户端的数据
Request.QueryString-->针对表单并且为get的提交方式
Request.Form-->看到Form就想到了表单,这种方式与前者get对应的是post的提交方式
Request.File,获取post提交的文件(文件上传)
文件上传需要注意的是一个需要在表单加一个属性enctype="multipart/form-data"
Request.MapPath,在上传文件的过程中将虚拟路径(相对路径)转换为物理路径(绝对路径)
2.Session
Session俗称会话。 它有几个比较重要的特点:储存在服务器上、安全性较高、性能较差、储存少量重要数据
例如:身份验证(登录账号、密码等)。每个用户登录会拥有独立的Session值,互不干扰。存活时间是20分钟。销毁Session可以调用Abandon()方法或者Clear()方法
3.Cookie
相比Session,Cookie的特点就显而易见了,安全性较低,原因主要是,Cookie它是存储在客户端的数据,用户可以更改内容。并且Cookie还有一个特点就是时效性。可以通过Expires设置Cookie的存活时间。同样也可以销毁存储在客户端的Cookie
使用过期的方式做到清除Cookie
数据的传递
1.从控制器--》视图
通过ViewBag,将ViewBag作为一个贯穿视图和控制器的一个桥梁
通过@在对应的view页面输出
注:ViewBag实际上是一个动态的类型 Content相当于变量,你也可以把它当做 js 中的 var
通过ViewData。本质上ViewBag也是ViewData集合,也就是说他们的存储方式是一样的。两种方式一般存放一般不主要数据。
通过TempData。TempData和Session相似,通过键值对读取存储。当时TempData在读取后悔会被清空,与ViewData不同的是TempData是可以跨页面的,但是只能用一次。
那主要的数据是通过什么传递的呢
来讲讲 return View()
View实际上是一个重载方法,控制器中的View可以传递一个Object类型的参数,也就是说可以是Model类中的对象。
那怎么在View视图去接收呢?
实际上在调用Student类中的属性时是没有提示的,我们可以在视图加上这样一行代码
这样就是告诉视图,我传过来的是Model中Student实体类对象,这样它就知道可以通过调用属性的方式拿到数据。如果不加这一行代码它就是一个弱类型视图,加上就是强类型视图。
需要注意的是,由于View有多个参数,在向视图层传值的过程中,参数值不一定是在ActionResult对应的方法里面显示,为什么呢?
还可以针对母版页传递第二个参数。
2.从视图--》控制器
[HttpGet] 表示从视图传数据到控制器限制于Get方式提交,如果使用post会出现404的错误。
通过给Index方法设置参数,不但可以接收get提交的数据,也可以接收post提交的数据。
另一种方式通过实体类来作为参数
这样写有什么好处呢?
在EF设计模型中,我们可以在实体层中给属性进行各种数据校验。
在控制器层我们需要通过 ModelState.IsValid 来判断Model是否合法。
文件的上传和读取
在action方法里面写入参数 HttpPostedFileBase file ,file我把它看作是变量。
在D盘创建了一个名为uploads的文件夹。通过拼接字符串保存在uploads中。在前面我们也说到了上传文件也可以通过Request.File的方式从客户端接收,并且需要将虚拟路径(相对路径)转换为物理路径(绝对路径)。
同样在使用Form表单时,也需要加上enctype的属性,并且input的name属性必须和 HttpPostedFileBase 变量file一致!当然文件上传不只是上传图片
输出 json 数据
JsonRequestBehavior.AllowGet 可以通过get请求的方式来获取。
再来说说分布式页面的作用吧
创建分布式视图时候,在我看来最大的作用就是可以在不同的地方使用它,只要调用就ok了。类似于 vue 里面的组件。可以重复使用!调用的方法就是
分布页面也有两种写法:第一种就是待处理的,第二种就是不带处理的。
那什么是待处理的呢? 我刚刚上面的那一种写法就是待处理的。
有与之对应的 ActionResult 方法,在调用的时候可以直接通过 .Action获取对应的分布页面。
另一种不待处理的。
这是我们新建的一个登陆的不待处理的分布页面。注意要遵循不管是分布页面还是布局页面都需要_下划线开头。
与待处理不同的是就是调用的方法。
那怎么传数据呢?
可以通过Model参数,然后在视图层调用即可,User 是新建的实体类。
说一下一个叫MVC 区域 的东西
为什么要设置一个区域呢?在我们的开发过程中,有时候项目过于庞大,如果放在一个MVC项目里面会显得杂乱无章,不清楚哪个是哪个。这个时候我们就可以通过设置区域来建立一个独立的MVC 。如上图所示,Areas文件夹里面有个sport,sport是区域名,下面三个文件夹就是对于的 Controllers、Models、Views。最主要的是它有一个单独的路由
这里需要注意的是,当你返回到最外层的Index首页是它会报如下错误提示。
根据上面的错误提示,我们可以在我最外层的路由上加上这样一行代码。
这样我们就可以通过不同的板块进行区分。
跨路由跳转的问题
简单的来说就是我们需要在最外层给定一个a标签,使其跳转到设置区域对应的模块页面!
在这里由于路由的问题,我们不能够直接写一个a标签跳过去,因为一旦改动路由设置,a标签也必须进行变动,这样会显得非常的繁琐。
我们可以通过系统的a标签来实现!
参数1:表示LinkText也就是显示的名称。
参数2:表示路由的名称,这个可以在对应的区域路由查看,如下图
参数3:表示相对应的路由值,也就是区域的控制器名称和action方法名。
这个时候无论你的路由怎么设置,我们都可以成功的实现区域的跳转。
与 @Html.RouteLink 相对应的就是 @Html.ActionLink
@Html.ActionLink就是当前路由跳转
最后来看看ViewModel的一些规则