我在bootstrap中有一些标签,必须根据被击中的动作设置为活动状态。我也有子标签,必须根据被击中的动作设置为活动状态。
以下是它的外观图像:
因此,当子选项卡处于活动状态时,父选项卡也必须处于活动状态。
所以我想创建一个新的Attribute,我为每个动作保存一个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 :(得分:1)
以下是我对此问题的解决方案:
首先创建了一个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中识别出一个动作:)
现在它运作良好。
答案 1 :(得分:0)
如果我理解正确,您正在尝试为每个页面/视图创建一个id,并在页面/视图中使用它来动态设置css类,以便将菜单选项卡设置为活动状态。如果是这样的话......不是试图在Controller中设置ID,而是仅使用以下代码创建一个共享视图 - 如下所示....
在View中编写以下Razor / 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类。