2017-08-29 74 views
0

我知道這可能是一個古老的問題,但與我在一起,因爲這與網絡中解釋的其他人不同。我在bootstrap中有一些選項卡,根據被擊中的動作,它必須被設置爲主動。我也有一些子選項卡,根據被擊中的動作,它也必須設置爲主動。在ASP.NET MVC中設置一個啓動選項卡活動

這裏是它的外觀像一個形象:

因此,當一個子標籤正在積極父標籤必須是活躍。

enter image description here

所以我想,我節省了PAGEID每個動作,並根據視圖上的PAGEID我可以將其設置爲創建一個新的屬性活躍與否:

這裏是屬性:

public class YcoPageId : Attribute 
{ 
    public YcoPageId(int pageId) 
    { 
     PageId = pageId; 
    } 
    public int PageId { get; } 
} 

這裏是動作:

[YcoPageId(1)] 
public ActionResult Admin() 
{ 
    return View(); 
} 

對於視圖,我想創建一個擴展方法來查看選項卡和子選項卡是否處於活動狀態!

這裏是我的代碼:

public static bool IsActive(this HtmlHelper htmlHelper, params int[] ids) 
{ 
    var viewContext = htmlHelper.ViewContext; 
    var action = viewContext.... 
    //How to get the YcoPageId attribute from here and see the Id 
    //Here i will test if ids contain id but dont know how to get it... 
} 

,如果你認爲添加的每一頁的ID是壞主意,我覺得對於我來說,我會用這個ID爲其他目的,因爲它會像標識符一個具體的行動...

所以我的問題是我怎麼能得到屬性YcoPageId當前行動在我的擴展方法?

的觀點看起來就像這樣:

<li class="@(Html.IsActive(1, 4, 5... etc)? "active" : "")"> 
    <a href="@url"> 
     <div class="row text-center"> 
      <div class="col-md-12"> 
       <i class="fa @fontAwesomeIcon fa-4x" aria-hidden="true"></i> 
       <br/>@menuName 
      </div> 
     </div> 
    </a> 
</li> 

如果有什麼更好的想法如何解決這個問題,請繼續!

在此先感謝!

+0

這些標籤的關係是什麼?頂部選項卡是否與控制器相關,並且子選項卡與所選控制器中的操作方法相關? –

+0

不,他們沒有任何關係,因爲我正在將一些ASP.NET Webforms代碼遷移到ASP.MVC中,所以我可以創建任何類型的關係,對我來說它的工作很重要:) –

+0

@StephenMuecke但是現在我正在思考爲父控制器設置一個控制器是有意義的,但這會讓我測試操作名稱的子選項卡,同時僅爲控制器名稱選擇父控制器,這就是你想要解釋的東西嗎? –

回答

0

這是我解決這個問題:

首先創建一個actionfilter屬性象下面這樣:

public class YcoPageIdAttribute : ActionFilterAttribute 
{ 
    public YcoPageIdAttribute(int pageId) 
    { 
     PageId = pageId; 
    } 
    public int PageId { get; } 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.Result is ViewResult) 
     { 
      filterContext.Controller.TempData[DomainKeys.ViewPageId] = PageId; 
     } 
     else 
     { 
      throw new Exception("Only ViewResult has unique id"); 
     } 
     base.OnActionExecuted(filterContext); 
    } 
} 

然後,我的行動看起來像這樣的:

[YcoPageId(1)] 
public ActionResult Admin() 
{ 
    return View(); 
} 

我創建了一個擴展方法如下:

public static bool IsActive(this HtmlHelper htmlHelper, params int[] ids) 
{ 
    var viewContext = htmlHelper.ViewContext; 
    return viewContext.TempData.ContainsKey(DomainKeys.ViewPageId) && 
     int.Parse(viewContext.TempData.Peek(DomainKeys.ViewPageId).ToString()).In(ids); 
} 

因爲我現在知道行動的ID我只有把代碼如下視圖:

<li class="@(Html.IsActive(1)? "active" : "")"> 
    <a href="@url"> 
     <div class="row text-center"> 
      <div class="col-md-12"> 
       <i class="fa @fontAwesomeIcon" aria-hidden="true"></i> 
       <br /><small>@menuName</small> 
      </div> 
     </div> 
    </a> 
</li> 

我做了啓動另一種方法來檢查,如果我有像下面重複值操作:

public static void CheckForDuplicateActionId() 
{ 
    Assembly asm = Assembly.GetExecutingAssembly(); 
    var controllerActionlist = asm.GetTypes() 
     .Where(type => typeof(Controller).IsAssignableFrom(type)) 
     .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | 
              BindingFlags.Public)) 
     .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), 
      true).Any()) 
     .Where(m => m.GetCustomAttribute<YcoPageIdAttribute>() != null) 
     .Select(
      x => 
       new 
       { 
        Controller = x.DeclaringType.Name, 
        Area = x.DeclaringType.FullName, 
        Action = x.Name, 
        ReturnType = x.ReturnType.Name, 
        Id = x.GetCustomAttribute<YcoPageIdAttribute>().PageId 
       }) 
     .ToList(); 
    var actionIds = controllerActionlist.Select(x => x.Id).ToList(); 
    var actionIdsGrouped = actionIds.GroupBy(x => x).Where(x => x.Count() > 1).ToList(); 
    if (!actionIdsGrouped.IsNullOrEmpty()) 
    { 
     StringBuilder error = new StringBuilder(""); 
     actionIdsGrouped.ForEach(actionId => 
     { 
      var actions = controllerActionlist.Where(x => x.Id == actionId.Key); 
      actions.ForEach(a => 
      { 
       error.Append(
        $" | Id : {a.Id}, Action Name: {a.Action}, Controller Name : {a.Controller}, Location : {a.Area}. "); 
      }); 
     }); 
     var maxId = controllerActionlist.Max(x => x.Id); 
     error.Append(
      "PLease consider changing the the duplicated id - Here are some options to choose from : Id {"); 
     for (int i = 1, j = 1; i < maxId + 5; i++) 
     { 
      if (actionIds.Contains(i)) continue; 
      if (j < 5) 
      { 
       error.Append(i + ","); 
       j++; 
      } 
      else 
      { 
       error.Append(i + "}"); 
       break; 
      } 
     } 
     throw new Exception(
      $"There are more than one action duplicated with the same Id, The action data are as below : {error}"); 
    } 
} 

也許我會在數據庫中添加所有這些數據,以便我可以從一個ID從數據庫中找出一個動作以及:)

現在工作好。

0

如果我理解正確,您正試圖爲每個頁面/視圖創建一個id,並在頁面/視圖中使用它來動態設置css類以將菜單選項卡設置爲活動狀態。如果是這種情況...而不是嘗試在控制器中設置ID,那麼如何創建一個只有下面的代碼的共享視圖 - 像這樣...

在視圖中寫下面的剃刀/ C#代碼。

@{ 
 
     var iPageId = 0 
 
     var sViewPath = ((System.Web.Mvc.BuildManagerCompiledView)ViewContext.View).ViewPath; 
 
     
 
     //for example 
 
     if (sViewPath.ToLower.IndexOf("admin") >= 0) 
 
     { 
 
      iPageId = 1; 
 
     } 
 
     else if (sViewPath.ToLower.IndexOf("dashboard") >= 0) 
 
     { 
 
      iPageId = 2; 
 
     } 
 
     else if (sViewPath.ToLower.IndexOf("vessels") >= 0) 
 
     { 
 
      iPageId = 3; 
 
     } 
 
     else if (sViewPath.ToLower.IndexOf("reports") >= 0) 
 
     { 
 
      iPageId = 4; 
 
     } 
 
    }

渲染結合下面的代碼段中的主視圖中的共享視圖。

@Html.Partial("~/Views/Menu/_SharedViewName.cshtml")

那麼你應該能夠變量的任何地方訪問iPageId在主頁/期(縣),並設置相應的CSS類。

相關問題