Loading

ASP.NET Core MVC Razor小记

_Layout模板

常规的页面一般由头部导航、左侧菜单、中间主体内容主成,而其中唯一变动的基本就只有中间主体内容了,而Layout模板就是用来做这样一件事,编写好模板,需要变动的地方则使用@RenderBody()方法

image-20211214211357520

_ViewStart

我们尝试在_Layout模板的footer标签中增加一点内容,运行程序,发现也会跟着改动,明明在Index文件中未作任何操作

image-20211214211644003

image-20211214211653969

这是因为有_ViewStart的存在,发现里面默认有这样一行代码

@{
    Layout = "_Layout";
}

如果在Index中头部未声明使用任何模板则会使用ViewStart定义的默认模板,默认一般是不定义,如果赋值为null或其它默认,则优先使用页面中定义的

image-20211214212021169

页面加载顺序

_ViewStart.cshtml-->_Index.cshtml-->_Layout.cshtml
  1. 首先_ViewStart在所有View加载之前加载,设置了默认的模板页
  2. 接着由Controller指定的页面查找Index.cshtml加载,并读取该页面的Layout设置(在头部@{}中设置,如未设置则使用默认模板)
  3. 最后根据Index页面的Layout设置的模板页查找对应的模板页加载

我们尝试将ViewStart的Layout设置为_Layout1,运行程序,可以看到报错了

image-20211214212521057

View的查找规则:先查找Controller对应的文件夹,若未找到,则到View/Shard和Pages/Shard文件夹查找,若最终还是未找到,则抛出异常

TagHelper

TagHelper与HtmlHelper对比

以下是在视图中使用TagHelper和HtmlHelper对比

@model HelloCore.Models.Book
@{
    Layout = null;
}
@*HtmlHelper*@
@Html.EditorFor(m=>m.Name)
@Html.LabelFor(m=>m.Name)
<br />
@*TagHelper*@
<label asp-for=Name></label>
<input asp-for=Name />

通过浏览器F12看看这俩到底有啥区别

image-20211214220717549

emm..目前看起来生成后的代码是没有多大区别,个人感觉主要区别还是在写法上,TagHelper相对HtmlHelper更为接近原生写法

比如,现在给它们都加一个样式,看看二者的写法

image-20211214221141728

自定义TagHelper

创建一个类,名称建议以TagHelper结尾,并继承自TagHelper

重写ProcessAsync方法

public class LabelTagHelper : TagHelper
    {
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            //校验label是否设置了show-type
            if (output.Attributes.TryGetAttribute("show-type",out TagHelperAttribute tagHelperAttribute))
            {
                //校验设置的show-type是否为bookCode
                if (tagHelperAttribute.Value.ToString().Equals("bookCode"))
                {
                    //设置该标签的class为codeColor样式
                    output.Attributes.SetAttribute("class", "codeColor");
                    //获取标签的Contne内容
                    string content = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); ;
                    //设置Content
                    output.Content.SetContent($"MVP{content}");
                }
            }
        }
    }

效果如下:

image-20211214224434314

之所以会“乱码”,应该是编码问题,转一下就OK了

TagHelper注册

在_ViewImports中添加一行

@addTagHelper *,HelloCore

表示添加该程序集下所有TagHelper

TagHelper的作用范围

目前上面这种方式只能作用于label标签,如果p标签也要用,可以在类上加上特性注解

[HtmlTargetElement("p")]
public class LabelTagHelper : TagHelper{

}

但这样一来,label标签上就不起作用了

改造一下:

[HtmlTargetElement("p", Attributes = "show-type", ParentTag = "div")]
    [HtmlTargetElement("label", Attributes = "show-type", ParentTag = "div")]
    public class LabelTagHelper : TagHelper{
    
    }

如果HtmlTargetElement设置多个,则是or的关系,也就是只要满足一个就会生效,通过Attributes和ParentTag属性会极大的缩小要作用的对象范围,ParentTag表示父标签

如果个别标签想要屏蔽TagHelper,则可以在标签尖括号后加上叹号

<!label show-type="bookCode" asp-for=Name class=codeColor></!label>
自定义标签

在页面中添加一个标签

<BookCode>1001</BookCode>

新增一个BookCodeTagHelper

public class BookCodeTagHelper : TagHelper
    {
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            output.Attributes.SetAttribute("class", "codeColor");
            string content = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); ;
            output.Content.SetContent($"MVP{content}");
        }
    }

看看最后生成出来的HTML

image-20211215213737249

注意:TagHelper会将大驼峰的命名方式转换成小写并以“-”分割

比如BookCodeTagHelper--->book-code

强大的VS还会根据我们所写的TagHelper给予提示和纠错

1

TagHelper与页面之间的数据传递

假设现在我们编号的前缀不再固定为“MVP”,我们可以这么做

修改TagHelper

image-20211215214712548

修改页面

<book-code prefix="@Model.Prefix"></book-code>

还可以直接在标签中的prefix属性上传入整个@Model,然后在TagHelper中取出前缀属性拼接上去,效果是一样的

取消标签输出

自定义标签代码

[HtmlTargetElement("div", Attributes = "suppress-type")]
    public class SuppressTagHelper : TagHelper
    {
        public string SuppressType { get; set; }
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (SuppressType.Equals("Suppress"))
            {
                output.SuppressOutput();
            }
        }
    }

index代码

<div suppress-type="Suppress" >1002</div>

运行程序,可以看到页面中并未显示这个div,F12查看也并没有这个标签

image-20211215220240243

TagBuilder

TagBuilder可以辅助生成标签

[HtmlTargetElement("div", Attributes = "simple-type")]
    public class SimpleTagHelper : TagHelper
    {
        public string SimpleType { get; set; }
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (SimpleType.Equals("1"))
            {
                output.Content.SetHtmlContent("<p>傲慢与偏见</p>");
            }
            else if (SimpleType.Equals("2")) {
                var p = new TagBuilder("p");
                p.InnerHtml.Append("傲慢与偏见");
                p.AddCssClass("codeColor");
                output.Content.SetHtmlContent(p);
            }
        }
    }
<div simple-type="1"></div>
<div simple-type="2"></div>

image-20211215221608910

posted @ 2021-12-14 23:13  傲慢与偏见luc  阅读(64)  评论(0编辑  收藏  举报