ASP.Net MVC3 - 将剃刀标记作为参数传递

时间:2022-06-11 10:24:15

I have a helper called EditableArea which provides a user with a runtime-editable div (via JS). EditableArea helper checks if an editable area (not related to MVC's Area) with the specified ID exists in the DB, if so then it renders the area's HTML, otherwise it displays default markup specified as a parameter to the helper:

我有一个名为EditableArea的帮助器,它为用户提供了一个运行时可编辑的div(通过JS)。 EditableArea帮助程序检查数据库中是否存在具有指定ID的可编辑区域(与MVC的区域无关),如果是,则呈现该区域的HTML,否则它将显示指定为辅助程序的参数的默认标记:

@Html.EditableArea(someId, "<p>Click to edit contents</p>")

It all works ok, but I'd like to change it so that the default markup is specified not as a string but in razor syntax, something like:

一切正常,但我想更改它,以便默认标记不是作为字符串指定,而是在剃刀语法中,如下所示:

@using (Html.EditableArea(someId))
{
    <p>Click to edit contents</p>
}

Or something similar, like the way @sections work in MVC3.

或者类似的东西,比如@sections在MVC3中的工作方式。

How can I achieve that?

我怎样才能做到这一点?

I can make an IDisposable which in it's Dispose closes the TagBuilder, etc., but I cannot avoid rendering the inner Razor markup even if the helper finds an area with an ID (I can clear the rendered contents in Dispose() but the code inside the { } would still run, which I'd like to skip).

我可以创建一个IDisposable,它的Dispose关闭了TagBuilder等,但即使帮助器找到一个带ID的区域,我也无法避免渲染内部Razor标记(我可以清除Dispose()中的渲染内容但是里面的代码{}仍会运行,我想跳过)。

And if i don't use using is there some other way to pass a razor block to the helper, which may or may not be actually rendered by the helper?

如果我不使用使用是否有其他方法将剃刀块传递给帮助器,帮助器实际可能会或可能不会实现?

2 个解决方案

#1


25  

Here's an example I use to render jQuery Template markup by passing in a template Id and razor-style syntax for the template itself:

这是我用来通过传递模板Id和模板本身的razor样式语法来呈现jQuery模板标记的示例:

public static MvcHtmlString jQueryTmpl(this HtmlHelper htmlHelper, 
    string templateId, Func<object, HelperResult> template) 
{
    return MvcHtmlString.Create("<script id=\"" + templateId + 
        "\" type=\"x-jquery-tmpl\">" + template.Invoke(null) + "</script>");
}

and this would be called with

这将被称为

@Html.jQueryTmpl("templateId", @<text>any type of valid razor syntax here</text>)

Basically just use Func<object, HelperResult> as your parameter and template.Invoke(null) (with arguments if necessary) to render it. Obviously you can skip the call to .Invoke() to avoid rendering the "default" markup.

基本上只需使用Func 作为参数和template.Invoke(null)(如有必要,带参数)来渲染它。显然,您可以跳过对.Invoke()的调用,以避免呈现“默认”标记。 ,helperresult>

#2


3  

Just to expand on the accepted answer, as it took me quite a while to resolve a similar problem and this is the question which popped up. What I really need was a @helper, which would accept razor text, as the template should contain quite some code. I played around for a long while trying to use several versions of type @helper item(Func<object, HelperResult> input), which I found on the web, with no success. Therefore I went for an approach like:

只是为了扩展已接受的答案,因为我花了很长时间来解决类似的问题,这就是出现的问题。我真正需要的是@helper,它会接受剃刀文本,因为模板应该包含相当多的代码。我玩了很长时间试图使用几个版本的@helper项目(Func 输入),这是我在网上找到的,没有成功。因此,我采取了以下方法: ,helperresult>

namespace project.MvcHtmlHelpers
{
    public static class HelperExtensions
    {
        public static MvcHtmlString RazorToMvcString(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
        {
            return MvcHtmlString.Create(template.Invoke(null).ToString());
        }
    }
}

and

@project.MvcHtmlHelpers    
@helper item(other input, MvcHtmlString content)
    {
        <div class="item">
            ...other stuff... 
            <div class="content">
                @content
            </div>
        </div>
    }

and use this via

并使用此通过

@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>))

Now I can use the helper template for both Razor input, but I can also drop in partial views, which is handy at some points. As I am no expert there might be better options, but it seems like a flexible approach to me.

现在我可以使用辅助模板进行Razor输入,但我也可以放入部分视图,这在某些方面很方便。由于我不是专家,可能有更好的选择,但对我来说这似乎是一种灵活的方法。

#1


25  

Here's an example I use to render jQuery Template markup by passing in a template Id and razor-style syntax for the template itself:

这是我用来通过传递模板Id和模板本身的razor样式语法来呈现jQuery模板标记的示例:

public static MvcHtmlString jQueryTmpl(this HtmlHelper htmlHelper, 
    string templateId, Func<object, HelperResult> template) 
{
    return MvcHtmlString.Create("<script id=\"" + templateId + 
        "\" type=\"x-jquery-tmpl\">" + template.Invoke(null) + "</script>");
}

and this would be called with

这将被称为

@Html.jQueryTmpl("templateId", @<text>any type of valid razor syntax here</text>)

Basically just use Func<object, HelperResult> as your parameter and template.Invoke(null) (with arguments if necessary) to render it. Obviously you can skip the call to .Invoke() to avoid rendering the "default" markup.

基本上只需使用Func 作为参数和template.Invoke(null)(如有必要,带参数)来渲染它。显然,您可以跳过对.Invoke()的调用,以避免呈现“默认”标记。 ,helperresult>

#2


3  

Just to expand on the accepted answer, as it took me quite a while to resolve a similar problem and this is the question which popped up. What I really need was a @helper, which would accept razor text, as the template should contain quite some code. I played around for a long while trying to use several versions of type @helper item(Func<object, HelperResult> input), which I found on the web, with no success. Therefore I went for an approach like:

只是为了扩展已接受的答案,因为我花了很长时间来解决类似的问题,这就是出现的问题。我真正需要的是@helper,它会接受剃刀文本,因为模板应该包含相当多的代码。我玩了很长时间试图使用几个版本的@helper项目(Func 输入),这是我在网上找到的,没有成功。因此,我采取了以下方法: ,helperresult>

namespace project.MvcHtmlHelpers
{
    public static class HelperExtensions
    {
        public static MvcHtmlString RazorToMvcString(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
        {
            return MvcHtmlString.Create(template.Invoke(null).ToString());
        }
    }
}

and

@project.MvcHtmlHelpers    
@helper item(other input, MvcHtmlString content)
    {
        <div class="item">
            ...other stuff... 
            <div class="content">
                @content
            </div>
        </div>
    }

and use this via

并使用此通过

@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>))

Now I can use the helper template for both Razor input, but I can also drop in partial views, which is handy at some points. As I am no expert there might be better options, but it seems like a flexible approach to me.

现在我可以使用辅助模板进行Razor输入,但我也可以放入部分视图,这在某些方面很方便。由于我不是专家,可能有更好的选择,但对我来说这似乎是一种灵活的方法。