【问题标题】:Razor Func<object, object> mixed with MvcHtmlStringRazor Func<object, object> 与 MvcHtmlString 混合
【发布时间】:2011-09-21 07:07:05
【问题描述】:

我不是 Razor 语法的专家,但我尝试使用流畅风格的 à là Telerik 的 GUI 组件构建一个通用库。

我有以下几件(大约):

public static MyBox Box(this HtmlHelper helper)
{
    return new MyBox(helper.ViewContext);
}

和:

/// <summary>
/// http://geekswithblogs.net/shaunxu/archive/2010/04/10/lt-gt-htmlencode-ihtmlstring-and-mvchtmlstring.aspx
/// </summary>
public class MyBox : IHtmlString
{
    private readonly ViewContext _viewContext;
    private string _content;
    private string _title;

    public MyBox(ViewContext viewViewContext)
    {
        _viewContext = viewViewContext;
    }

    /// <summary>
    /// See: http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public MyBox Content(Func<object, object> value)
    {
        _content = value.DynamicInvoke(_viewContext).ToString();
        return this;
    }

    /// <summary>
    /// See: http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx
    /// </summary>
    /// <param name="values"></param>
    /// <returns></returns>
    public MyBox Content(params Func<object, object>[] values)
    {
        foreach (var value in values)
        {
            _content += value.DynamicInvoke(_viewContext).ToString();
        }
        return this;
    }

    public MyBox Content(MvcHtmlString content)
    {
        _content = content.ToString();
        return this;
    }

    public MyBox Title(string title)
    {
        _title = title;
        return this;
    }

    public string ToHtmlString()
    {
        using (var stringWriter = new StringWriter())
        {
            WriteHtml((TextWriter)stringWriter);
            return stringWriter.ToString();
        }
    }

    public void Render()
    {
        using (var writer = new HtmlTextWriter(_viewContext.Writer))
            WriteHtml(writer);
    }

    protected virtual void WriteHtml(TextWriter writer)
    {
        writer.WriteLine("<!-- START BOX -->");
        writer.WriteLine("<h1>" + _title + "</h1>));
        writer.WriteLine(_content);
        writer.WriteLine("<!-- END BOX -->");
    }
}

我还有一组返回 MvcHtmlString 的 Html 扩展方法。一个例子是(简化的):

public static class GuiElementExtensions
    {
        private const string FieldContainerHeadingTemplate = @"
<tr><th style=""text-align:left"" colspan=""2"">{0}</th></tr>
";

    public static MvcHtmlString GuiFieldContainerHeading(this HtmlHelper helper, string text)
        {
            return new MvcHtmlString(String.Format(FieldContainerHeadingTemplate, text));
        }
}

然后,在我的 .cshtml 文件中,我执行以下操作:

  @using (Html.BeginForm())
       {
           @(Html.Gui()
                      .Box()
                      .Title("Hello World!")
                      .Content(
                                @<h1>Hello World! This is the cool Gui.Box</h1> 
                       )
        )
 }

调用public MyBox Content(Func&lt;object, object&gt; value),并且有效。 同样,当我尝试以下操作时:

  @using (Html.BeginForm())
       {
           @(Html.Gui()
                      .Box()
                      .Title("Hello World!")
                      .Content(
                                Html.GuiFieldContainerHeading("SubHeading 1")
                       )
        )
 }

它愉快地调用public MyBox Content(MvcHtmlString content) 并按预期工作。

但是,当我尝试执行以下操作时,我无法理解 Razor 编译器引擎的工作原理。我如何让它返回总和

  • @&lt;h1&gt;Hello World! This is Gui().Box()&lt;/h1&gt;(这是一个 Func)
  • Html.GuiFieldContainerHeading("SubHeading 1")(这是一个 MvcHtmlString)

作为一个对象(无论是 Func、MvcHtmlString 还是对象列表?我想在 MyBox 类中的 Content 函数的参数列表中编写通用 Razor 语法,如下所示:

  @using (Html.BeginForm())
       {
           @(Html.Gui()
                      .Box()
                      .Title("Hello World!")
                      .Content(
                                @<h1>Hello World! This is Gui().Box()</h1> 
                                Html.GuiFieldContainerHeading("SubHeading 1")
                Html.TextBoxFor(model => model.Name)
                @<h2>Hello there!</h2>
                       )
        )
 }

我是在正确的轨道上,还是有更简单的方法来做我想做的事?我想将我们系统中的所有“通用 gui 元素”收集到一个通用 DLL 中,因此不是我组织中的每个开发人员都需要在每个项目上重新发明轮子。

任何帮助表示赞赏。


好的,下一个问题:

我已经将 Box 概括为一个 Container,并创建了两个子类 Box 和 HighlightArea。但是,使用以下代码,Razor 编译器会向我发送消息

内联标记块 (@

Content

) 不能嵌套。 只允许使用一级内联标记。

代码不工作,是:

 @(Html.Gui()
              .Box()
              .Title("BoxTitle")
              .Content(@<text>
                        <h1>Hello World! This is the box content</h1> 
                        @Html.GuiFieldContainerHeading("This is the heading")
                        @(Html.Gui().HighlightArea()
                              .Content(
                                @Html.ValidationSummary()
                                @<h1>Jalla</h1>
                              )
                        )
                       </text>
               )

我们有解决方法吗?还是我的方法不可行?

【问题讨论】:

  • 您的示例包含This is Gui().Box() 有点令人困惑。它看起来好像包含一些 C# 代码,但它可能不应该是。
  • 谢谢。我已经更新了问题以避免任何混淆。除了困惑之外,对这个问题有什么想法吗?
  • 下一个问题(感谢 Bill The Lizard 更新问题... :))...对此有任何想法(请参阅问题)

标签: asp.net-mvc-3 razor


【解决方案1】:

您可以使用&lt;text&gt; 标签将所有内容组合成一个参数。

@using (Html.BeginForm())
{
    @(Html.Gui()
        .Box()
        .Title("Hello World!")
        .Content(
            @<text>
                <h1>Hello World! This is Gui.Box</h1> 
                @Html.GuiFieldContainerHeading("SubHeading 1")
                @Html.TextBoxFor(model => model.Name)
                <h2>Hello there!</h2>
            </text>
        )
    )
}

我猜你的例子并没有真正起作用。如果我没记错的话,你可以让它像这样工作:

@<h1>Hello World! This is Gui.Box</h1>
 + Html.GuiFieldContainerHeading("SubHeading 1")
 + Html.TextBoxFor(model => model.Name)
 + @<h2>Hello there!</h2>

&lt;text&gt; 标签似乎更容易。

【讨论】:

  • 工作就像一个魅力。谢谢! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多