I have a custom mediator that checks to see if the user has access to the document that he requested; I want to know how can I check the route that this custom binder uses?
I am trying to run this test but getting this error:
MvcContrib.TestHelper.AssertionException: The value for the contract parameter does not match: expected 'Domain.Models.Contract', but was ''; in the context of the route there is no value for the action parameter called "contract" - does your corresponding route contain a token called "contract"?
[SetUp] public void Setup() { MvcApplication.RegisterModelBinders(); MvcApplication.RegisterRoutes(RouteTable.Routes); } [Test] public void VersionEdit() { var contract = TestHelper.CreateContract(); var route = "~/Contract/" + contract.Id.ToString() + "/Version/Edit/" + contract.Versions.Count; route.ShouldMapTo<VersionController>(c => c.Edit(contract)); }
If I try to debug, a custom binder will never be called.
Defining my route:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "VersionToken", // Route name "Contract/{contractId}/Version/{version}/{action}/{token}", // URL with parameters new { controller = "Version", action = "ViewContract", version = 1, token = UrlParameter.Optional } // Parameter defaults ); routes.MapRoute( "Version", // Route name "Contract/{contractId}/Version/{version}/{action}", // URL with parameters new { controller = "Version", action = "Create", version = UrlParameter.Optional } // Parameter defaults ); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); if (HttpContext.Current != null && !HttpContext.Current.IsDebuggingEnabled) routes.IgnoreRoute("CI"); }
My Model binder:
public static void RegisterModelBinders() { var session = (ISession)DependencyResolver.Current.GetService(typeof(ISession)); var authService = (IAuthenticationService)DependencyResolver.Current.GetService(typeof(IAuthenticationService)); System.Web.Mvc.ModelBinders.Binders[typeof (Contract)] = new ContractModelBinder(session, authService); } public class ContractModelBinder : DefaultModelBinder { private readonly ISession _session; private readonly IAuthenticationService _authService; public ContractModelBinder(ISession session, IAuthenticationService authService) { _session = session; _authService = authService; } public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var contractId = GetValue(bindingContext, "contractId"); var version = GetA<int>(bindingContext,"version"); var token = GetValue(bindingContext, "token"); var contract = _session.Single<Contract>(contractId); if (contract == null) { throw new HttpException(404, "Not found"); } if (contract.Versions.Count < version.Value) { throw new HttpException(404, "Not found"); } contract.RequestedVersionNumber = version.Value; if(token == null) { var user = _authService.LoggedUser(); if (user == null) throw new HttpException(401, "Unauthorized"); if (contract.CreatedBy == null || !contract.CreatedBy.Id.HasValue || contract.CreatedBy.Id.Value != user.Id) { throw new HttpException(403, "Forbidden"); } } else { contract.RequestedToken = token; var userToken = contract.RequestedVersion.Tokens.SingleOrDefault(x => x.Token == token); if (userToken == null) { throw new HttpException(401, "Unauthorized"); } } return contract; } private static T? GetA<T>(ModelBindingContext bindingContext, string key) where T : struct, IComparable { if (String.IsNullOrEmpty(key)) return null;