如何访问我正在拦截的对象?

时间:2011-01-18 16:59:36

标签: c# asp.net castle-windsor

我正在使用Castle Core创建自定义属性和拦截器,以使用属性将安全检查注入我们的代码中。 例如[安全(“角色1”)]

在拦截器的实现中:

public class SecurityInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        object o;

        MethodInfo mi = invocation.Method;
        SecurityAttribute[] atts = (SecurityAttribute[])mi.GetCustomAttributes(typeof(SecurityAttribute), true);

        // if method not marked with Security attribute, then pass on call
        if (atts.Length == 0)
        {
            invocation.Proceed();
        }
        else
        {
            //for now assume that there is only one security attribute on the method
            //do some security test 
            {
                invocation.Proceed();
            }
        }

    }

在上面的“做一些安全性测试”部分中,我需要访问HttpContext.Session对象,以便检索一些保存的对象来进行安全性测试。

假设此属性所在的方法是一个代码隐藏的asp.net页面,即Page类的一个实例) 我不能只在这个属性中使用this.Context [Security(“Role1”,this.Context)] 因为属性不允许这样做。

那么如何在Intercept方法中访问httpContext?

或者有更好的方式以类似的方式这样做吗?

2 个答案:

答案 0 :(得分:4)

InvocationTarget实例的IInvocation属性具有目标对象。因此,在您的情况下,如果您确定拦截发生在Page对象上,您应该能够这样做:

var page = (Page)invocation.InvocationTarget;

如果情况并非总是如此,您应该以另一种方式访问​​HTTP上下文。

正如Ben指出的那样,HttpContext.Current允许您从任何地方访问当前HttpContext,但访问该静态属性只是icky。然而,有一种更好的方法,那就是注册一个允许注入会话状态的工厂方法:

container.Register(
    Component.For<ISessionState>()
        .UsingFactoryMethod(k => new SessionWrapper(HttpContext.Current.Session)
        .Lifestyle.PerWebRequest));

假设您已经创建了ISessionState接口和一个适当的包装器,该包装器具有您希望在与ASP.NET HttpSessionState对象交互时使用的API。

现在,由于拦截器像容器一样从容器中拉出,它可能依赖于ISessionState

public class SecurityInterceptor : IInterceptor
{
    public SecurityInterceptor(ISessionState sessionState)
    {
        //...
    }
}

使你的拦截器变得美观和可测试。

可能有很多其他方法可以做到这一点,也可能有更好的方法。这只是关于如何继续项目的想法:)

答案 1 :(得分:1)

只要从ASP.net进程调用代码,您就可以在任何地方使用HttpContext.Current.Session