7

我有一个类似于以下的 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 。

4

5 回答 5

3

我最终做了一些 hacky 来让它按照我需要的方式工作。

在我的页面上,我有:

@{
    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

如果有更好的方法我想知道。

于 2011-02-08T13:31:24.350 回答
2

渲染器期望在布局文件中的某个时间调用该方法。您可以欺骗渲染器并使用“全局”条件(想想登录)。

@{
    ViewBag.content = RenderBody();
}
@if (Request.IsAuthenticated) {
        @ViewBag.content;
} 
else {
        @Html.Partial("_LoginPartial")
}
于 2012-10-02T02:32:26.487 回答
0

具有性能的私有静态只读字段信息的扩展方法:

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", "…"); }

是的,是的,是的....我知道....不好的反映!使用风险自负:)

于 2014-09-21T21:36:29.320 回答
0

我在我的视图基类中使用以下方法(来自这篇优秀的博客文章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>
于 2014-12-18T22:02:20.190 回答
-1

您可以将整个部分包装在 if 语句中IsSectionDefined

布局.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>
    }
}
于 2011-02-04T21:54:24.540 回答