我有一个Razor助手函数,它可以创建一个可重用的HTML面板,省go 了我一遍又一遍地编写相同的HTML.

@helper DefaultPanel(string panelTitle) {
    <div class="panel">
        <div class="panel-logo"><img src="/logo.png"></div>
            <div class=panel-inner">
                <p class="panel-title">@panelTitle</p>
                <div class="panel-content">
                    /* Can I pass content to be rendered in here here? */
                </div>
            </div>
        </div>
    </div>
}

我想知道,是否有可能重复使用这个帮助程序,用更多的HTML填充.panel-content,以允许进一步的灵活性和代码重用——similar到下面这样的内容:

@LayoutHelpers.DefaultPanel("Welcome back") {
    <div class="panel-content-inner">
        <p>Welcome back, please select from the following options</p>
        <a href="#">Profile</a>
        <a href="#">My Defails</a>
    </div>
}

使用时.NET MVC我注意到Html.BeginForm()Html.BeginForm声明的@using语句中包装代码时做了类似的事情,比如:

@using (Html.BeginForm("Index", "Login", FormMethod.Post))
{
    <div>This content gets rendered within the <form></form> markup.</div>
}

但是,使用@helper种方法能做到这一点吗?如果不是,是否可以创建一个HtmlHelper扩展来做与Html.BeginForm()方法类似的事情呢?

您可以使用@section语法做一件非常类似的事情,如图here所示

在此处输入图像描述

这似乎是一件非常有用的事情,而且奇怪的是,在组件级别上没有简单的方法可以做到这一点.

推荐答案

有两种方法可以实现所需的功能.

1. @helper

创建@helper,它接受您需要的任何参数和一个函数(单个对象参数,返回对象):

@helper DefaultPanel(string panelTitle, Func<object, object> content)
{
    <div class="panel">
        <div class="panel-logo">
                <img src="/logo.png" />
            </div>
            <div class="panel-inner">
                <p class="panel-title">@panelTitle</p>
                <div class="panel-content">
                    @content(null)
                </div>
            </div>
    </div>
}

用法:

@DefaultPanel("title",
@<div class="panel-content-inner">
    <p>Welcome back, please select from the following options</p>
    <a href="#">Profile</a>
    <a href="#">My Defails</a>
</div>
)

函数也可以接受参数,例如here.

2. HtmlHelper extension method

在项目中的任意位置添加以下代码:

namespace System.Web.Mvc
{
    public static class HtmlHelperExtensions
    {
        public static HtmlDefaultPanel DefaultPanel(this HtmlHelper html, string title)
        {
            html.ViewContext.Writer.Write(
            "<div class=\"panel\">" +
            "<div class=\"panel-inner\">" +
            "<p class=\"panel-title\">" + title + "</p>" +
            "<div class=\"panel-content\">"
            );

            return new HtmlDefaultPanel(html.ViewContext);
        }
    }

    public class HtmlDefaultPanel : IDisposable
    {
        private readonly ViewContext _viewContext;
        public HtmlDefaultPanel(ViewContext viewContext)
        {
            _viewContext = viewContext;
        }
        public void Dispose()
        {
            _viewContext.Writer.Write(
            "</div>" +
            "</div>" +
            "</div>"
            );
        }
    }
}

用法:

@using (Html.DefaultPanel("title2"))
{
    <div class="panel-content-inner">
        <p>Welcome back, please select from the following options</p>
        <a href="#">Profile</a>
        <a href="#">My Defails</a>
    </div>
}

扩展方法直接写入上下文.诀窍是返回一个一次性对象,该Dispose方法将在using块结束时执行.

Asp.net相关问答推荐

有人可以解释一下这个Eager 加载示例吗?

Stimulsoft 没有在智能手机中显示正确的 pdf 字体

如何在 ASP.NET 中设置自动实现属性的默认值

当前http上下文的http动词

在正则表达式中允许 -(破折号)

格式化 DataBinder.Eval 数据

使用 C# 和 ASP.NET 从 Gmail/Hotmail/Yahoo 导入通讯簿

在控制器 asp.net mvc 5 的视图上显示错误消息

如何从以特定名称开头的 appsettings 键中获取所有值并将其传递给任何数组?

在 RedirectToAction 调用中传播 QueryString 参数

如何在 ASP.NET Web API 中使用非线程安全的 async/await API 和模式?

ASP.NET Core 中的授权. [Authorize] 属性总是 401 Unauthorized

无法使用单例Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor中的范围服务MyDbContext

如何在 C# 应用程序中调用 VBScript 文件?

实体框架:如何解决外键约束可能导致循环或多个级联路径?

如何从后面的 ASP.NET 代码访问 HTML 表单输入

如何获取程序集的最后修改日期?

global.asax 中的 Application_Error 未捕获 WebAPI 中的错误

以编程方式滚动到锚标记

ASP.NET Web 窗体中的 jQuery 验证插件