qua*_*els 32 c# asp.net asp.net-mvc action-filter
我正在尝试创建一个自定义ActionFilter,它操作一组参数,这些参数将从控制器传递给它.
到目前为止,我的客户ActionFilter看起来像这样:
public class CheckLoggedIn : ActionFilterAttribute
{
public IGenesisRepository gr { get; set; }
public Guid memberGuid { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Member thisMember = gr.GetActiveMember(memberGuid);
Member bottomMember = gr.GetMemberOnBottom();
if (thisMember.Role.Tier <= bottomMember.Role.Tier)
{
filterContext
.HttpContext
.Response
.RedirectToRoute(new { controller = "Member", action = "Login" });
}
base.OnActionExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我仍然需要检查空值等,但我无法弄清楚为什么gr并且memberGuid没有成功通过.我这样称为过滤器:
[CheckLoggedIn(gr = genesisRepository, memberGuid = md.memberGUID)]
public ActionResult Home(MemberData md)
{
return View(md);
}
Run Code Online (Sandbox Code Playgroud)
genesisRepository并且md正在控制器的构造函数中设置.
我无法将其编译.我得到的错误是:
Error 1 'gr' is not a valid named attribute argument because it is not a valid attribute parameter type
Error 2 'memberGuid' is not a valid named attribute argument because it is not a valid attribute parameter type
Run Code Online (Sandbox Code Playgroud)
我仔细检查了那个gr和memberGuid是同一类型,genesisRepority并且md.memberGUID,是什么原因造成这些错误?
感谢jfar提供解决方案.
这是我最终使用的过滤器:
public class CheckLoggedIn : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var thisController = ((MemberController)filterContext.Controller);
IGenesisRepository gr = thisController.GenesisRepository;
Guid memberGuid = ((MemberData)filterContext.HttpContext.Session[thisController.MemberKey]).MemberGUID;
Member thisMember = gr.GetActiveMember(memberGuid);
Member bottomMember = gr.GetMemberOnBottom();
if (thisMember.Role.Tier >= bottomMember.Role.Tier)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new {
controller = "Member",
action = "Login"
}));
}
base.OnActionExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ell 34
这是一种使这项工作的方法.您可以从ActionFilter对象访问ControllerContext,从而访问Controller.您需要做的就是将控制器转换为类型,您可以访问任何公共成员.
鉴于此控制器:
public GenesisController : Controller
{
[CheckLoggedIn()]
public ActionResult Home(MemberData md)
{
return View(md);
}
}
Run Code Online (Sandbox Code Playgroud)
ActionFilter看起来像
public class CheckLoggedIn : ActionFilterAttribute
{
public IGenesisRepository gr { get; set; }
public Guid memberGuid { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
/* how to get the controller*/
var controllerUsingThisAttribute = ((GenesisController)filterContext.Controller);
/* now you can use the public properties from the controller */
gr = controllerUsingThisAttribute .genesisRepository;
memberGuid = (controllerUsingThisAttribute .memberGuid;
Member thisMember = gr.GetActiveMember(memberGuid);
Member bottomMember = gr.GetMemberOnBottom();
if (thisMember.Role.Tier <= bottomMember.Role.Tier)
{
filterContext
.HttpContext
.Response
.RedirectToRoute(new { controller = "Member", action = "Login" });
}
base.OnActionExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)
当然这是假设ActionFilter没有在多个控制器上使用,你可以使用耦合.另一个选项是使用共享属性创建ICheckedLoggedInController接口,然后简单地转换为该接口.