第一单元 Mvc概述

第一单元 Mvc概述 第一单元 Mvc 概述

1. 什么是Mvc

模型-视图-控制器 (MVC) 体系结构模式将应用程序分成 3 个主要组件组:视图模型、视图和控制器。 此模式有助于实现关注点分离。 使用此模式,用户请求被路由到控制器,后者负责使用模型来执行用户操作和/或检索查询结果。 控制器选择要显示给用户的视图,并为其提供所需的任何模型数据。

下图显示 3 个主要组件及其相互引用关系:

 

这种责任划分有助于根据复杂性缩放应用程序,因为这更易于编码、调试和测试包含单一作业的某个组成部分(模型、视图或控制器)。 但这会加大更新、测试和调试代码的难度,该代码在这 3 个领域的两个或多个领域间存在依赖关系。 例如,用户界面逻辑的变更频率往往高于业务逻辑。 如果将表示代码和业务逻辑组合在单个对象中,则每次更改用户界面时都必须修改包含业务逻辑的对象。 这常常会引发错误,并且需要在每次进行细微的用户界面更改后重新测试业务逻辑。

视图和控制器均依赖于模型。 但是,模型既不依赖于视图,也不依赖于控制器。 这是分离的一个关键优势。 这种分离允许模型独立于可视化展示进行构建和测试。

 

模型责任

MVC 应用程序的模型 (M) 表示应用程序和任何应由其执行的业务逻辑或操作的状态。 业务逻辑应与保持应用程序状态的任何实现逻辑一起封装在模型中。 强类型视图通常使用 ViewModel 类型,旨在包含要在该视图上显示的数据。 控制器从模型创建并填充 ViewModel 实例。

视图责任

视图 (V) 负责通过用户界面展示内容。 它们使用 Razor 视图引擎 在 HTML 标记中嵌入 .NET 代码。 视图中应该有最小逻辑,并且其中的任何逻辑都必须与展示内容相关。 如果发现需要在视图文件中执行大量逻辑以显示复杂模型中的数据,请考虑使用 View Component、ViewModel 或视图模板来简化视图。

控制器职责

控制器 (C) 是处理用户交互、使用模型并最终选择要呈现的视图的组件。 在 MVC 应用程序中,视图仅显示信息;控制器处理并响应用户输入和交互。 在 MVC 模式中,控制器是初始入口点,负责选择要使用的模型类型和要呈现的视图(因此得名 - 它控制应用如何响应给定请求)。

备注

控制器不应由于责任过多而变得过于复杂。 要阻止控制器逻辑变得过于复杂,请将业务逻辑推出控制器并推入域模型。

提示

如果发现控制器操作经常执行相同类型的操作,可将这些常见操作移入筛选器

2. ASP.NET Core MVC

ASP.NET Core MVC 框架是轻量级、开源、高度可测试的演示框架,并针对 ASP.NET Core 进行了优化。它摒弃了传统的全家桶模式,采用了按需所取的方式给用户提供服务。

ASP.NET Core MVC 提供一种基于模式的方式,用于生成可彻底分开管理事务的动态网站。 它提供对标记的完全控制,支持 TDD 友好开发并使用最新的 Web 标准。

1. 与Framework 下的 Asp.Net Mvc 的区别

详细内容: ASP.NET MVC 和 ASP.NET Core 之间的体系结构差异 | Microsoft Docs

体系结构非跨平台跨平台启动方式ASP.NET 应用托管在 IIS 中,它们依赖于 IIS 来实例化某些对象,并在请求到达时调用某些方法。ASP.NET Core 应用是独立程序。 因此,它们通常包含一个 Program.cs 文件,该文件包含应用的入口点 .托管差异ASP.NET MVC 应用托管在 IIS 中,并可能依赖 IIS 配置来实现其行为。 这通常包括 IIS 模块使用了更轻量的kestrel 服务器,它可支持跨平台静态文件由 IIS 托管静态文件。支持将静态文件与应在服务器上保持私有的文件并排放置。(可使用内容分发网络CDN优化)不能直接支持,必须配置静态文件中间件。(wwwroot为固定文件夹)注入差异需要借助第三方工具,如Autofac,Unity,Ninject...内置于框架中,在应用启动时,将调用 ConfigureServices,该调用负责注册 DI 容器(服务集合/服务提供商)可在应用中创建和注入的所有类型模块和处理程序HTTP 模块和 HTTP 处理程序是 ASP.NET 体系结构的必要部分。 处理请求时,每个请求都由多个 HTTP 模块(例如身份验证模块和会话模块)处理,然后由单个 HTTP 处理程序进行处理。 在处理程序处理请求后,请求通过 HTTP 模块传输回去。(全家桶)ASP.NET Core 在每个应用的 Configure 方法中定义一个请求管道。 此请求管道定义了应用如何处理传入的请求,其中管道中的每个方法都调用下一个方法,直到最终方法终止(按需所用)配置差异配置使用应用文件夹中内置的 .NET 配置文件web.config,ConfigurationManager静态访问配置本身是可配置的。可根据需要注入IConfiguration访问配置值

2. Mvc:约定大于配置

  1. 控制器类加Controller后缀,而且都放在Web项目下的Controllers文件夹中,控制器类继承Controller基类。

  2. 视图文件必须放在名称为Views/Pages 的文件夹下的名称为控制器名称的文件夹中。

  3. _ViewStart.cshtml 执行任何Action(控制器中以IActionResult为返回类型的方法叫Action方法)之前,都会先执行它.

  4. 以下划线命名开头的视图一般作为布局/ViewCompenent 视图,放在shared文件夹下面

  5. _ViewImport.cshtm 为全局视图文件共公命名空间的引用

3. 快速入门

  1. 创建项目

 

刚新建好的空项目:

 

  1. 选中Controllers 文件夹,右键-->新建-->类/接口

     

  2. 控制器代码

// Hello 表示控制器名称,HelloController 是控制器类名(C)
public class HelloController:Controller
{
    // 创建视图文件的方法(V)
    public IActionResult Index()
    {
        // 业务逻辑,模型操作(M)
        List<StudentViewModel> list = new List<StudentViewModel>()
        {
            new(1,"张三"), // C#9.0 以上创建对象语法
            new(2,"李四"),
            new (3,"王五")
        };

        return View(list);// 将模型数据传递给视图
    }
}

public record StudentViewModel(int Id,string Name);

 

  1. 在Views/ 目录下创建Hello目录,在Hello目录下创建Index.cshtml文件。

  2. 编写任意html代码

    @* 接收视图模型传递过来的数据 *@
    @model List<WebApplication2.Controllers.StudentViewModel>
    
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Mvc 快速入门</title>
    </head>
    <body>
    <div>
          <h1>大家好,欢迎来到任我行码农场,Asp.net Mvc</h1>
    </div>
    </body>
    </html>

     

     

3. Mvc 项目结构

 

  • Dependencies:项目所依赖的组件

  • launchSettings.json : 项目发布设置文件

    {
      "iisSettings": {// iis 设置
        "windowsAuthentication": false,
        "anonymousAuthentication": true,
        "iisExpress": {
          "applicationUrl": "http://localhost:21843",
          "sslPort": 44331
        }
      },
      "profiles": {
        "WebApplication2": {
          "commandName": "Project",
          "dotnetRunMessages": true,
          "launchBrowser": true,// 使用浏览器
          "applicationUrl": "http://localhost:5096",// 项目运行地址
          "environmentVariables": { // 当前环境
            "ASPNETCORE_ENVIRONMENT": "Development" // 表示当前环境为Development
          }
        },
        "IIS Express": { // 内置IIS 的设置
          "commandName": "IISExpress",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        }
      }
    }

     

  • Controllers: 存放所有的控制器

  • Models: 存放所有的ViewModel 文件

  • Views: 存放所有的视图文件

  • Views/Shared : 存放公共的视图文件

  • Views/Shared/_Layout.cshtml : 公共布局文件

  • Views/Shared/Error.cshtml: 错误提示视图

  • Views/_ViewImports.cshtml: 公共导入命名空间,引用公共的标签助手

    @using WebApplication2
    @using WebApplication2.Models
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    Views/_ViewStart.cshtml: 视图起始文件,所有视图在加载时,都会先加载此视图文件
    
    wwwroot: 存放所有的静态资源文件(css/js/html)
    
    wwwroot/favicon.ico : 应用程序的图标
    
    appsetting.json: 当前应用程序的配置文件
    
    appsetting.Development.json: 当前环境的配置文件,如果在此文件中未找到想要的配置,则会去appsetting.json 文件中去寻找。
    
    Program:程序的主入口,用于初始化系统的相关配置,注册服务,配置中间件与注册管道。
    
     
    
    4. 控制器动作
    控制器动作(具体的action)返回的结果叫做控制器动作结果,动作结果是控制器返回给浏览器请求的内容。ASP.NET Core MVC 框架支持几十种标准类型的动作结果,以下是常见的类型
    
    动作名称    简要概述
    ViewResult    返回视图
    RedirectToActionResult    重定向到某个Action方法
    JsonResult    Json结果,可以用于Ajax应用程序
    ContentResult    文本结果
    RedirectResult    重定向到一个新的URL
    FileResult    返回一个文件,一般用于下载
    它们 都实现了IActionResult 接口。
    
    public ViewResult Index()
    {
        List<StudentViewModel> list = new List<StudentViewModel>()
        {
            new(1,"张三"), 
            new(2,"李四"),
            new (3,"王五")
        };
        
        return View(list);
    }
    
    public JsonResult Index2()
    {
        List<StudentViewModel> list = new List<StudentViewModel>()
        {
            new(1,"张三"), 
            new(2,"李四"),
            new (3,"王五")
        };
        return Json(list);
    }
    
    public ContentResult Index3()
    {
        return Content("hello,任我行码农场");
    }
    
    
    public RedirectToActionResult Index4()
    {
        return RedirectToAction("Index2", "Hello");
    }
    
    public FileResult Download()
    {
        using MemoryStream ms = new MemoryStream();
        var buffer = Encoding.UTF8.GetBytes("文件下载");
        ms.Write(buffer);
        return File(ms.ToArray(), "application/octet-stream", "测试文件.txt");
    }

     

Action方法与普通方法的区别

Action方法是由Mvc 框架管理,Mvc 框架可以对Action方法进行处理与渲染(例如渲染视图,拦截请求等等),而普通则不受mvc 控制。

举个例子,ContentResult 通常的作用也是直接返回一个字符串,当我们执行Content("hello,任我行码农场") 时,我们只是告诉Mvc框架,我们需要返回 “hello,任我行码农场”,而并非立即返回,Mvc 框架在此之后可能还会做很多的处理,或许在中间的某个环节,有可能请求被拦截,导致我们可能得到不同的结果(日后要讲的AOPA思想)。而return "hello,任我行码农场" 则是立即返回。

 

 

5. Razor视图

注释

@* *@ 

 

 

输出纯文本:

@:这里是妹子可以看的内容

 

 

编写C#代码

<html>
<head>
    <title>Mvc 快速入门</title>
</head>
<body>
<div>
    <h1>大家好,欢迎来到任我行码农场,Asp.net Mvc</h1>
    
    @{
        int a = 1;
        int b = 2;
        Console.WriteLine(a+b);
    }
</div>
</body>
</html>

 

 

if else

<html>
<head>
    <title>Mvc 快速入门</title>
</head>
<body>
<div>
    <h1>大家好,欢迎来到任我行码农场,Asp.net Mvc</h1>
    
    @if (true)
    {
        <h1>hello</h1>
    }
    else
    {
        <p>world</p>
    }
</div>
</body>
</html>

 

视图传值

1. TempData

public IActionResult Index()
{
    TempData["username"] = "任我行";
    return View();
}
<body>
<div>
    <h1>我的名称:@TempData["username"]</h1>
</div>
</body>

 

TempData 保存在Session中,Controller每次执行请求的时候,会从Session中先获取 TempData,而后清除Session,获取完TempData数据,虽然保存在内部字典对象中,但是其集合中的每个条目访问一次后就从字典表中删 除。具体代码层面,TempData获取过程是通过SessionStateTempDataProvider.LoadTempData方法从 ControllerContext的Session中读取数据,而后清除Session,故TempData只能跨Controller传递一次。

 

2.ViewBag 与 ViewData

ViewData:

ViewData 只在当前 Action 中有效,生命周期和 View 相同;

public IActionResult Index()
{
    ViewData["username"] = "任我行";

    return View();
}
<body>
<div>
    <h1>我的名称:@ViewData["username"]</h1>
</div>
</body>

 

ViewBag

ViewBag其实本质就是ViewData,只是多了层Dynamic控制。所以,使用何种方式完全取决于你的个人爱好。

public IActionResult Index()
{
    ViewBag.UserName = "任我行";

    return View();
}
<body>
<div>
    <h1>我的名称:@ViewBag.UserName</h1>
</div>
</body>

 

两者区别如下:

差异Frameowrk MvcMvc Core
它是key/value字典集合它是dynamic类型对象从asp.net mvc1就有了从asp.netmvc3才有基于asp.netframework 3.5基于asp.net framework4.0viewdata比viewbag快viewbag比viewdata慢页面查询数据时需要转换合适的类型在页面查询数据时不需要转换合适的类型有一些类型转换代码可读性较好

总结

1、ViewData和TempData是字典类型,赋值方式用字典方式,ViewData["myName"]

2、ViewBag是动态类型,使用时直接添加属性赋值即可 ViewBag.myName

3、ViewBag和ViewData只在当前Action中有效,等同于View

4、TempData可以通过转向继续使用(Server.Tranfer()),因为它的值保存在Session中。但TempData只能经过一次传递,之后会被系统自动清除(Framework)

5、ViewData和ViewBag中的值可以互相访问,因为ViewBag的实现中包含了ViewData

 配套视频链接:Asp.Net Mvc Core 6.0 详细教程 - 网易云课堂 (163.com)

 

海阔平鱼跃,天高任我行,给我一片蓝天,让我自由翱翔。
评论
  
ViewDataViewBag