我有一个类似于以下的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。
答案 0 :(得分: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
如果有更好的方式我想知道。
答案 1 :(得分:2)
渲染器期望在布局文件中某个时候调用该方法。您可以欺骗渲染器并使用“全局”条件(想想登录)。
@{
ViewBag.content = RenderBody();
}
@if (Request.IsAuthenticated) {
@ViewBag.content;
}
else {
@Html.Partial("_LoginPartial")
}
答案 2 :(得分:0)
具有针对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", "…"); }
是的,是的,是的......我知道......糟糕的反思!使用风险自负:)
答案 3 :(得分: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>
答案 4 :(得分:-1)
您可以使用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>
}
}