Есть ли способ сделать @section необязательным с помощью asp.net mvc Razor ViewEngine? - PullRequest
7 голосов
/ 05 февраля 2011

У меня есть Page.cshtml, похожий на следующий (который не работает):

@{
    Layout = "../Shared/Layouts/_Layout.cshtml";
    var mycollection = (ViewBag.TheCollection as IQueryable<MyCollectionType>);
}

<h2>@ViewBag.Title</h2>

content here

@if (mycollection != null && mycollection.Count() > 0)
{    
    @section ContentRight
    {    
        <h2>
            Stuff
        </h2>
        <ul class="stuff">
            @foreach (MyCollectionType item in mycollection )
            {
                <li class="stuff-item">@item.Name</li>
            }
        </ul>
    }
}

Как я уже сказал, это не работает.Я хочу не определять раздел, если в коллекции ничего нет.Есть ли способ получить что-то подобное этой работе?Если нет, каковы мои другие варианты?Я очень новичок в этом Razor ViewEngine.

Изменить

В моем макете у меня есть:

@if(IsSectionDefined("ContentRight")) 
{
    <div class="right">
        RenderSection("ContentRight")
    </div>
}

что я не хочуэто div для вывода, когда секция пуста.

Ответы [ 5 ]

3 голосов
/ 08 февраля 2011

Я закончил тем, что сделал что-то хакерское, чтобы все заработало так, как мне нужно.

на моей странице у меня есть:

@{
    Layout = "../Shared/Layouts/_Layout.cshtml";
    var mycollection = (ViewBag.TheCollection as IQueryable<MyCollectionType>);
    ViewBag.ShowContentRight = mycollection != null && mycollection.Count() > 0;
}

тогда в моем макете у меня есть:

@if(IsSectionDefined("ContentRight") && (ViewBag.ShowContentRight == null ||ViewBag.ShowContentRight == true)) 
{
    <div class="right">
        RenderSection("ContentRight")
    </div>
}
else if(IsSectionDefined("ContentRight"))
{
    RenderSection("ContentRight")
}

Если раздел определен, его нужно отобразить, но если нет содержимого, я не хочу <div> s

Если есть способ получше, я бы хотел знать.

2 голосов
/ 02 октября 2012

Рендерер ожидает, что метод будет вызван когда-нибудь в файле макета.Вы можете подделать рендерер и использовать «глобальные» условные выражения (например, логин).

0 голосов
/ 19 декабря 2014

Я использую следующий метод в своем базовом классе просмотра (из этого отличного сообщения в блоге http://haacked.com/archive/2011/03/05/defining-default-content-for-a-razor-layout-section.aspx/):

public HelperResult RenderSection(string name, Func<dynamic, HelperResult> defaultContents)
{
    if (IsSectionDefined(name))
    {
        return RenderSection(name);
    }
    return defaultContents(null);
}

Если у вас нет базового класса представления, я рекомендую его, потому что он позволяет добавлять в ваши представления все виды небольших дополнительных функций. Просто создайте класс со следующей подписью: public abstract class MyViewPage<T> : WebViewPage<T>, а затем установите его в web.config:

<system.web.webPages.razor>
  <pages pageBaseType="MyViewPage">
    ...
  </pages>
</system.web.webPages.razor>
0 голосов
/ 22 сентября 2014

Метод расширения с частной статической информацией только для чтения для perf:

private static readonly FieldInfo RenderedSectionsFieldInfo = typeof(WebPageBase).GetField("_renderedSections", BindingFlags.Instance | BindingFlags.NonPublic);

public static void EnsureSectionsAreRegisteredAsRendered(this WebPageBase webPageBase, params string[] sectionNames)
{
    var renderedSections = RenderedSectionsFieldInfo.GetValue(webPageBase) as HashSet<string>;
    if (renderedSections == null)
    {
        throw new WebCoreException("Could not get hashset from private field _renderedSections from WebPageBase");    
    }
    foreach (var sectionName in sectionNames)
    {
        if (!renderedSections.Contains(sectionName))
        {
            renderedSections.Add(sectionName);
        }
    }
}

В вашем cshtml:

@{ this.EnsureSectionsAreRegisteredAsRendered("SectionName1", " SectionName2", "…"); }

Да, да, да .... Я знаю ...плохое отражение!Используйте на свой страх и риск:)

0 голосов
/ 05 февраля 2011

Вы можете заключить весь раздел в оператор if с помощью IsSectionDefined

Layout.cshtml:

@if (IsSectionDefined("ContentRight"))
{
    <div>
    @RenderSection(name: "ContentRight", required: false)
    </div>
}

Ваша cshtml-страница:

@section ContentRight
{    
    @if (mycollection != null && mycollection.Count() > 0)
    {   
    <h2>
        Stuff
    </h2>
    <ul class="stuff">
        @foreach (MyCollectionType item in mycollection )
        {
            <li class="stuff-item">@item.Name</li>
        }
    </ul>
    }
}
...