Как передать содержимое HTML в частичный вид в MVC-Razor, как блок "для"

Я использую тему Chromatron для панели администратора в своем приложении. Существует гаджет боковой панели с содержимым HTML и небольшим трюком CSS, который можно показать совершенно другим.

<section class="sidebar nested">
    <h2>Nested Section</h2>
    <p>Lorem ipsum dolor sit amet, conse ctetur adipiscing elit. Maec enas id augue ac metu aliquam.</p>
    <p>Sed pharetra placerat est suscipit sagittis. Phasellus <a href="#">aliquam</a> males uada blandit. Donec adipiscing sem erat.</p>
</section>

Я хочу иметь частичный вид, который используется следующим образом:

@Html.Partial("Path/To/Partial/View"){
    <h2>Nested Section</h2>
    <p>Lorem ipsum dolor sit amet, conse ctetur adipiscing elit. Maec enas id augue ac metu aliquam.</p>
    <p>Sed pharetra placerat est suscipit sagittis. Phasellus <a href="#">aliquam</a> males uada blandit. Donec adipiscing sem erat.</p>
}

TBH, я хочу иметь такую ​​функциональность, как я в блоке @for(...){ }. Возможно ли это в Razor?

Ответ 1

У меня была та же самая дилемма. Попробуйте создать тип модели представления со свойством Func, а затем передайте HTML как делегат.

public class ContainerViewModel
{
    public String Caption { get; set; }
    public String Name { get; set; }
    public Int32 Width { get; set; }
    public Func<object, IHtmlString> Content { get; set; }
}

@Html.Partial("Container", new ContainerViewModel()
{
    Name = "test",
    Caption = "Test container",
    Content =  
    @<text>
       <h1>Hello World</h1>
    </text>,
    Width = 600
})

Вы можете назвать это так в своей части.

@Model.Content(null)

Если вы хотите быть модным, вы можете добавить этот метод расширения.

public static class PartialExtensions
{
    public static IHtmlString Display<T>
        (this T model, Expression<Func<T, Func<Object, IHtmlString>>> content) 
    {
        var compiled = content.Compile();
        return compiled.Invoke(model).Invoke(null);
    }
}

Затем, каждый раз, когда вы используете этот шаблон, вы можете назвать его таким образом в своей части (не полностью протестированной).

@model ContainerViewModel
@Model.Display(m => m.Content)  // Use delegate property

Надеюсь, что это работает для вас.

Это работает, потому что синтаксис @... создает небольшой HtmlHelper для вас, который использует модель (которую вы объявляете здесь как тип object, и для которой передается значение null) и возвращает IHtmlString.

ОСТОРОЖНО, значения формы не отправляются на сервер, если в контенте используется @Html.BeginForm.

Поэтому оберните свою форму вокруг контейнера.

Ответ 2

Кажется, вы хотите, чтобы какая-то функция htmlhelper генерировала этот контент. Вы изучали реализацию его как помощника вместо частичного представления?