@Helpers在ASP.NET核心发生了什么?

当您将基于Razor的应用程序端口移植到ASP.NET核心时,无论是它的 MVC应用程序或网页应用程序,您可能会注意到添加一个 @functions 阻止你的 .cshtml. 文件按预期工作, 但任何尝试添加一个 @helpers 块根本不起作用。

A Prepasasp.net核心剃须刀的帮助 是暴露作为一种方法的剃刀语法的可重复使用片段,用于将HTML渲染到浏览器。 ASP.NET Core提供了许多用于创建可重复使用的HTML片段的其他选项 - 部分页面, 标签查看组件. 这些方法与一个方法之间的差异 @helper block is that the @helper block can be declared in a page. So, 虽然在应用程序中可能不那么可重复使用,但它是一个 如果您只想在一页中使用该方法,非常有用。它意味着文件之间的切换较少。

您可能有一个页面包含许多无序列表,所有 需要略有不同的造型。以下是您如何声明prepasasp.net 核心剃刀帮助者协助:

@helper RenderList(IEnumerable<string> items, string style){
    <ul>
        @foreach(var item in items){
            <li class="@style">@item</li>
        }
    </ul>
}

使用以下语法调用此页面内:

@RenderList(new[]{"A","B","C"}, "pretty")

The @helper syntax wasn't included in ASP.NET Core. Instead, in ASP.NET Core 2.x或更早版本,您可以使用一个模板剃刀委托,其中有 自从剃刀首次介绍以来一直存在。模板剃刀的早期例子 delegates tend to make use of the dynamic type, probably because 剃刀本身植根于网页框架中,致力于使用 dynamic 类型。因此,看到模板剃须刀是很常见的 代表如下声明:

Func<dynamic, object> template = @<div>@item</div>

The dynamic parameter can represent any type. It is exposed within the Razor template by the special parameter named item. Unlike the @helper example which can be designed to accept any 参数数量,模板剃刀委托只能拍一个。如果你想申请这个 approach to replicate the RenderList helper defined earlier, you would create a class to 打包列表项和字符串。然后您可以定义委托:

@{
    class ListPackage
    {
        public string[] ListItems { get; set; }
        public string Style { get; set; }
    }
    
    Func<dynamic, object> template = @<ul>
        @foreach (var listItem in item.ListItems)
        {
            <li class="@item.Style">@listItem</li>
        }
    </ul>;
}

上面的示例显示模板被声明为本地方法 (in a Razor @{ } block), you can also declare the template in a @functions 堵塞。您可以使用页面/视图的内容部分中的模板:

@template(new ListPackage { ListItems = new[] { "A","B","C" }, Style = "pretty" })

动态方法提供了一点灵活性的潜力 您可以将任何对象传递给委托,只要它有一个 ListItems property that can be enumerated, and a Style property that can be rendered.

您可以通过将模板声明为一个更强烈的方法 Func<[some type], IHtmlContent>。模板的定义 更改以下内容:

@{
    Func<ListPackage, IHtmlContent> template = @<ul>
        @foreach (var listItem in item.ListItems)
        {
            <li class="@item.Style">@listItem</li>
        }
    </ul>;
}

这种方法只能用作本地方法。它不起作用 @functions block. You will also need to add a using directive to reference Microsoft.AspNetCore.Html. The usage within the content part of the page remains the same.

ASP.NET核心3.

一些东西相对静静地滑入ASP.NET核心3.0,很大程度上 由布拉泽眩光出来的。其中一个是更正式的 更换剃刀助手。您现在可以在身体中包含HTML标记 代码块中声明的方法作为先前,或者在其中的本地方法中 @functions 堵塞。该方法应该是 return void, or Task if it requires asynchronous 加工。以下是列表帮助程序是如何用ASP.NET Core 3编写的:

@{
    void Template(string[] listItems, string style) 
    {
        <ul>
        foreach (var listItem in listItems)
        {
            <li class="@style">@listItem</li>
        }
        </ul>
    }
}

就像旧的帮助方法一样,方法可以采取任何数量的方法 参数。在输出所在的位置调用方法的语法 to be rendered differs slightly because it returns void, so it needs to be called in a local code block:

@{ Template(new[] { "A","B","C" },  "pretty" ); }

应该指出的是,所有这些方法都是基于剃刀的使用,因此它们只能在剃刀中工作(.cshtml.) 文件。它们不适用于标准C#类文件。

概括

大多数时候,涉及额外文件的解决方案将是 提供HTML可重用片段的最佳选择。但如果你的重用案例 没有超越当前页面,模板剃刀代表将为您服务 在ASP.NET Core 2.x或更低中,ASP.NET核心看到了介绍 许多人的解决方案 - 在方法身体内标记。