我希望在我的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);
}
感谢您的帮助!
答案 0 :(得分: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方法中实例化一个新的AppContextImplemenation
public abstract class BaseApiController: ApiController
{
public IAppContext AppContext {get; set;}
protected override void OnActionExecuting(
ActionExecutingContext filterContext)
{
AppContext = new AppContextImplementation();
}
}
New Class - 实现IAppContext并包装HttpContext会话。为了进行测试,您可以创建一个TestAppContextImplementation,它不依赖于Session,而是依赖于其他一些内存存储机制。
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; }
}
}
答案 1 :(得分:-1)
对于ApiControllers
,请自己构建一个DelegatingHandler
并将所有好处推送到request.Properties
。无论您是在测试还是在线运行,您都可以从您的请求中检索它们。这样做的好处是,您可以在Controller中对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];