当前位置: 首页 > article >正文

Backend - C# asp .net core MVC

目录

一、Controllers 目录

1. 命名空间都是项目名.Controllers。

2. 类名的后缀固定是Controller。

3. [ApiController]

4. [Route("[controller]")]

5. 基类ControllerBase

​编辑 二、视图文件

(一).cshtml(视图文件)存储位置:

1. 默认位置

2. 指定其他位置

 (二).cshtml(视图文件)快速生成方式:

三、controller的视图方法View()

(一)查找视图文件的三种方法

1. View() 或 View(object model)

2. View(string viewName)

3. View(string viewName, object model ) 

(二)数据从控制器传递到视图的三种方法

1. ViewData

2. ViewBag

3. 强类型视图(编译时提供类型检查和智能提示)

(三)三种方法的定义和使用例子

1. Book.cs(Models中)

2. Bookcontroller.cs(Controllers中,部分代码)

3. test2.cshtml(Views/Book中)

4. test3.cshtml(Views/Book中)

5. test4.cshtml(Views/Book中)

6. 测试网页路由

① ViewBag测试

② ViewData测试

③ 强类型model测试

四、ViewModel 视图模型

1. 定义视图模型名

2. 作用

3. 强类型的好处

4. 举例

(1)新建ViewModels文件夹,以及子文件BookTestModelViewModel.cs

(2)Bookcontroller.cs(Controllers中,部分代码)

(3)test5.cshtml(Views/Book中)

(4)测试

五、MVC中HTTP请求的常用返回类型

1. IActionResult

2. ViewResult。

3. RedirectResult

4. RedirectToActionResult

5. 举例

六、MVC前端显示列表

1. 新建ViewModels文件夹,以及子文件BookTestModelViewModel.cs

2. Bookcontroller.cs(Controllers中,部分代码)

3. test6.cshtml(Views/Book中)

4. 测试

七、MVC前端模板

1. 命名

2. 位置

3. 文件类型

4. 引用公共页面

5. 具体实现的例子

(1)新建ViewModels文件夹,以及子文件BookTestModelViewModel.cs

(2)Bookcontroller.cs(Controllers中,部分代码)

(3)testchild1.cshtml(Views/Book中)

八、MVC前端模板的RenderSection

1. 作用

2. 共享文件定义时

3. 子页面渲染时

九、MVC中的Razor视图开始文件(视图检视开始)

1. 命名

2. 位置

3. 优先级

4. 作用

十、MVC中Razor视图导入文件(视图检视汇入)

1. 命名

2. 作用

3. 位置

4. 优先级

5. 例子

(1)未使用导入文件时

(2)使用导入文件时

① 某cshtml引入model的写法是:

② 搭配导入文件的内容是:

十一、MVC中的路由

(一)传统路由

(二)属性路由

(三)属性路由(高级写法)

1. 第一种方式

2. 第二种方式

十二、模板href跳转路由

第一种:

第二种:

第三种:(推荐)

十三、Taghelper 跳转链接

(一)作用

(二)引入

(三)举例(生成跳转链接):

1. 写法:

(1)首先配置路由

(2)跳转路由

(3)执行跳转

(4)如果配置的路由发生变化

① 写法

② 执行跳转

十四、模板中引入文件

1. 引入快捷方式

2. 位置

3. 注意

4. 引入样式文件写法

十五、模型绑定顺序

十六、模型绑定注解验证

(一)Model类

(二)cshtml模板文件 

(三)Controller类

十七、MVC架构的简单项目例子

(一)实体类(项目名/Models/Book.cs)

(二)模拟存储库的接口(项目名/Models/IBookRepository.cs)

(三)模拟存储库的实体类(项目名/Models/MockBookRepository.cs)

(四)控制器中注入依赖(项目名/Controllers/BookController.cs)

(五)Program.cs 中注册 IBookRepository

(六)测试(浏览器URL中输入)

1. 默认路由

2. 通过bookID获取值

十八、AddMvcCore & AddMvc


一、Controllers 目录

针对Controllers目录下的某个Controller文件内容:

1. 命名空间都是项目名.Controllers。

2. 类名的后缀固定是Controller。

3. [ApiController]

        作用是设置该类是一个API控制器。可以自动绑定请求体到方法参数,自动验证不符合要求的数据请求。

4. [Route("[controller]")]

        作用是指定路由模板。[controller]是一个占位符,会自动替换成类名(获取类名的前半部分,去掉Controller后缀。如WeatherForecastController中,获取WeatherForecast)。最终组成该控制器的API路径是/weatherforecast,也可以直接设定Route("Book/add"),最终的API路径则是/Book/add)。

5. 基类ControllerBase

        作用是提供自动化HTTP请求和响应处理(如Ok())。


 
二、视图文件

(一).cshtml(视图文件)存储位置:

1. 默认位置

        默认目录是 Views / 所在controller名(去掉controller后缀)文件夹里。

        在Controller找页面时,用return View();

2. 指定其他位置

        一般放在Views目录下,然后再自定义文件夹存放。

        在Controller找页面时,用return View("~/Views/XXX/XXX.cshtml"); // 一定要带上文件后缀(.cshtml)

例子:

[Route("authorurl/test")]
public IActionResult testurl2() // 测试路由
{
    ViewData["Title"] = "这是路由标题"; 
    ViewData["bookName"] = "这是路由名"; 
return View("~/Views/Book/TestView.cshtml");
}

 (二).cshtml(视图文件)快速生成方式:

        在 return View(); 中的 View 单词上右击,选择“新增视图”,在提供的默认配置下直接点击“新增”。
 

三、controller的视图方法View()

(一)查找视图文件的三种方法

1. View() 或 View(object model)

        查找与操作方法相同名称的视图文件。

2. View(string viewName)

        查找自定义的视图文件。

        可指定绝对路径,但须带上.cshtml后缀。若是相对路径则不用带后缀。

3. View(string viewName, object model ) 

(二)数据从控制器传递到视图的三种方法

1. ViewData

2. ViewBag

3. 强类型视图(编译时提供类型检查和智能提示)

(三)三种方法的定义和使用例子

1. Book.cs(Models中)

namespace ASPNetAPI.Models
{
    public class Book
    {
        public int BookID {  get; set; }
        public string BookName { get; set; }
        public string Description { get; set; }
        public string Author { get; set; }
        public double Price { get; set; }
    }
}

2. Bookcontroller.cs(Controllers中,部分代码)

public IActionResult TestViewBag() // 用ViewBag测试数据传递 
{
    Book bookmodel = _bookRepository.GetBook(1);
    ViewBag.bookTitle = bookmodel.BookName.ToString() + "(ViewBag)";
    ViewBag.bookDetails = bookmodel;
    return View("test2");
}
 
public IActionResult TestViewData() // 用ViewData测试数据传递
{
    Book bookmodel = _bookRepository.GetBook(1);
    ViewData["bookTitle"] = bookmodel.BookName.ToString() + "(ViewData)";
    ViewData["bookDetails"] = bookmodel;
    return View("test3");
}
 
public IActionResult TestViewModel() // 用强类型测试数据传递
{
    Book bookmodel = _bookRepository.GetBook(1);
    ViewData["bookTitle"] = bookmodel.BookName.ToString() + "(Model)";
    return View("test4", bookmodel); // 指定视图文件,传入bookmodel作为强类型
}

3. test2.cshtml(Views/Book中)

@using ASPNetAPI.Models // 引入Book类所需
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>ViewBag的使用</title>
</head>
<body>
    <h3>@ViewBag.bookTitle</h3>
 
    @{
        var books = ViewBag.bookDetails as Book; //显示转换 使用动态属性取值
    }
    <div>书籍名称 @books.BookName</div>
    <div>书籍作者 @books.Author</div>
    <div>书籍价格 @books.Price</div>
</body>
</html>

4. test3.cshtml(Views/Book中)

@using ASPNetAPI.Models // 引入Book类所需
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>ViewData的使用</title>
</head>
<body>
    <h3>@ViewData["bookTitle"]</h3>
 
    @{
        var books = ViewData["bookDetails"] as Book; //显示转换 使用字典取值
    }
    <div>书籍名称 @books.BookName</div> 
    <div>书籍作者 @books.Author</div>
    <div>书籍价格 @books.Price</div>
</body>
</html>

5. test4.cshtml(Views/Book中)

@model ASPNetAPI.Models.Book // 用@model指定模型类型。匹配到Controller文件的view( )传入的bookmodel
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>强类型的使用</title>
</head>
<body>
    <h3>@ViewData["bookTitle"]</h3>
    <div>书籍名称 @Model.BookName</div><!--固定用@Model访问模型对象属性-->
    <div>书籍作者 @Model.Author</div>
    <div>书籍价格 @Model.Price</div>
</body>
</html>

6. 测试网页路由

① ViewBag测试

        https://localhost:44372/Book/testviewbag

② ViewData测试

        https://localhost:44372/Book/testviewdata

③ 强类型model测试

        https://localhost:44372/Book/testviewdmodel

四、ViewModel 视图模型

1. 定义视图模型名

        一般是:视图名+操作方法名+ViewModel

2. 作用

        将所有数据都用模型对象存储,保证所有数据都用强类型视图的方式来获取。

3. 强类型的好处

        编译时提供类型检查和智能提示、方便获取和传递数据。

4. 举例

(1)新建ViewModels文件夹,以及子文件BookTestModelViewModel.cs
using ASPNetAPI.Models;
 
namespace ASPNetAPI.ViewModels
{
    public class BookTestModelViewModel
    {
        public Book Book { get; set; }
        public String PageTitle { get; set; }
    }
}
(2)Bookcontroller.cs(Controllers中,部分代码)
public IActionResult TestModel() // 测试数据传递(强类型)
 {
     BookTestModelViewModel bookmodel = new BookTestModelViewModel()
     {
         Book = _bookRepository.GetBook(1),
         PageTitle = "ViewModel测试"
     };
     return View("test5", bookmodel);
 }
(3)test5.cshtml(Views/Book中)
@model ASPNetAPI.ViewModels.BookTestModelViewModel
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>强类型的使用</title>
</head>
<body>
    <h3>@Model.PageTitle</h3>
    <div>书籍名称 @Model.Book.BookName</div><!--固定用Model-->
    <div>书籍作者 @Model.Book.Author</div>
    <div>书籍价格 @Model.Book.Price</div>
</body>
</html>

(4)测试

其他文件不变。

测试:https://localhost:44372/Book/TestModel

五、MVC中HTTP请求的常用返回类型

1. IActionResult

        理解:是一个接口,定义了所有可能的返回类型。

2. ViewResult。

        作用:是 IActionResult 的实现之一,返回视图页面(HTML)

        搭配:return View()

3. RedirectResult

        作用:将客户端重定向到指定的 URL。

        搭配:return Redirect("url")

4. RedirectToActionResult

        作用:将请求重定向到控制器的其他动作方法。

        搭配:return RedirectToAction("ActionName")  或者return RedirectToAction("操作方法名", new { 参数key = 参数值 });

        其中,return使用的是RedirectToAction()指定到方法中,而不是 View()指定到视图中

5. 举例

 [HttpPost]
 public RedirectToActionResult AddMusic(Music music)
 {
     Music newMusic = _musicRepository.CreateSong(music);
     return RedirectToAction("ShowOneSong", new { id = newMusic.MusicID }); // 注意使用new { id = newMusic.MusicID }。不要直接传递newMusic.MusicID(会导致路由的参数名映射错误)
}

六、MVC前端显示列表

具体实现的例子:

1. 新建ViewModels文件夹,以及子文件BookTestModelViewModel.cs

using ASPNetAPI.Models;
 
namespace ASPNetAPI.ViewModels
{
    public class BookTestEnumerableViewModel
    {
        public IEnumerable<Book> Books { get; set; }
        public String PageTitle { get; set; }
    }
}

2. Bookcontroller.cs(Controllers中,部分代码)

public IActionResult TestEnumerable() // 测试数据传递
{
    BookTestEnumerableViewModel bookmodel = new BookTestEnumerableViewModel()
    {
        Books = _bookRepository.GetBooks(),
        PageTitle = "Enumerable测试"
    };
    //ViewData["bookTitle"] = bookmodel.Book.BookName.ToString() + "(Model)";
    return View("test6", bookmodel);
}

3. test6.cshtml(Views/Book中)

@model ASPNetAPI.ViewModels.BookTestEnumerableViewModel
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>强类型的使用</title>
</head>
<body>
    <h3>@Model.PageTitle</h3>
    <table>
        <thead>
            <tr>
                <th>BookID</th>
                <th>BookName</th>
                <th>Description</th>
                <th>Author</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
           @foreach(var bk in Model.Books){
                <tr>
                    <td>@bk.BookID</td>
                    <td>@bk.BookName</td>
                    <td>@bk.Description</td>
                    <td>@bk.Author</td>
                    <td>@bk.Price</td>
                </tr>
           }
        </tbody>
    </table>
</body>
</html>

4. 测试

        其他文件不变。

        测试:https://localhost:44372/Book/TestEnumerable

七、MVC前端模板

1. 命名

        模板页面的命名都用下划线开头。

2. 位置

        一般放在Views/Shared目录中。

3. 文件类型

        新增的文件类型是Razor布局(Razor版面配置)。

4. 引用公共页面

        子页面通过以下代码引用到公共布局页面。

@{
    Layout = "~/views/XXX/_Layout.cshtml"; // 斜杠使用/,而不是\。
    ViewBag.Title = "子页面测试";
}

5. 具体实现的例子

(1)新建ViewModels文件夹,以及子文件BookTestModelViewModel.cs
using ASPNetAPI.Models;
 
namespace ASPNetAPI.ViewModels
{
    public class BookTestEnumerableViewModel
    {
        public IEnumerable<Book> Books { get; set; }
        public String PageTitle { get; set; }
    }
}
(2)Bookcontroller.cs(Controllers中,部分代码)
public IActionResult TestLayout() // 测试数据传递
 {
     BookTestEnumerableViewModel bookmodel = new BookTestEnumerableViewModel()
     {
         Books = _bookRepository.GetBooks(),
         PageTitle = "Layout测试"
     };
     //ViewData["bookTitle"] = bookmodel.Book.BookName.ToString() + "(Model)";
     return View("testchild1", bookmodel);
 }
(3)testchild1.cshtml(Views/Book中)
@model ASPNetAPI.ViewModels.BookTestEnumerableViewModel
@{
    Layout = "~/views/common/_layout.cshtml"; // 斜杠使用/,而不是\。
    ViewBag.Title = "子页面测试";
}
 
<table>
    <thead>
        <tr>
            <th>BookID</th>
            <th>BookName</th>
            <th>Description</th>
            <th>Author</th>
            <th>Price</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var bk in Model.Books)
        {
            <tr>
                <td>@bk.BookID</td>
                <td>@bk.BookName</td>
                <td>@bk.Description</td>
                <td>@bk.Author</td>
                <td>@bk.Price</td>
            </tr>
        }
    </tbody>
</table>

八、MVC前端模板的RenderSection

1. 作用

        方便不同的子页面使用不同的JS。

2. 共享文件定义时

@RenderSection("sectionJS", false) // <!--写在模板文件代码的body内最底部,参数1为自定义节点名,参数2为是否必需JS插入文件-->

3. 子页面渲染时

@section sectionJS{
    <script src="~/js/common.js"></script> <!--写在要使用某JS的子页面代码的最底部,sectionJS为节点名-->
}

九、MVC中的Razor视图开始文件(视图检视开始)

1. 命名

        新建时默认用_ViewStart.cshtml名。

2. 位置

        可存储在Views目录里的任何位置。

3. 优先级

        内部代码里 > 同层级的_ViewStart.cshtml > 父级的_ViewStart.cshtml

4. 作用

        统一处理文件。如统一引入Layout布局模板文件。(每个子页面就不用都引入Layout模板文件,直接在_ViewStart.cshtml中统一管理)

十、MVC中Razor视图导入文件(视图检视汇入)

1. 命名

        新建时,默认用_ViewImports.cshtml名。

2. 作用

        统一处理命名空间。

3. 位置

        可存储在Views目录里的任何位置。

4. 优先级

        内部代码里 > 同层级的_ViewImports.cshtml > 父级的_ViewImports.cshtml

5. 例子

(1)未使用导入文件时

        某cshtml引入model的写法是:

@model ASPNetAPI.ViewModels.BookViewModel
(2)使用导入文件时
① 某cshtml引入model的写法是:
@model BookViewModel
② 搭配导入文件的内容是:
@using ASPNetAPI.ViewModels;

十一、MVC中的路由

(一)传统路由

// programs.cs中配置路由
app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action}/{id?}", // 自定义路由(其中id对应某方法的参数名)
    defaults: new { controller = "Book", action = "Index" }); // 默认路由
app.Run();

(二)属性路由

属性路由可以修饰控制器类、控制器的操作方法。

举例(修饰方法):

using Microsoft.AspNetCore.Mvc;
namespace ASPNetAPI.Controllers
{
public class RouteController: Controller
{
    [Route("")] // 表示默认路由。直接https://localhost+端口号就可执行该方法
    [Route(自定义路径/自定义路径…")]  // 路径可自定义
    [Route("自定义路径/自定义路径.../{id?}/{name?}")] // 若有参数,参数名必须和方法中的参数名一致(参数名必须一致,参数位置可以任意调换)
    // [Route("~/")] // 该方式不要用,含有~,好像会报错。
    public string testurl(int id, string name) // 测试路由
    {
        return "测试路由 id: "+id+"; name: "+ name;
    }
}
}

(三)属性路由(高级写法)

该写法的好处是,在重命名控制器或操作方法的名称时,不用再修改路由规则。

1. 第一种方式

类的路由修饰:[Route("[controller]")]

方法的路由修饰: [Route("[action]/{id?}/{name?}")]

using Microsoft.AspNetCore.Mvc;
namespace ASPNetAPI.Controllers
{
    [Route("[controller]")]
    public class RouteController: Controller
    {
        [Route("")]
        [Route("[action]/{id?}/{name?}")]
        public string testurl(int id, string name) // 测试路由
        {
            return "测试路由 id: "+id+"; name: "+ name??"未指定该参数名";
        }
 
        [Route("[action]")]
        public IActionResult testurl2() // 测试路由
        {
            ViewData["Title"] = "这是Route路由标题"; 
            ViewData["bookName"] = "这是Route路由名"; 
            return View("~/Views/Book/TestView.cshtml");
        }
 
    }
}

2. 第二种方式

类的路由修饰:[Route("[controller]/[action]")]

方法的路由修饰: [Route("{id?}/{name?}")]

using Microsoft.AspNetCore.Mvc;
namespace ASPNetAPI.Controllers
{
    [Route("[controller]/[action]")]
    public class RouteController: Controller
    {
        [Route("")]
        [Route("{id?}/{name?}")]
        public string testurl(int id, string name) // 测试路由
        {
            return "测试路由 id: "+id+"; name: "+ name??"未指定该参数名";
        }
 
        public IActionResult testurl2() // 测试路由
        {
            ViewData["Title"] = "这是Route路由标题"; 
            ViewData["bookName"] = "这是Route路由名"; 
            return View("~/Views/Book/TestView.cshtml");
        }
 
    }
}

十二、模板href跳转路由

举例:

第一种:

<a href="/music/showonesong/@Model.MusicID" class="btn btn-primary">查看</a>

第二种:

<a href=@Url.Action("showonesong", "music", new{id = mc.MusicID}) class="btn btn-primary">查看</a> <!--Action的参数1是action名,参数2是controller名,参数3是传的值-->

第三种:(推荐)

使用Taghelper的方式。下面章节会讲。

十三、Taghelper 跳转链接

(一)作用

        处理HTML。包括生成链接、创建表单、加载数据等。

(二)引入

        在_ViewImports.cshtml文件顶部引入addTagHelper组件。

        注意引入的代码最后没有分号;

        代码写法如下:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

(三)举例(生成跳转链接):

        在前面章节有讲模板href跳转路由的两种常见写法。除此之外,还有一种是使用Taghelper的特性有asp-controller,asp-action,asp-route-id。      

        使用Taghelper创建跳转路由(生成链接)的好处:programs.cs中的MapControllerRoute配置路由一旦有变,也不会影响跳转路由的当初设定。

1. 写法:

(1)首先配置路由
app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action}/{id?}", // 自定义路由
    defaults: new { controller = "music", action = "Index" } // 默认路由
); 
(2)跳转路由
<a asp-controller="music" asp-action="showonesong" asp-route-id="@Model.MusicID">查看1</a>
<a href="/music/showonesong/@Model.MusicID" class="btn btn-primary">查看2</a>
(3)执行跳转

        是https://localhost:44372/music/ShowOneSong/1

(4)如果配置的路由发生变化
① 写法
app.MapControllerRoute(
    name: "default",
    pattern: "test/{controller}/{action}/{id?}", // 自定义路由(加上了test前缀)
    defaults: new { controller = "music", action = "Index" } // 默认路由
); 
② 执行跳转

        "查看1"的href,通过Taghelper会自动带上test的前缀:https://localhost:44372/test/music/ShowOneSong/1 

        "查看2"的href,还是不变:https://localhost:44372/music/ShowOneSong/1 

十四、模板中引入文件

1. 引入快捷方式

        可直接拖动样式文件到代码里,自动生成link文件的代码。

2. 位置

        将引入代码放在html模板代码的head内部里。

3. 注意

        得用@Url.Content()。

4. 引入样式文件写法

 <link href="@Url.Content("~/css/test.css")" rel="stylesheet" />

        同理,引入图片文件写法:

<img src="@Url.Content("~/images/car.png")" />

十五、模型绑定顺序

        表单中的属性值form values > 路径参数(路由中的值)route values > 查询参数(查询字符串的值)query string。

        例如,在执行如下链接时:在https://localhost:44372/music/singer/123/张杰?id=234&name=周深 中,“123/张杰”是路由参数,“?id=234&name=周深”问号后是查询参数。

        对应的控制器是:

[HttpGet("/music/singer/{id}/{name}")]
public IActionResult Singer(int id, string name)
{
    return Ok(new { Id = id, Name = name }); // 得到的值是123和张杰
}

十六、模型绑定注解验证

(一)Model类

        需要引入DataAnnotations:using System.ComponentModel.DataAnnotations;

        需要在相应字段上方写模型验证,如[Required] 指定该字段必填,[Display(Name = "XXX")]指定该字段名昵称。

        若显示自定义的提示内容,则写法是:[Required(ErrorMessage ="请输入歌名")]
例如:

using System.ComponentModel.DataAnnotations;
namespace ASPNetAPI.Models
{
    public class Music
    {
        public int MusicID {  get; set; }
        [Required(ErrorMessage ="请输入歌名")]
        public string MusicName { get; set; }
        public string Description { get; set; }
        public string Singer { get; set; }
        public int PlayTimes { get; set; }
        public double SongPrice { get; set; }
    }
}

(二)cshtml模板文件 

        若显示所有栏位属性的验证错误信息,则在form表单中添加:

<div asp-validation-summary="All"></div> 

        若显示单个栏位属性的验证错误信息,则在form表单中该栏位属性下添加:

<span asp-validation-for="字段名"></span>

        例如:

@model Music
@{
ViewBag.Title = "新增曲目";
}
<form asp-controller="Music" asp-action="AddMusic" method="post" class="mt-3">
    <div asp-validation-summary="All" class="text-danger"></div>
        <div class="mb-3 row">
            <label asp-for="MusicName" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
            <input asp-for="MusicName" class="form-control" placeholder="请输入歌名" />
            <span asp-validation-for="MusicName" class="text-danger"></span>
        </div>
    </div>
    <div class="mb-3 row">
        <label asp-for="Description" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Description" class="form-control" placeholder="请输入备注" />
            <span asp-validation-for="Description" class="text-danger"></span>
        </div>
    </div>
    <div class="mb-3 row">
        <label asp-for="Singer" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <select asp-for="Singer" asp-items="Html.GetEnumSelectList<MusicSingersEnum>()" class="form-select me-sm-2"></select> <!--通过Html获取枚举值-->
        </div>
    </div>
    <div class="mb-3 row">
        <div class ="col-sm-10">
            <button type="submit" class="btn btn-primary">提交</button>
        </div>
    </div>
</form>

(三)Controller类

        使用ModelState.IsValid进行模型验证。

        例如:

[HttpPost]
public IActionResult AddMusic(Music music)
{
    if (ModelState.IsValid) // 模型验证
    {
        Music newMusic = _musicRepository.CreateSong(music);
        return RedirectToAction("ShowOneSong", new { id = newMusic.MusicID }); // 注意使用  new { id = newMusic.MusicID },而不是直接传递newMusic.MusicID,直接传递会导致路由参数名映射不对
    }
    return View();
}

十七、MVC架构的简单项目例子

自建一个模拟数据库,并测试获取该数据库的值。

(一)实体类(项目名/Models/Book.cs)

namespace ASPNetAPI.Models
{
    public class Book
    {
        public int BookID {  get; set; }
        public string BookName { get; set; }
        public string Description { get; set; }
        public string Author { get; set; }
        public double Price { get; set; }    
    }
}

(二)模拟存储库的接口(项目名/Models/IBookRepository.cs)

namespace ASPNetAPI.Models
{
    public interface IBookRepository
    {
        Book GetBook(int id);
    }
}

(三)模拟存储库的实体类(项目名/Models/MockBookRepository.cs)

namespace ASPNetAPI.Models
{
    public class MockBookRepository : IBookRepository
    {
        private List<Book> _booksList;
        public MockBookRepository()
        {
            _booksList = new List<Book>()
            {
                new Book() {BookID=1,BookName="数据结构",Author="萝卜",Price=30.0 },
                new Book() {BookID=1,BookName="操作系统",Author="派大星",Price=45.5 },
                new Book() {BookID=1,BookName="计算机组成原理",Author="海绵宝宝",Price=24.0 },
            };
        }
        public Book GetBook(int id)
        {
            return _booksList.FirstOrDefault(bk=> bk.BookID==id);
        }
    }
}

(四)控制器中注入依赖(项目名/Controllers/BookController.cs)

using ASPNetAPI.Models;
using Microsoft.AspNetCore.Mvc;
namespace ASPNetAPI.Controllers
{
    public class BookController: Controller
    {
        private readonly IBookRepository _bookRepository;

        public BookController(IBookRepository bookRepository) {
            _bookRepository = bookRepository;
        }

        public string Index()
        {
            return _bookRepository.GetBook(1).BookName;
        }
    }
}

(五)Program.cs 中注册 IBookRepository

using ASPNetAPI.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IBookRepository, MockBookRepository>(); // 注册 IBookRepository 和它的实现类 MockBookRepository
builder.Services.AddControllersWithViews(); // 添加 Mvc 服务
var app = builder.Build();
app.MapControllerRoute(   // 配置路由, 映射控制器(MVC中间件添加到请求管道中)
    name: "default",
    pattern: "{controller}/{action}/{id?}",  // 自定义路由
    defaults: new { controller = "Book", action = "Index" });  // 默认路由
app.Run(); // 启动程式

(六)测试(浏览器URL中输入)

1. 默认路由

        https://localhost:44372/或者https://localhost:44372/Book/Index

2. 通过bookID获取值

        https://localhost:44372/Book/ByBookID/2

十八、AddMvcCore & AddMvc

AddMvcCore:只提供了最核心的MVC服务。AddMvc添加了所有MVC服务(包含了第三方常用服务,内部会调用AddMvcCore)


 


http://www.kler.cn/a/472616.html

相关文章:

  • 《解锁计算机视觉智慧:编程实现图片场景文字描述的开源宝藏》
  • flink的EventTime和Watermark
  • 2025新春烟花代码(二)HTML5实现孔明灯和烟花效果
  • EXCEL: (二) 常用图表
  • Bash语言的数据库编程
  • 【Axios使用手册】如何使用axios向后端发送请求并进行数据交互
  • 制造业该怎么做数据治理?
  • 【免费】2000-2010年各省第二产业就业人数数据
  • HarmonyOS 应用开发实践——基于 `Index` 组件的多语言、主题模式与文件存储管理
  • json报文的序列化与反序列化问题总结(对比fastjson和jackson)
  • QT鼠标、键盘事件
  • JavaAPI.02.包装类与正则表达式
  • 在vue3项目中利用自定义ref实现防抖
  • C++和Python中负数取余结果的区别
  • imageio 图片转mp4 保存mp4
  • 深度学习从入门到实战——卷积神经网络原理解析及其应用
  • js 根据条件判断样式
  • ElasticSearch内存占用率过高怎么办?
  • Java中将特征向量转换为矩阵的实现
  • CentOS 8 系统中添加 4G 大小的swap(交换空间)
  • 如何理解支持向量回归
  • 滑动变阻器的三种连接方式
  • linux中给自己编译的模块签名
  • element-ui下拉输入框+resetFields无法回显
  • 【物联网原理与运用】知识点总结(上)
  • node-sass@4.14.1报错的最终解决方案分享