2017-08-29 95 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类。

相关问题