【问题标题】:Use session state for an ApiController为 ApiController 使用会话状态
【发布时间】:2012-12-24 12:33:02
【问题描述】:

我想在我的 ApiController (MVC4) 中拥有自己的 AppContext。

应该是这样的

public class TestController : BaseApiController
{
    [HttpGet]
    public IEnumerable<TestVM> GetAll()
    {
        // the test service is injected with SimpleInjector
        return _testService.GetAll(**base.AppContext**);
    }
}

但 ApiController 无法访问 Session。 是否有任何解决方案可以“激活”特定键的会话(因为我不想要整个会话)? 或者您有什么其他想法(缓存或 cookie)?

这是 BaseApiController

public abstract class BaseApiController: ApiController
{
    public IAppContext AppContext
    {
        get { return SessionState.AppContext; }
    }
}

这是我的 IAppContext(以后会有更多的属性)

public interface IAppContext
{
    IIdentity User { get; }

    /// <summary> Gets the user id. </summary>
    /// <value>The user id.</value>
    int IdUser { get; }
}

这里是web.config中注册的应用模块

public class ApplicationModule : IHttpModule
{
    // ...
    SessionState.AppContext = _appContext.InitializeNew(
        HttpRuntime.AppDomainAppPath, languages);
    // ...
}

SessionState 类获取 AppContext

public class SessionState : BaseSessionVariables
{
    public static IAppContext AppContext
    {
        get { return SessionState.Get<IAppContext>("AppContext"); }
        set { SessionState.Set("AppContext", value); }
    }
}

这里是 BaseSessionVariables 类

public static HttpSessionState GetSession()
{
    return HttpContext.Current.Session;
}

protected static T Get<T>(string key) where T : class
{
    var session = BaseSessionVariables.GetSession();

    if (session == null)
    {
        throw new Exception("No session");
    }
    return (session[key] as T);
}

感谢您的帮助!

【问题讨论】:

    标签: asp.net-mvc-4 controller session-state


    【解决方案1】:

    看看下面的实现。它应该让你朝着正确的方向前进。

    更新的 IAppContext - 添加了设置器

    public interface IAppContext
    {
        IIdentity User { get; set; }
    
        /// <summary> Gets the user id. </summary>
        /// <value>The user id.</value>
        int IdUser { get; set; }
    }
    

    更新的基本控制器 - 在 OnActionExecuting 方法中实例化一个新的 AppContextImplementation

    public abstract class BaseApiController: ApiController
    {
        public IAppContext AppContext {get; set;}
    
        protected override void OnActionExecuting(
            ActionExecutingContext filterContext)
        {
            AppContext = new AppContextImplementation();
        }
    }
    

    New Class - 实现 IAppContext 并包装 HttpContext Session。为了进行测试,您可以创建一个不依赖 Session 而是依赖其他内存存储机制的 TestAppContextImplementation。

    public class AppContextImplementation : IAppContext
    {
        public IIdentity User
        { 
            get { return HttpContext.Current.Session["User"] as IIdentity; }
            set { HttpContext.Current.Session["User"] = value; }
        }
    
        int IdUser
        { 
            get { return Convert.ToInt32(Session["IdUser"]); }
            set { Session["IdUser"] = value; }
        }
    }
    

    【讨论】:

    • 感谢您的提示,但 ApiController 中没有可覆盖的 OnActionExecuting
    【解决方案2】:

    对于ApiControllers,为自己建立一个DelegatingHandler,并将你所有的好东西推送到request.Properties。然后,无论您是在测试还是实时运行,您都可以从您的请求中检索它们。这样做的好处是您对控制器中的 Session 的依赖为零。

    消息处理程序

    public class ContextHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            // get the goodies to add onto the request
            var goodies = /* call to goodieGoodieYumYum */
    
    
            // add our goodies onto the request
            request.Properties.Add(Constants.RequestKey_Goodies, goodies);
    
            // pass along to the next handler
            return base.SendAsync(request, cancellationToken);
        }
    }
    

    控制器动作

    var goodies = (List<Goodie>)Request.Properties[Constants.RequestKey_Goodies];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 2010-12-13
      • 2013-08-02
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多