Bootstrap

完全透彻了解一个asp.net core MVC项目模板2

这是《完全透彻了解一个asp.net core MVC项目模板》的第二篇,如果你直接进入了本篇博文而不知道上下文,请先阅读《完全透彻了解一个asp.net core MVC项目模板》的第一篇。
在这里插入图片描述


原文出处:
https://haigear.blog.csdn.net/article/details/143316084

一、补充几个问题

1、有关导航链接和Tag Helper

我们在views/share文件夹下看到有两个文件_ViewStart.cshtml、_ViewImports.cshtml和,貌似什么都没有写,就几行引用库文件的代码,尤其第二个文件中有这么一句话:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

这句话相当的有作用,否则你的导航就不灵了。原因是TagHelper起到了特别的作用,下面我们来介绍一下它的作用。

  1. Tag Helper的基本原理
    • Tag Helpers是ASP.NET Core中的一个强大特性,它允许你在HTML元素上使用自定义属性来生成服务器端代码。addTagHelper是在服务配置中用于注册Tag Helper的方法,它使得相关的HTML元素能够被“增强”。
    • asp - controllerasp - action属性为例,当你在HTML <a>标签上使用这些属性(如<a asp - controller="Home" asp - action="Index">Home</a>),如果没有注册相应的Tag Helper,这些属性就只是普通的自定义属性,浏览器不会理解它们的特殊用途。
  2. Tag Helper对路由的利用
    • addTagHelper注册了相关的Tag Helper(例如Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper用于<a>标签)后,在服务器端渲染视图时,Tag Helper会介入。它会读取<a>标签上的asp - controllerasp - action属性。
    • 然后,根据ASP.NET Core的路由系统,它会将这些属性值转换为一个有效的URL路径。路由系统会查找Program.cs(或Startup.cs)中定义的路由规则(如app.MapControllerRoute),根据asp - controller(控制器名称)和asp - action(动作名称)来生成一个指向正确控制器动作的链接。
  3. 与HTML的对比
    • 如果没有Tag Helper,<a>标签就会按照HTML的标准行为进行处理。HTML标准规定,<a>标签的href属性用于指定链接的目标URL。当没有href属性,只有文本内容时,浏览器会将其视为普通文本,而不会将其识别为一个可以点击的链接。
    • Tag Helper实际上是在服务器端为<a>标签动态地生成了一个合适的href属性(或者以其他符合HTML标准的方式来创建链接),从而使得在浏览器中呈现的<a>标签能够正确地作为一个链接,引导用户访问指定的控制器和动作。

2、_ViewStart.cshtml与视图引擎加载过程

这个文件更简单了,其实它的作用就是调用layout文件。开始渲染,代码如下:

@{
    Layout = "_Layout";
}

没有什么可讲解的。倒是视图引擎的加载过程有必要在这里说一说:

程序页面开始时视图引擎控制首先加载viewstart文件(从名字上就可以看出来,老版本的dotnet core 项目有一个startup.cs的文件,现在合并到program中去了,这个viewstart文件还留着,估计下次升级也会被合并掉)。在_ViewStart.cshtml文件(通常位于Views文件夹下)中有对布局文件的引用,如@{Layout = “~/Views/Shared/_layout.cshtml”;}。这告诉视图引擎在渲染任何视图时,都要使用这个布局文件作为模板。
当Index.cshtml被请求时,视图引擎首先加载_layout.cshtml,然后将Index.cshtml的内容插入到_layout.cshtml中定义的@RenderBody()位置。@RenderBody()是一个占位符,用于放置具体视图的内容。所以,导航栏部分(包含标签)是布局文件本身的一部分,会在每次渲染视图时一起显示在页面顶部,为用户提供导航链接。

二、model的建立和使用

1、Error.cshtml

在上一篇博文中,我们说过views\share文件夹下的Error.cshtmlh和_ValidationScriptsPartial.cshtml需要配合models来讲解。那么我们现在来看看,为什么,首先我们来看看Error.cshtml的代码:

@model ErrorViewModel
@{
    ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
    <p>
        <strong>Request ID:</strong> <code>@Model.RequestId</code>
    </p>
}

<h3>Development Mode</h3>
<p>
    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>
    It can result in displaying sensitive information from exceptions to end users.
    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
    and restarting the app.
</p>

它的第一行就开始引入了模型,在下面还是用到了模型的ShowRequestID属性:

if (Model.ShowRequestId)
{
    <p>
        <strong>Request ID:</strong> <code>@Model.RequestId</code>
    </p>
}

2、ErrorViewModel.cs

这个文件是models文件夹下面唯一的文件,我们来看看代码

namespace WebApplicationDemo.Models
{
    public class ErrorViewModel
    {
        public string? RequestId { get; set; }

        public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
    }
}

其实,这个model文件普通得再普通不过了,就定义了一个属性和一个方法。很基础的C#知识,这里就不逐句讲解了。
原文出处:
https://haigear.blog.csdn.net/article/details/143316084

三、来一个自己的页面

1、建立模型文件

模型文件我们还是用前面博文《
一步一步从微信小程序获取asp.net Core API的数据中》使用过的Personalinfo的模型,可以直接拷贝过来

using System.ComponentModel.DataAnnotations;
using System.ComponentModel;

namespace WebApplicationDemo.Models
{
    public class PersonalInfo
    {
        [Required]
        [StringLength(50)]
        [DefaultValue("张三")]
        public string? Name { get; set; }

        [Required]
        [Range(0, 150)]
        [DefaultValue(24)]
        public int? Age { get; set; }

        [Required]
        [StringLength(10)]
        [DefaultValue("男")]
        public string? Gender { get; set; }

        [Required]
        [EmailAddress]
        [DefaultValue("[email protected]")]
        public string? Email { get; set; }

        [Required]
        [Phone]
        [DefaultValue("13788888888")]
        public string? PhoneNumber { get; set; }

        [Required]
        [DataType(DataType.Date)]
        [DefaultValue("2000-01-01")]
        public DateTime BirthDate { get; set; }

        [Required]
        [StringLength(100)]
        [DefaultValue("张家口市张家镇张家村张家冲21号")]
        public string? Address { get; set; }


        [StringLength(50)]
        [DefaultValue("码农")]
        public string? Occupation { get; set; }

        [Required]
        [StringLength(30)]
        [DefaultValue("China")]
        public string? Nationality { get; set; }
    }
}

2、建立视图页面

有了模型了,我们就可以利用VS的向导来直接建立一个视图页面,在Views文件夹上右键菜单,选择添加“视图”:
在这里插入图片描述
添加视图时,选在模板Details,省得自己写代码,同时别忘记选择我们刚刚前面建立的模型类Personalinfo,选择好后一键生成即可得到视图文件了:
在这里插入图片描述
生成的页面代码自己如下:

@model WebApplicationDemo.Models.PersonalInfo

@{
    ViewData["Title"] = "View";
}

<h1>View</h1>

<div>
    <h4>PersonalInfo</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Name)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Name)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Age)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Age)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Gender)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Gender)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Email)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Email)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.PhoneNumber)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.PhoneNumber)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.BirthDate)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.BirthDate)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Address)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Address)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Occupation)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Occupation)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Nationality)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Nationality)
        </dd>
    </dl>
</div>
<div>
    @Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
    <a asp-action="Index">Back to List</a>
</div>

我们发现,其实这个页面与前面我们介绍的index.cshtml页面没有什么差别,差别在@后面,大量的使用了Html关键字而不是MOdel,最后个div中包含了一个@Html.ActionLink(“Edit”, “Edit”, new { /* id = Model.PrimaryKey */ }) 我们来一起看看这些是什么意思?

关于Html.DisplayFor

a、DisplayFor方法简介

  • @Html.DisplayFor是ASP.NET MVC 和ASP.NET Core MVC 中常用的一个 HTML 辅助方法(HTML Helper)。它主要用于在视图中显示模型(model)的某个属性(在这个例子中是Nationality属性)的值。
  • 表达式语法(model => model.Nationality)的作用
    这里的model => model.Nationality是一个 Lambda 表达式。它指定了要显示的模型属性。前面的model.Nationality,model.Occupation,model.Name,model.Age都采用的这样方法来显示。
    具体来说,model代表视图中的模型对象(这个对象是由控制器传递给视图的)。=>是 Lambda 表达式的操作符,model.Nationality表示要获取模型对象的Nationality属性。这个 Lambda 表达式告诉DisplayFor方法具体要显示模型中的哪个属性。
    b、工作原理
    当视图被渲染时,DisplayFor方法会根据模型对象的类型和Nationality属性的类型来决定如何显示这个属性的值。
    例如,如果Nationality是一个简单的字符串类型(如 “Chinese”),它可能会直接将这个字符串显示在页面上。如果Nationality是一个复杂的对象,DisplayFor可能会根据对象的ToString方法或者其他自定义的显示逻辑来呈现它的值。
    另外,DisplayFor方法还会考虑数据注解(Data Annotations)等因素。如果在模型类的Nationality属性上有[DisplayFormat]或其他相关的数据注解,DisplayFor会按照注解的要求来显示属性值,例如按照指定的日期格式显示日期属性,或者按照指定的文本格式显示数值属性等。。

关于Html.ActionLink

a. @Html.ActionLink的作用

  • 和前面的Html.Dispplayfor一样@Html.ActionLink也是一个HTML辅助方法(HTML Helper),它的主要作用是生成一个HTML超链接(<a>标签)。
  • 在这个例子中,@Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ })会生成一个链接,链接的文本是“Edit”。它会将用户引导到名为“Edit”的操作(通常是控制器中的一个方法),并且在理想情况下,会将与当前模型相关的主键(这里代码被注释掉了,假设是Model.PrimaryKey)作为参数传递过去。

b. 为什么是@Html.ActionLink而不是@Model.ActionLink

  • 首先,Model通常代表视图模型对象,它的主要目的是在视图和控制器之间传递数据,如业务逻辑相关的数据、状态信息等。它一般不包含用于生成HTML链接的方法。
  • @Html.ActionLink是由ASP.NET提供的HTML辅助方法,它属于System.Web.Mvc.Html命名空间(在旧版本的MVC中)或者相关的ASP.NET Core命名空间。这些HTML辅助方法是为了方便在视图中生成各种HTML元素,利用了ASP.NET的路由系统和内部逻辑来构建正确的链接,这是一种与视图渲染和路由相关的功能,不是视图模型本身应该承担的职责。

如果我们此时调整好homecontroller中的路由访问的话(具体如何调整,可以参本章的4小节“看看效果”),得到的是一个没有任何信息的浏览页
在这里插入图片描述
所以,我们需要给它配上一个控制器来显示数据。

3、建立控制器

与建立视图文件一样,在controllers文件件上右键菜单,选择添加“控制器”,选择
在这里插入图片描述

打开文件,修改代码为

using Microsoft.AspNetCore.Mvc;
using WebApplicationDemo.Models;

namespace WebApplicationDemo.Controllers
{
    public class PersonalInfoController : Controller
    {

        public IActionResult Index()
        {
            var personalInfo = new PersonalInfo
            {
                Name = "张三",
                Age = 24,
                Gender = "男",
                Email = "[email protected]",
                PhoneNumber = "13788888888",
                BirthDate = new DateTime(2000, 1, 1),
                Address = "张家口市张家镇张家村张家冲21号",
                Occupation = "码农",
                Nationality = "China"
            };
            return View(personalInfo);
        }
        

    }
}

如果,我们此时运行程序观察效果,一定还是与原来一样,根本没任何改变,那么问题出在哪里呢??

有可能遇到的问题

按照ASP.NET Core MVC 的约定,视图文件的名称通常应该与控制器方法的名称相同。并且视图文件应该位于Views文件夹下的与控制器名称对应的子文件夹中
1、如果控制器是PersonalInfoController,视图文件应该在Views/PersonalInfo文件夹中,不能随便乱丢在其他文件件中。
2、控制器方法是Index,视图文件应该是Index.cshtml。我们这个项目的PersonalinfoController中的方法是Index,所以视图文件名称就是index.cshtml。不用怀疑,我们每个文件夹中都可以拥有一个index.cshtml,而不是以前我们写网站时一个网站只有一个index.asp/index.jsp/index.html。
保证上述问题后,基本就可以得到正确的浏览结果了。
看效果之前,我们也在导航中把我们的页面给挂上去,这样才能和现在的项目融为一体。那么我们需要干两件事:

a、在layout文件中增加一个链接

参照第一篇博文,找到layout中的nav标签,然后在其中增加下面的内容即可:

 <li class="nav-item">
     <a class="nav-link text-dark" asp-area="" asp-controller="PersonalInfo" asp-action="index">PersonalInfo</a>
 </li>

看看效果
在这里插入图片描述
好了,到这里,我们的《完全透彻了解一个asp.net core MVC项目模板》算是完整了,感兴趣的同学可以继续关注我的博客。
原文出处:
https://haigear.blog.csdn.net/article/details/143316084

;