I had the same problem, but I decided to go for ServiceLocator (DependencyResolver.GetService) for this, since it is within the framework, as it seems to me, a valid approach
public class RequiresSessionAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { var sessionService = (ISessionService) actionContext .ControllerContext.Configuration.DependencyResolver .GetService(typeof (ISessionService)); var sessionId = HttpUtility .ParseQueryString(actionContext.Request.RequestUri.Query) .Get("sessionId"); if (sessionId == null || !sessionService.IsValid(sessionId)) throw new SessionException(); base.OnActionExecuting(actionContext); } }
and here is a test for this attribute, a bit of pain, but possible
public class requires_sessionId { [Fact] void can_call_action_with_session_id() { var context = GetContext("http://example.com/?sessionId=blaa"); var sut = new RequiresSessionAttribute(); Assert.DoesNotThrow( () => sut.OnActionExecuting(context)); } [Fact] void can_not_call_action_without_session_id() { var context = GetContext("http://example.com/"); var sut = new RequiresSessionAttribute(); Assert.Throws<SessionException>( () => sut.OnActionExecuting(context)); } HttpActionContext GetContext(string url) { var sessionServiceMock = new Mock<ISessionService>(); sessionServiceMock .Setup(x => x.IsValid(It.IsAny<string>())) .Returns(true); var dependancyResolverMock = new Mock<IDependencyResolver>(); dependancyResolverMock .Setup(x => x.GetService(It.IsAny<Type>())) .Returns(sessionServiceMock.Object); var config = new HttpConfiguration { DependencyResolver = dependancyResolverMock.Object }; var controllerContext = new HttpControllerContext { Configuration = config, Request = new HttpRequestMessage( HttpMethod.Get, url) }; return new HttpActionContext { ControllerContext = controllerContext, }; } }
Anthony johnston
source share