MVC 3 Razor,自定义标记/部分的助手

Jos*_*osh 10 html-helper razor asp.net-mvc-3

我甚至不确定这是否可行,但我想我会检查是否有办法让这更容易.

首先,我的网站中有一些重复的标记,如下所示:

<div class="module">
    <h3>Title</h3>
    <div>
        <p>Information goes here</p>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

我想要做的是将它包装在某种辅助/部分中,以便我可以做这样的事情

@MyHelper("This is my Title") {
    <p>Here is my custom markup</p>
}
Run Code Online (Sandbox Code Playgroud)

然后,当它呈现时,它将通过<h3></h3>div中的自定义标记之间的参数注入传入的标题.自定义标记可以是从测试,表单控件到局部视图的任何内容.这是可能的吗?

sla*_*wek 15

还有另一种方式,没有一次性技巧,这也需要少一点工作,非常适合小帮手.

@helper MyHelper(string title, Func<object, object> markup) {
    <div class="module">
        <h3>Title</h3>
        <div>
            <p>@markup.DynamicInvoke(this.ViewContext)</p>
        </div>
    </div>
}
Run Code Online (Sandbox Code Playgroud)

这个助手的用法如下:

@MyHelper("This is my Title", 
    @<p>Here is my custom markup</p>
)
Run Code Online (Sandbox Code Playgroud)

或者有多行:

@MyHelper("This is my Title", 
    @<text>
        <p>More than one line</p>
        <p>Of markup</p>
    </text>
)
Run Code Online (Sandbox Code Playgroud)

例如,Telerik MVC控件使用此技巧让您在文档加载时添加javascript代码.

这也是一个很好的例子.还有一些信息在这里.


Jim*_*iTh 12

好吧,这是使用HTML帮助扩展程序做一些接近它的"标准"方法.什么Html.BeginForm()做的非常简单的版本.

方法:只需返回一个IDisposable,并让using声明处理其余部分.

这只是概念的一个例子(尽管它有效).不打算立即重复使用.使用大量快捷方式快速编写,而不是生产代码,大量改进和优化的机会,可能有愚蠢的错误,可以使用TagBuilder等.可以轻松修改以重用Wrapper类用于不同的...包装(甚至可能是一个已经在ASP.NET MVC中的通用 - 没有一个需要).

public static class WrapHelper
{
    private class Wrapper : IDisposable
    {
        private bool disposed;
        private readonly TextWriter writer;

        public Wrapper(HtmlHelper html)
        {
            this.writer = html.ViewContext.Writer;
        }

        public void Dispose()
        {
            if (disposed) return;

            disposed = true;

            writer.WriteLine("  </div>");
            writer.WriteLine("</div>");
        }
    }

    public static IDisposable Wrap(this HtmlHelper html, string title)
    {
        TextWriter writer = html.ViewContext.Writer;

        writer.WriteLine("<div class=\"module\">");
        writer.WriteLine("  <h3>" + html.Encode(title) + "</h3>");
        writer.WriteLine("  <div>");

        return new Wrapper(html);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

@using (Html.Wrap("Title"))
{
    <p>My very own markup.</p>
}
Run Code Online (Sandbox Code Playgroud)