微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-mvc-3 – Razor Func与MvcHtmlString混合使用

我不是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> 
                       )
        )
 }

哪个调用公共MyBox内容(Func< object,object> value),并且有效.
同样,当我尝试以下内容时:

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

它愉快地调用公共MyBox内容(MvcHtmlString内容)并按预期工作.

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

> @< h1> Hello World!这是Gui().Box​​()< / h1> (这是一个Func)
> Html.GuiFieldContainerheading(“Subheading 1”)(这是一个MvcHtmlString)

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

@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>
                       )
        )
 }

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

任何帮助赞赏.

好的,下一个问题:

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

Inline markup blocks (@<p>Content</p>) cannot be nested.
Only one level of inline markup is allowed.

代码不起作用,是:

@(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>
               )

我们有解决方法吗?或者我的方法不可行?

解决方法

您可以使用< text>标记将所有内容组合成一个参数.
@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>

但< text>标签似乎更容易.

原文地址:https://www.jb51.cc/aspnet/247087.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐