3

我想在我的 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);
}

谢谢你的帮助!

4

2 回答 2

0

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

更新了 IAppContext - 添加了 Setter

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

新类 - 实现 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; }
    }
}
于 2013-01-10T14:20:09.740 回答
-1

因为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];
于 2014-03-21T17:03:26.130 回答