如何将参数传递到ASP.NET MVC 2自定义ActionFilter? [英] How to pass parameters to a custom ActionFilter in ASP.NET MVC 2?

查看:397
本文介绍了如何将参数传递到ASP.NET MVC 2自定义ActionFilter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创造出一组将被传递给它从控制器运行参数的自定义ActionFilter。

到目前为止,我的客户ActionFilter看起来是这样的:

 公共类CheckLoggedIn:ActionFilterAttribute
{
    公共IGenesisRepository克{搞定;组; }
    公众的Guid memberGuid {搞定;组; }    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        会员thisMember = gr.GetActiveMember(memberGuid);
        会员bottomMember = gr.GetMemberOnBottom();        如果(thisMember.Role.Tier< = bottomMember.Role.Tier)
        {
            filterContext
                .HttpContext
                。响应
                .RedirectToRoute(新{控制器=会员,行动=登录});
        }        base.OnActionExecuting(filterContext);
    }
}

我知道我还需要检查空值,等等。但我不明白,为什么 memberGuid 未成功传递。我打电话这样此次筛选:

  [CheckLoggedIn(GR = genesisRepository,memberGuid = md.memberGUID)
    公众的ActionResult主页(MemberData MD)
    {
        返回查看(MD);
    }

genesisRepository MD 在控制器的构造函数中被设置。

我没能得到这个编译。我得到的错误是:

 错误1'克'是不是一个有效的命名特性参数,因为它不是一个有效的属性参数类型
错误2'memberGuid'不是一个有效的命名特性参数,因为它不是一个有效的属性参数类型

我仔细检查了该 memberGuid 是一样的类型, genesisRepority md.memberGUID ,是什么原因造成这些错误?

解决方案

感谢jfar为提供解决方案。

下面是我最终使用的过滤器:

 公共类CheckLoggedIn:ActionFilterAttribute
{    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        变种thisController =((MemberController)filterContext.Controller);        IGenesisRepository克= thisController.GenesisRepository;
        GUID memberGuid =((MemberData)filterContext.HttpContext.Session [thisController.MemberKey])MemberGUID。        会员thisMember = gr.GetActiveMember(memberGuid);
        会员bottomMember = gr.GetMemberOnBottom();        如果(thisMember.Role.Tier> = bottomMember.Role.Tier)
        {
            filterContext.Result =新RedirectToRouteResult(
                新RouteValueDictionary(
                    新{
                        控制器=会员,
                        行动=登陆
                    }));
        }        base.OnActionExecuting(filterContext);
    }
}


解决方案

这是一种方法,使这项工作。您可以从ActionFilter对象访问ControllerContext,因此控制器。所有你需要做的是投你的控制器的类型,你可以访问任何公共成员。

鉴于此控制器:

 公共GenesisController:控制器
{
    [CheckLoggedIn()]
    公众的ActionResult主页(MemberData MD)
    {
        返回查看(MD);
    }
}

ActionFilter看起来像

 公共类CheckLoggedIn:ActionFilterAttribute
{
    公共IGenesisRepository克{搞定;组; }
    公众的Guid memberGuid {搞定;组; }    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        / *如何让控制器* /
        变种controllerUsingThisAttribute =((GenesisController)filterContext.Controller);        / *现在你可以从控制器使用的公共属性* /
        GR = controllerUsingThisAttribute .genesisRepository;
        memberGuid =(controllerUsingThisAttribute .memberGuid;        会员thisMember = gr.GetActiveMember(memberGuid);
        会员bottomMember = gr.GetMemberOnBottom();        如果(thisMember.Role.Tier< = bottomMember.Role.Tier)
        {
            filterContext
                .HttpContext
                。响应
                .RedirectToRoute(新{控制器=会员,行动=登录});
        }        base.OnActionExecuting(filterContext);
    }
}

当然,这是假设的ActionFilter不是跨多个控制器使用,你没事的耦合。另一个选项是使ICheckedLoggedInController接口与共享的属性和简单地投射到该代替

I'm trying to create a custom ActionFilter which operates on a set of parameters that would be passed to it from the controller.

So far, my customer ActionFilter looks like this:

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);
    }
}

I know I still need to check for nulls, etc. but I can't figure out why gr and memberGuid aren't successfully being passed. I'm calling this Filter like this:

    [CheckLoggedIn(gr = genesisRepository, memberGuid = md.memberGUID)]
    public ActionResult Home(MemberData md)
    {
        return View(md);
    }

genesisRepository and md are being set in the controller's constructor.

I'm not able to get this to compile. The error I get is:

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

I double checked that gr and memberGuid were the same types as genesisRepority and md.memberGUID, What is causing these errors?

Solution

Thanks to jfar for offering a solution.

Here's the Filter I ended up using:

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);
    }
}

解决方案

This is a way to make this work. You have access to the ControllerContext and therefore Controller from the ActionFilter object. All you need to do is cast your controller to the type and you can access any public members.

Given this controller:

public GenesisController : Controller
{
    [CheckLoggedIn()]
    public ActionResult Home(MemberData md)
    {
        return View(md);
    }
}

ActionFilter looks something like

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);
    }
}

Of course this is assuming the ActionFilter isn't used across multiple controllers and you're ok with the coupling. Another Option is to make a ICheckedLoggedInController interface with the shared properties and simply cast to that instead.

这篇关于如何将参数传递到ASP.NET MVC 2自定义ActionFilter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆