2011-02-04 10 views
6

は、私は(それが動作しません)次のようPage.cshtmlは似てい:asp.net mvc Razor ViewEngineで@sectionをオプションにする方法はありますか?

@{ 
    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要素です。

答えて

3

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

あなたCSHTMLページどのように私がそれを必要とするように働かせる。私のページの

私が持っている:

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

もっと知りたい場合はこちらをご覧ください。

+0

残念ながら、これは現在おそらくあなたの最善の選択肢です。もう一つの可能​​なオプションは、 "@ section"が翻訳されたものであるDefineSectionを直接呼び出そうとすることです。問題は、Razor v2のラムダ内にMarkupを置くことができないということです(私たちが将来見ているもの)。@helperコンストラクトでコンテンツを定義し、そのヘルパーをDefineSectionラムダから呼び出さなければならない。結局のところ、それはあなたが持っているようにそれをするのが簡単になるかもしれません。しかし、今後のバージョンでこれを改善する予定です! –

-1

あなたはIsSectionDefined

Layout.cshtmlでif文であなたの全体のセクションをラップすることができます:私は少しハック何かをやってしまった

@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> 
    } 
} 
+0

を使用すると、レイアウトファイルにIsSectionDefinedを入れたいと必要とrendersectionを呼び出す – ajma

+0

私が現在持っているものだが、それだことセクションが何もない場合でも定義されているのでdivを出力します。 –

+0

周囲のdivがIsSectionDefinedでラップされている場合はどうなりますか? – ajma

2

レンダラは、レイアウトファイルでいつでもメソッドを呼び出すことを期待しています。あなたはレンダラーをスプーフィングし、 "グローバル"条件を使用することができます(ログインと思う)。あなたのCSHTMLで

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

:PERFのためのプライベート静的読み取り専用フィールド情報と

@{ 
    ViewBag.content = RenderBody(); 
} 
@if (Request.IsAuthenticated) { 
     @ViewBag.content; 
} 
else { 
     @Html.Partial("_LoginPartial") 
} 
0

拡張メソッド

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

はい、はい、はい....私が知っています...悪い反射!ご自身の責任で使用してください:)

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> 
関連する問題