2017-08-05 22 views
0

私はMVCにnewbyしています。それぞれのビューに異なるボディクラスを使用したいと思います。 私のヘッダーは部分的なビューで、@RenderSectionは機能しません。部分ビューヘッダーのページごとに異なるボディクラスを指定する

_Layout.cshtml:

@{ 
     Html.RenderAction("GetHeader", "Main"); 
    } 

    @RenderBody() 

    @{ 
     Html.RenderAction("GetFooter", "Main"); 
    } 

_HeaderLayout.cshtml:

//... 
    <body class=" here must be specified class different for each view"> 
    //... 

メインコントローラ:

public class MainController : Controller 
    { 
     public ActionResult GetHeader() 
     { 
      return PartialView("~/Views/Shared/_HeaderLayout.cshtml"); 
     } 

     public ActionResult GetFooter() 
     { 
      return PartialView("~/Views/Shared/_FooterLayout.cshtml"); 
     } 
    } 

任意のアイデアしてください?

答えて

1

私は2つの方法でそれを行うだろう:

  1. アプリで使用されているすべてのビューモデルの基本のViewModelクラスを作成し、BodyClassのプロパティを追加し、その後、部分的なビューでそれを実装します。
  2. 部分図を返す前にViewBag辞書にプロパティを追加します。

例: 1.基本クラス

public class BaseViewModel 
{ 
    public string BodyClass {get; set;} 
} 

使用:

基本クラス:部分図で

:CONTに

@model BaseViewModel 
///... 
<body class="@Model.BodyClass"> 

ローラー:ViewBag

public ActionResult GetHeader() 
{ 
    var vm = new BaseViewModel { BodyClass= "test-class" }; 
    return PartialView("~/Views/Shared/_HeaderLayout.cshtml", vm); 
} 

部分図で

public ActionResult GetHeader() 
{ 
    ViewBag[SomeConstantStringValue] = "test-class"; 
    return PartialView("~/Views/Shared/_HeaderLayout.cshtml"); 
} 

<body class="@ViewBag[SomeConstantStringValue]"> 

そうしないと、エラーが発生します、あなたは常にそのViewBag値を指定する必要があることを忘れないでください。

+0

ありがとう@mihailしかしHeaderLayoutはビューの前にロードされ、BodyClassはMainControllerのGetHeaderに設定することはできません。各ビューの各コントローラに別々に設定する必要があります。ではない? –

0

おそらくMihail Stancescuの回答が最適ですが、各コントローラメソッドのビューモデルが必要ない場合は、代わりにヘルパー関数を使用できます。いずれにしても、あなたはおそらく返すクラスを決める独自のメソッドを作る必要があります(下記のBodyClassForTabAndMethod()を参照)。

(すでに適切なものを持っていない場合)ヘルパークラスを作成します。あなたのビューで

public static class Helper 
{ 
    public static string BodyClassForTabAndMethod() 
    { 
     string[] selectedTabAndMethod = GetSelectedTabAndMethod(); 

     string bodyClass = ""; 

     // Change the below switch statements based upon the controller/method name. 
     switch (selectedTabAndMethod[0]) 
     { 
      case "home": 
       switch (selectedTabAndMethod[1]) 
       { 
        case "index": 
         return "IndexClass"; 
        case "about": 
         return "AboutClass"; 
        case "contact": 
         return "ContactClass"; 
       } 
       break; 
      case "account": 
       switch (selectedTabAndMethod[1]) 
       { 
        case "login": 
         return "LoginClass"; 
        case "verifycode": 
         return "VerifyCodeClass"; 
       } 
       break; 
     } 

     return bodyClass; 
    } 

    public static string[] GetSelectedTabAndMethod() 
    { 
     string[] selectedTabAndMethod = new string[2]; // Create array and set default values. 
     selectedTabAndMethod[0] = "home"; 
     selectedTabAndMethod[1] = "index"; 

     if (HttpContext.Current.Request.Url.LocalPath.Length > 1) 
     { 
      // Get the selected tab and method (without the query string). 
      string tabAndMethod = HttpContext.Current.Request.Url.LocalPath.ToLower(); 

      // Remove the leading/trailing "/" if found. 
      tabAndMethod = ((tabAndMethod.Substring(0, 1) == "/") ? tabAndMethod.Substring(1) : tabAndMethod); 
      tabAndMethod = ((Right(tabAndMethod, 1) == "/") ? tabAndMethod.Substring(0, tabAndMethod.Length - 1) : tabAndMethod); 

      // Convert into an array. 
      if (tabAndMethod.Count(s => s == '/') == 1) 
      { 
       string[] split = tabAndMethod.Split('/'); 
       selectedTabAndMethod[0] = split[0]; 
       selectedTabAndMethod[1] = split[1]; 
      } 
     } 

     return selectedTabAndMethod; 
    } 

    public static string Right(string value, int length) 
    { 
     if (string.IsNullOrEmpty(value)) return string.Empty; 

     return ((value.Length <= length) ? value : value.Substring(value.Length - length)); 
    } 
} 

そしてを: <body class="@Helper.BodyClassForTabAndMethod()">

0

を私は、自分の質問のためのソリューションに達しました非常に簡単に:

グローバルで。asax://または開始任意のコントローラーとビュー/部分的なビューを返す前

public static class WrrcGlobalVariables 
    { 
     //any other global variables... 

     public static string BodyClass { get; set; } 
    } 

にロードする他のクラス:

public ActionResult Index() 
    { 
     //some codes... 

     WrrcGlobalVariables.BodyClass = "HomePage"; 

     return View(); 
    } 

と_HeaderLayout.cshtmlで:

<body class="@WrrcGlobalVariables.BodyClass"> 
0

Mihail Stancescuのアプローチはどちらも正しいですが、必要な場合にのみデフォルト値とカスタム値を持つもう1つの方法があります。また、RenderActionの代わりにRenderPartialを使用するのは、子コントローラを必要とする余分なロジックを持たずに部分をレンダリングする場合だけです。 _Layout.cshtmlで

@Html.Partial("_HeaderLayout") 
@RenderBody() 
@Html.Partial("_FooterLayout") 

_HeaderLayout.cshtmlで

<body class="@ViewBag[SomeConstantStringValue]"> 

そしてどこでもこのViewBag値を設定する任意のビューまたはコントローラに

@{ 
    ViewBag[SomeConstantStringValue] = ViewBag[SomeConstantStringValue] ?? "default-class"; 
} 

_ViewStart.cshtml

において、これはnull参照例外を防ぐために保証されたデフォルト値を保証する方法

関連する問題