无法在MVC中定义自定义渲染器lambda

时间:2013-03-12 13:17:31

标签: c# asp.net-mvc razor

我想在我的MVC视图中将自定义渲染器定义为lambda,我可以在局部使用它来多次渲染相同的东西。我打算将它存储在视图数据中。到目前为止,我已经创建了这个扩展方法来存储渲染器:

public static class HtmlHelperExtensions
{
   public static void DefineRenderer<TModel>(this HtmlHelper<TModel> html, string rendererName, Action renderer)
   {
      html.ViewData["_Renderer" + rendererName] = renderer;
   }
}

我正在尝试在我的视图中定义渲染器,但它无法正常工作;我假设我的语法已关闭。有人能告诉我这里我做错了什么吗?我只是希望它在调用时呈现测试段落:

@Html.DefineRenderer("AnalysisTableHeader", () => {
    <p>test paragraph</p>
@});

3 个答案:

答案 0 :(得分:1)

DefineRenderer - 方法需要返回除void之外的任何内容,例如IHtmlString使用剃刀@ - 语法调用它,否则您需要像这样调用它:

@{
    Html.DefineRenderer("AnalysisTableHeader", () => {
        <p>test paragraph</p>
    });
}

编辑:抱歉,我看到renderer参数的类型为System.Action。我认为它必须是System.Func<dynamic, HelperResult>类型,你需要调用它

@{ Html.DefineRenderer("AnalysisTableHeader", @<text><p>test paragraph</p></text>); }
例如,

。然后,您可以像这样呈现它:render(null).ToHtmlString()。无论如何要注意,如果你在视图中做这样的事情,你可能会遇到部分视图缓存的问题。

答案 1 :(得分:0)

我仍然不能100%确定这是否是你所需要的,但也许它会有所帮助。 在部分视图中定义@helper,并根据Model中的值决定要呈现的版本:

在代码中使用标题类型声明枚举

public enum HeaderTypes
{
    AnalysisTable,
    SomethingElse
}

然后在你看来

@helper RenderHeader(HeaderTypes headerType) {
    switch (headerType)
    {
        case HeaderTypes.AnalysisTable:
            @: <p>your html</p>
            break;
        default: 
            @: <p>default</p>
            break;
    }
}

@RenderHeader(HeaderTypes.None)
@RenderHeader(HeaderTypes.AnalysisTable)

或者您可以根据字符串值或其他内容进行切换。

答案 2 :(得分:0)

从@ mariozski的评论中得到一些灵感,我设法得到了我想要的行为。我使用@helper作为渲染器。传递给partial的模型包含辅助渲染的结果,即。一个HelperResult。所以它看起来像这样:

public class AnalysisResponseTableViewModel {
    public HelperResult HeaderTypeRowRenderer { get; set; }
    public List<AnalysisUserResponseViewModel> Responses { get; set; }
}

然后,调用视图调用部分如下:

@helper RenderHeaderTypeRow() {
    <tr class="headerTypeRow">
        <td>Header type row</td>
        <td>Goes here</td>
    </tr>
}

@Html.Partial("AnalysisResponseTableContentsPartial",
    new AnalysisResponseTableViewModel {
        Responses = Model.OverallCaseStudyUserResponses,
        HeaderTypeRowRenderer = RenderHeaderTypeRow()
    }
)

最后,部分本身可以像这样多次呈现'标题类型行':

@Html.Raw(Model.HeaderTypeRowRenderer.ToHtmlString())
@{bool reachedSummaryRows = false;}
@foreach (var response in Model.Responses) {
    if (!reachedSummaryRows && !response.IsPass.HasValue) {
        reachedSummaryRows = true;
        @:@Html.Raw(Model.HeaderTypeRowRenderer.ToHtmlString())
    }

    // other table rows here
}