ASP.NET5 MVC6 beta4中,“@helper指令”不再默认起作用。

13

自从我将ASP.NET5项目更新到beta4版本(包含在Visual Studio 2015 RC中的版本),我所有使用帮助器(helper)的Razor视图都存在问题,比如:

@helper foo()
{
   <h2>Bar</h2>
}

导致以下错误:

错误 CS0103: 当前上下文中不存在名称为 'helper' 的内容。

@helper指令不再受支持了吗?有人能指点一下这个问题的任何有用信息吗?

4个回答

14
< p >自beta 4以来,@helper指令已被删除,因为它对其他Razor功能施加了太多的限制:https://github.com/aspnet/Razor/issues/281

编辑
需要明确的是:根据GitHub问题讨论,微软不打算在ASP.NET Core中重新引入@helper指令或替代它。


1
视图助手从一开始就是个坏主意。 - Chris Pratt
17
这是我最不喜欢的一种Stack Overflow(简称SO)回答类型:它回答了问题,但完全没有提供任何其他选择或指导正确解决相同问题的方法。替代这个帮手的是什么,或者更确切地说,应该用什么来代替它呢? - Jon Story
3
我理解你的观点。但是,在我指出的问题中,即使是微软也没有提出任何替代方案。不幸的是,目前没有任何替代方案,并且这被认为是一项过时的功能。当阅读相关问题后可以明白我所说的内容,因此我不明白为什么需要发表这样的评论。 - Henk Mollema
2
这恰恰是关键所在 - 我不知道微软是否已经推出了替代品,因此在答案中包含这一点会很好。 - Jon Story

4

不必使用辅助方法,您可以使用带有视图模型的部分视图来实现相同的功能。只需将相关参数传递到Html.Partial命令中即可。


请参考Eilon在此处的答案,以了解示例:https://dev59.com/41kT5IYBdhLWcg3wbO8g - jspinella
如果您使用 .NET Core 3+,一个本地的 void 方法可以调用自身,从而消除创建新部分类的需要。 - jspinella

3
在 .Net Core 及以上版本中,您可以使用function derivative来实现相同的目的。
@functions {
    private void RenderFoo()
    {
        <h2>Bar</h2>
    }
}

<div>@{ RenderFoo(); }</div>

那样可以构建字符串,而不是像助手一样混合Razor类型的HTML代码? - Savage
啊,抱歉让你感到困惑。不,函数导数和@helper的工作方式相同,它们可以渲染任何Razor模板。我会改进我的示例以使其更清晰明了。 - ajbeaven

0

Templated Razor Delegates将是一个不错的选择。

声明foo

@{
    Func<dynamic, object> foo =
    @<h2>Bar</h2>
    ;
}

渲染foo

@foo(null)

作为一个高级示例,这可以转化为本地化助手。
例如,对于包含HTML标签的文本进行本地化。
请像以下代码一样重写: 请在<a href="~/logout">注销</a>后执行

page.cshtml

@inject SubstitutableHtmlUsecase SubstitutableHtmlUsecase
@inject IStringLocalizer<Msg> Msg


@SubstitutableHtmlUsecase.Render1(
    Msg["Please {logout} once"],
    "{logout}", @<a href="~/logout">@Msg["Logout"]</a>)

SubstitutableHtmlUsecase.cs

using Microsoft.AspNetCore.Html;
using System.Text.Encodings.Web;

namespace App.Usecases
{
    public class SubstitutableHtmlUsecase
    {
        public IHtmlContent Render1(string body, string marker1, Func<object?, IHtmlContent> razor1)
        {
            var parts = body.Split(marker1);

            return new Renderer(
                (writer, encoder) =>
                {
                    for (int idx = 0; idx < parts.Length; idx++)
                    {
                        bool isLast = (idx + 1 == parts.Length);
                        encoder.Encode(writer, parts[idx]);
                        if (!isLast)
                        {
                            razor1(null).WriteTo(writer, encoder);
                        }
                    }
                }
            );
        }

        private class Renderer : IHtmlContent
        {
            private readonly Action<TextWriter, HtmlEncoder> _writer;

            public Renderer(Action<TextWriter, HtmlEncoder> writer)
            {
                _writer = writer;
            }

            public void WriteTo(TextWriter writer, HtmlEncoder encoder)
            {
                _writer(writer, encoder);
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接