public void Apply(ApplicationModel application) { foreach (ControllerModel controller in application.Controllers) { if (IsDasherizedJsonApiController(controller) == false) { continue; } string route; RouteAttribute routeAttr = controller.ControllerType.GetCustomAttribute <RouteAttribute>(true); if (routeAttr != null) { route = routeAttr.Template; } else { route = controller.ControllerName.Dasherize(); } controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel { Template = $"{_namespace}/{route}" }; } }
public void Test3() { RouteAttribute r = new RouteAttribute("/post/:postId/comment/:commentId", true); var result = r.MatchPath("/Post/10/Comment/2"); Assert.IsFalse(result.Match); }
private IEnumerable <OperationInfo> BuildMethodDescriptor(MethodInfo method, RouteAttribute prefix) { bool explicitRoute; var verbs = new List <OnVerbAttribute>(); var route = method.GetDefaults(verbs, out explicitRoute); Type entityType = null; Type implementation; if ((!explicitRoute) && ((implementation = typeof(T).GetInterfaces().FirstOrDefault(@interface => (@interface.IsGenericType) && (typeof(IReadController <,>).IsAssignableFrom(@interface.GetGenericTypeDefinition())))) != null)) { entityType = implementation.GetGenericArguments()[0]; } UriTemplateBuilder templateRegex = new UriTemplateBuilder(entityType, true); templateRegex.Add(prefix.Url.ToString(), prefix, typeof(T)); templateRegex.Add(route.Url.ToString(), route, method); Url url = UrlParser.Parse(templateRegex.ToString()); IList <OperationInfo> result = new List <OperationInfo>(); foreach (var item in verbs) { UriTemplateBuilder uriTemplate = templateRegex.Clone(false); var parameters = BuildParameterDescriptors(method, item.Verb, templateRegex, ref uriTemplate); var regex = new Regex("^" + templateRegex + "$", RegexOptions.IgnoreCase); result.Add(new OperationInfo <Verb>(method, url, uriTemplate, regex, item.Verb, parameters).WithSecurityDetailsFrom(method)); } return(result); }
public void GetHashCode__IsNotZero() { var attr = new RouteAttribute("/Foobar"); var results = attr.GetHashCode(); results.Should().NotBe(0); }
/// <summary> /// Returns true if this is a valid vanity id. /// /// Doesn't check if the id has already been issued, or similar /// </summary> /// <param name="id"></param> /// <returns></returns> public static bool IsValidVanityId(string id, out string errorMsg) { if (id.Length > 40) { errorMsg = "Vanity OpenId cannot be more than 40 characters long."; return(false); } if (!AllowedVanityIdRegex.IsMatch(id)) { errorMsg = "Vanity OpenId can only contain letters, numbers, dashes, and periods."; return(false); } var existingRoutes = RouteAttribute.GetDecoratedRoutes().Keys.Select(k => k.ToLower()); if (existingRoutes.Contains(id.ToLower())) { errorMsg = "This Vanity OpenId is reserved."; return(false); } // These two routes are manually mapped and *don't* contain illegal characters, // so we need to check for them seperately if (id.ToLower() == "ping" || id.ToLower() == "report") { errorMsg = "This Vanity OpenId is reserved."; return(false); } errorMsg = null; return(true); }
private static string GenerateUrlFromRoute(RouteAttribute routeAttr, out List <string> routeParameters, List <ActionParameterInfo> actionParameters) { var routeParametersList = new List <string>(); routeParameters = routeParametersList; var result = routeAttr.Template; var matches = Regex.Matches(result, "[{].+?[}]"); if (matches.Count == 0) { return("\"" + result + "\""); } while (Regex.IsMatch(result, "(.)[{](.+?)[}](.*)")) { result = Regex.Replace(result, "(.)[{](.+?)[}](.*)", m => { var value = m.Groups[2].Value; routeParametersList.Add(value); var actionParam = actionParameters.FirstOrDefault(a => a.OriginalName == value); if (actionParam != null) { actionParam.RouteProperty = true; } return(m.Groups[1].Value + "\" + " + value + " + \"" + m.Groups[3].Value); }); } return("\"" + result + "\""); }
private void RegisterRoute(object service, string serviceName, MethodInfo method, RouteAttribute routeAttr) { foreach (var attr in routeAttr.Create()) { var returnType = method.ReturnType; var cache = !ExcludedFromCache.Contains(returnType); if (cache && !returnType.IsSubclassOf(typeof(Task))) returnType = typeof(Task<>).MakeGenericType(returnType); if (string.IsNullOrEmpty(attr.Path)) attr.Path = method.Name; var path = string.Format("/{0}/{1}", serviceName, attr.Path); path = attr.ModifyPath(path).ToLower(); var route = CreateRoute(attr, method, service); m_processor.AddRoute(attr.Verb, path, route); if (cache && !m_taskResultLookup.ContainsKey(returnType)) { CacheResultProperty(returnType); m_logger.Debug("Cached task result property for type: {0}", returnType.GetGenericArguments()[0].GetFriendlyName()); } } }
public string GetRouteFromClass(Type type, IActionDescriptorCollectionProvider routeProvider) { // does the class have a route attribute RouteAttribute classRouteAttribute = (RouteAttribute)type.GetCustomAttributes(true) .Where(r => r.GetType() == typeof(RouteAttribute)).FirstOrDefault(); if (classRouteAttribute != null && !String.IsNullOrEmpty(classRouteAttribute.Template)) { return(classRouteAttribute.Template); } ActionDescriptor route = routeProvider.ActionDescriptors.Items.Where(ad => ad .DisplayName.StartsWith(type.FullName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault(); if (route == null) { return(String.Empty); } if (route.AttributeRouteInfo != null) { return($"/{route.AttributeRouteInfo.Template}/{route.AttributeRouteInfo.Name}"); } else if (route.AttributeRouteInfo == null) { ControllerActionDescriptor controllerDescriptor = route as ControllerActionDescriptor; return($"/{controllerDescriptor.ControllerName}"); } return(String.Empty); }
/// <summary> /// If called from a "/submit" route, redirects to the *preceeding* route with the given message and the passed fields restored. /// /// If called from any other route type, this throws an exception. /// /// We fill values to be rendered into ViewData (after clearing it, for security purposes) to accomplish this. /// Anything that also appears in the target method signature will be set as a query parameter as well. /// /// So, if you call this from "/login/submit" with passBack = { username = "******" } it will render "/login" with ViewData["username"] = "******". /// message is stashed into ViewData["error_message"]. /// /// Note that this method does not work from route with parameters in the path. /// </summary> public ActionResult RecoverableError(string message, object passBack) { const string submit = "/submit"; var request = Current.RequestUri.AbsolutePath.ToLower(); if (!request.EndsWith(submit)) { throw new InvalidOperationException("Cannot recover from an error if a route isn't handling a POST"); } var previousRoute = request.Substring(0, request.Length - submit.Length); var trueRandom = Current.UniqueId().ToString(); var toStore = passBack.PropertiesAsStrings(); toStore["error_message"] = message; Current.AddToCache(trueRandom, toStore, TimeSpan.FromMinutes(5)); var queryString = "?recover=" + trueRandom; var route = RouteAttribute.GetDecoratedRoutes()[previousRoute.Substring(1)]; foreach (var param in route.GetParameters()) { if (toStore.ContainsKey(param.Name)) { queryString += "&" + param.Name + "=" + HttpUtility.UrlEncode(toStore[param.Name]); } } return(Redirect(previousRoute + queryString)); }
/// <summary>Builds the descriptor internally.</summary> /// <returns>Controller information.</returns> protected virtual ControllerInfo <T> BuildDescriptorInternal() { var assembly = (typeof(T).IsGenericType) && (typeof(T).GetGenericArguments()[0].GetInterfaces().Contains(typeof(IController))) ? typeof(T).GetGenericArguments()[0].Assembly : typeof(T).Assembly; var globalRoutePrefix = assembly.GetCustomAttribute <RouteAttribute>(); var prefix = GetControllerRoute(); EntryPointInfo entryPoint = null; if (globalRoutePrefix != null) { prefix = new RouteAttribute(((HttpUrl)prefix.Url).InsertSegments(0, ((HttpUrl)globalRoutePrefix.Url).Segments).ToString()); entryPoint = new EntryPointInfo(globalRoutePrefix.Url).WithSecurityDetailsFrom(assembly); } IList <OperationInfo> operations = new List <OperationInfo>(); var methods = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance) .Except(typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance) .SelectMany(property => new[] { property.GetGetMethod(), property.GetSetMethod() })) .Where(item => item.DeclaringType != typeof(object)); foreach (var method in methods) { operations.AddRange(BuildMethodDescriptor(method, prefix)); } return(new ControllerInfo <T>(entryPoint, prefix.Url, operations.ToArray()).WithSecurityDetailsFrom(typeof(T))); }
private Mock <HttpContext> BuildContext(string routePath, IService serviceInstance, Type requestDto = null, string requestBody = "", Type responseDto = null, string routeTemplate = "", string contentType = "application/json", string method = "GET", Dictionary <string, object> routeValues = null, IQueryCollection query = null, ISerializationProvider provider = null) { RestVerbs restMethods; Enum.TryParse(method, true, out restMethods); var route = new RouteAttribute(routePath, restMethods); var context = new Mock <HttpContext>().SetupAllProperties(); var request = new Mock <HttpRequest>().SetupAllProperties(); var response = new Mock <HttpResponse>().SetupAllProperties(); var reqBody = new MemoryStream(Encoding.ASCII.GetBytes(requestBody)); var resBody = new MemoryStream(); var features = new Mock <IFeatureCollection>().SetupAllProperties(); var rserviceFeature = new RServiceFeature(); var routingFeature = new RoutingFeature(); var serializationProvider = provider ?? new NetJsonProvider(); features.Setup(x => x[typeof(IRServiceFeature)]).Returns(rserviceFeature); features.Setup(x => x[typeof(IRoutingFeature)]).Returns(routingFeature); rserviceFeature.RequestDtoType = requestDto; rserviceFeature.ResponseDtoType = responseDto; rserviceFeature.MethodActivator = _rservice.Routes[Utils.GetRouteKey(route, 0)].ServiceMethod; rserviceFeature.Service = serviceInstance; rserviceFeature.RequestSerializer = serializationProvider; rserviceFeature.ResponseSerializer = serializationProvider; if (!string.IsNullOrWhiteSpace(routeTemplate)) { routingFeature.RouteData = new RouteData(); var constraints = new Mock <IInlineConstraintResolver>().SetupAllProperties(); var irouter = new Mock <IRouter>().SetupAllProperties(); var router = new Mock <Route>(irouter.Object, routeTemplate, constraints.Object) .SetupAllProperties(); foreach (var kvp in routeValues ?? new Dictionary <string, object>()) { routingFeature.RouteData.Values.Add(kvp.Key, kvp.Value); } routingFeature.RouteData.Routers.Add(null); routingFeature.RouteData.Routers.Add(router.Object); routingFeature.RouteData.Routers.Add(null); } request.Object.Method = method; request.Object.ContentType = contentType; request.Object.Body = reqBody; request.Object.Query = query; response.Object.Body = resBody; context.SetupGet(x => x.Request).Returns(request.Object); context.SetupGet(x => x.Response).Returns(response.Object); context.SetupGet(x => x.Features).Returns(features.Object); return(context); }
private void SetRoute(ControllerModel controllerModel) { if (controllerModel.Attributes.Where(attr => typeof(IRouteTemplateProvider).IsAssignableFrom(attr.GetType())).Count() == 0) { var routeAttr = new RouteAttribute(controllerModel.ControllerName); controllerModel.Attributes.Add(routeAttr); } }
public void Equals__ReturnsFalseIfOtherIsNullAsRouteAttribute() { var attr = new RouteAttribute("/Foobar"); // ReSharper disable once ReturnValueOfPureMethodIsNotUsed var results = attr.Equals(null); results.Should().BeFalse(); }
public static void AddVersioningRoute(this MvcOptions opt, string versionPrefix) { if (!string.IsNullOrEmpty(versionPrefix)) { var routeAttribute = new RouteAttribute(versionPrefix); opt.Conventions.Insert(0, new RouteConvention(routeAttribute)); } }
public AppTextRouteConvention(string prefix, Assembly assembly) { if (!string.IsNullOrEmpty(prefix)) { var routeTemplateProvider = new RouteAttribute(prefix); _appTextPrefixModel = new AttributeRouteModel(routeTemplateProvider); } _assembly = assembly; }
public Task <HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { HttpResponseMessage response; if (Result.IsSuccessful) { object serializableResult = null; IHasObject singleObject = Result as IHasObject; IHasObjects multipleObject = null; if (singleObject == null) { multipleObject = Result as IHasObjects; } if (singleObject != null) { serializableResult = singleObject.Object; } else if (multipleObject != null) { serializableResult = multipleObject.Objects; } response = new HttpResponseMessage(SuccessCode); response.Content = new ObjectContent <object>(serializableResult, new JsonMediaTypeFormatter()); if (SuccessCode == HttpStatusCode.Created) { MethodInfo actionMethod = Controller.GetType().GetMethod(Controller.ActionContext.ActionDescriptor.ActionName); Contract.Assert(actionMethod != null); RouteAttribute routeAttribute = actionMethod.GetCustomAttribute <RouteAttribute>(true); Contract.Assert(routeAttribute != null); // Universal resource identifier response.Headers.Location = Controller.Url.Route ( routeAttribute.Name, Controller.ActionContext.ActionArguments ).ToUri(); } } else { response = new HttpResponseMessage(FailCode); foreach (var pair in Result.AffectedResources) { Controller.ModelState.AddModelError(pair.Key, pair.Value); } } return(Task.FromResult(response)); }
public void Test1() { RouteAttribute r = new RouteAttribute("/post/:postId/comment/:commentId"); var result = r.MatchPath("/Post/10/comment/2"); Assert.IsTrue(result.Match); Assert.AreEqual("10", result.Captured["postId"]); Assert.AreEqual("2", result.Captured["commentId"]); }
public void Ctor__CompositeKeyIncludesPathAndRoute() { const string path = SvcForMethods.PostPath; const RestVerbs method = SvcForMethods.PostMethod; var route = new RouteAttribute(path, method); var service = new RService(_options); service.Routes.Keys.Should().Contain(Utils.GetRouteKey(route)); }
/// <summary> /// Returns a route configuration obtained from the specified MethodInfo /// </summary> /// <param name="controllerMethodInfo"></param> /// <returns></returns> internal RouteConfiguration GetRouteConfiguration(MethodInfo controllerMethodInfo) { RouteAttribute routeAttribute = (RouteAttribute)Attribute.GetCustomAttribute(controllerMethodInfo, typeof(RouteAttribute)); string prefix = GetRoutePrefix(controllerMethodInfo); string suffix = GetRouteSuffix(controllerMethodInfo); return(new RouteConfiguration($@"^{prefix}{suffix}", routeAttribute.RequestMethod, controllerMethodInfo)); }
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{*allaspx}", new { allaspx = @".*\.aspx(/.*)?" }); // any controller methods that are decorated with our attribute will be registered RouteAttribute.MapDecoratedRoutes(routes); // MUST be the last route as a catch-all! routes.MapRoute("", "{*url}", new { controller = "Error", action = "PageNotFound" }); }
private static string TryGetFixedPathFromTemplate(RouteAttribute route, string placeholder) { if (route.Template.Contains(placeholder)) { var controllerName = GetRawServiceName(); return(route.Template.Replace(placeholder, controllerName)); } return(null); }
public void Apply(ApplicationModel application) { foreach (var controller in application.Controllers) { // is considered Miru's Controller only if it's inside a feature if (controller.ControllerType.IsNested == false) { continue; } var controllerRoute = GetRouteModel(controller.Selectors); if (controllerRoute == null) { var routeAttribute = new RouteAttribute(controller.ControllerName); controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel(routeAttribute); } foreach (var controllerAction in controller.Actions) { var route = GetRouteModel(controllerAction.Selectors); if (route == null) { var routeAttribute = new RouteAttribute(controllerAction.ActionName.IfThen("Index", string.Empty)); route = new AttributeRouteModel(routeAttribute); controllerAction.Selectors[0].AttributeRouteModel = route; } var oneParam = controllerAction.Parameters.FirstOrDefault(); if (oneParam != null && oneParam.ParameterInfo.ParameterType.GetTypeInfo().IsClass&& oneParam.ParameterInfo.ParameterType != typeof(string)) { route.Name = oneParam.ParameterInfo.ParameterType.ToString(); var map = new ModelToUrlMap { Method = controllerAction.Attributes.OfType <HttpPostAttribute>().Any() ? HttpMethod.Post : HttpMethod.Get, ActionName = controllerAction.ActionName, ControllerName = controller.ControllerName }; _mappings[oneParam.ParameterInfo.ParameterType.ToString()] = map; // if (oneParam.ParameterInfo.ParameterType.DeclaringType != null) // _mappings[oneParam.ParameterInfo.ParameterType.DeclaringType] = map; } } } }
public void Declare_a_route_attribute() { // design: ensure class declares the route attribute MemberInfo member = _sut.GetType(); Assert.IsTrue(MemberDeclaresAttribute <RouteAttribute>(member)); RouteAttribute attr = GetAttribute <RouteAttribute>(member); Assert.AreEqual("api/[controller]", attr.Value()); }
public void TestAttributeClassWithParameters() { var service = serviceProvider.GetService <AttributesService>(); var attributes = service.GetType().GetCustomAttributes(typeof(RouteAttribute), false); Assert.AreEqual(1, attributes.Length); RouteAttribute attribute = (RouteAttribute)attributes[0]; Assert.AreEqual("class-attr", attribute.Template); Assert.AreEqual(345, attribute.Order); }
/// <summary> Добавить префикс к жёстко заданым роутам контроллеров, чтобы привести к единообразному формату url </summary> public static void UseAttributeRoutePrefix(this MvcOptions opts, string routPrefix) { if (!routPrefix.EndsWith('/')) { routPrefix = $"{routPrefix}/"; } var prefixRouteAttribute = new RouteAttribute(routPrefix); opts.Conventions.Insert(0, new AttributeRouteConvention(prefixRouteAttribute)); }
static public void AddDynamicController <TRepository, TModel, TEntity, TKey>(this ControllerFeature feature) where TRepository : IRepository <TEntity, TKey> where TModel : class where TEntity : class where TKey : IEquatable <TKey> { var type = typeof(RestController <TRepository, TModel, TEntity, TKey>); var route = new RouteAttribute(nameof(TModel)); feature.Controllers.Add(type.GetTypeInfo()); }
private static void VerifyRouteName(RouteAttribute routeAttribute, Type controllerType, MemberInfo action, List <string> errors) { if (string.IsNullOrWhiteSpace(routeAttribute.Name)) { errors.Add($"Action [{action.Name}] on [{controllerType.Name}] has empty name on [{nameof(RouteAttribute)}] with route [{routeAttribute.Template}]"); } else if (routeAttribute.Name != controllerType.Name + "." + action.Name) { errors.Add($"Action [{action.Name}] on [{controllerType.Name}] has incorrect name on [{nameof(RouteAttribute)}] with route [{routeAttribute.Template}]. " + $"Expected name = [{controllerType.Name + "." + action.Name}]. Actual name: [{routeAttribute.Name}]"); } }
public object GetMethods() { JObject apiList = new JObject(); Assembly assembly = Assembly.GetExecutingAssembly(); foreach (Type type in assembly.GetTypes().Where(t => t.Name.IsMatch("Controller"))) { JArray controllerMethods = new JArray(); RouteAttribute route = (RouteAttribute)type.GetCustomAttributes(typeof(RouteAttribute)).FirstOrDefault(); string controllerName = type.Name.Replace("Controller", string.Empty); string mainRoute = route.Template.Replace("[controller]", controllerName.ToLower()); foreach (MethodInfo method in type.GetMethods()) { foreach (HttpMethodAttribute attr in method.GetCustomAttributes(typeof(HttpMethodAttribute))) { JObject apiMethod = new JObject { { "route", $"{string.Join(", ", attr.HttpMethods)} {string.Join("/", new string[] { mainRoute, attr.Template }.Where(s => !string.IsNullOrEmpty(s)))}" } }; AuthorizeAttribute authAttr = (AuthorizeAttribute)method.GetCustomAttributes(typeof(AuthorizeAttribute)).FirstOrDefault(); if (authAttr != null) { apiMethod.Add("auth", new JObject { { "roles", authAttr.Roles }, { "policy", authAttr.Policy } }); } ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length > 0) { JArray methodParams = new JArray(); foreach (ParameterInfo parameter in method.GetParameters()) { methodParams.Add(new JObject { { "name", parameter.Name }, { "type", parameter.ParameterType.Name }, { "default", parameter.RawDefaultValue.ToString() } }); } apiMethod.Add("params", methodParams); } controllerMethods.Add(apiMethod); } } apiList.Add(controllerName, controllerMethods); } return(apiList); }
public void Ctor__ScansAssembliesForRoutesOnMethods() { var route = new RouteAttribute(SvcWithMethodRoute.RoutePath, RestVerbs.Get); var expectedPath = Utils.GetRouteKey(route); var service = new RService(_options); service.Routes.Keys.Should().Contain(expectedPath); service.Routes[expectedPath].Route.Should().Be(route); service.Routes[expectedPath].ServiceType.Should().Be(typeof(SvcWithMethodRoute)); service.Routes[expectedPath].ServiceMethod.Should().NotBeNull(); }
/// <summary> /// register our ASP.NET MVC routes /// </summary> public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("errors"); routes.IgnoreRoute("errors/{*pathInfo}"); routes.IgnoreRoute("{*allaspx}", new { allaspx = @".*\.aspx(/.*)?" }); routes.IgnoreRoute("{*allaxd}", new { allaxd = @".*\.axd(/.*)?" }); routes.IgnoreRoute("favicon.ico"); RouteAttribute.MapDecoratedRoutes(routes); // MUST be the last route as a catch-all! routes.MapRoute("{*url}", new { controller = "Error", action = "PageNotFound" }); }
public void Apply(ControllerModel controller) { if (controller.ControllerType.IsGenericType) { var genericType = controller.ControllerType.GenericTypeArguments[0]; var attr = new RouteAttribute($"/{genericType.Name}"); controller.Selectors.Add(new SelectorModel { AttributeRouteModel = new AttributeRouteModel(attr), }); } }
private RouteValueDictionary GetDefaults(ControllerAction controllerAction, RouteAttribute attribute) { var routeDefaults = new RouteValueDictionary(new { controller = controllerAction.ControllerShortName, action = controllerAction.Action.Name, }); if (string.IsNullOrWhiteSpace(attribute.Defaults) == false) { var attributeDefaults = _javaScriptSerializer.Deserialize<IDictionary<string, object>>(attribute.Defaults); foreach (var key in attributeDefaults.Keys) { routeDefaults[key] = attributeDefaults[key]; } } return routeDefaults; }
public MethodMatch(MethodInfo method, RouteAttribute route) { Method = method; Route = route; }
private RouteAction CreateRoute(RouteAttribute routeAttr, MethodInfo method, object service) { var methodParams = method.GetParameters(); IQueryValidator argResolver = null; if (routeAttr.QueryValidatorType != null) argResolver = (IQueryValidator)m_resolver.Create(routeAttr.QueryValidatorType); return async (context, routeArgs) => { var response = context.Response; var request = context.Request; response.Chunked = routeAttr.EnableChunking; routeAttr.ModifyHttpContext(context); object taskResult; try { var result = await GetResult(context, routeArgs, service, method, methodParams, argResolver); var routeError = result as RouteError; if (routeError != null) taskResult = routeAttr.HandleError(routeError); else taskResult = routeAttr.Transform(result); } catch (Exception ex) { if (ex is TargetInvocationException) ex = ex.InnerException; m_logger.Error(ex); response.Status = HttpStatusCode.InternalServerError; var message = m_debug ? ex.ToString() : "Internal server error"; var error = new RouteError(RouteErrorDomain.Invocation, message); taskResult = routeAttr.HandleError(error); } if (taskResult != null) { var data = request.Encoding.GetBytes(taskResult.ToString() + "\r\n"); if (!response.Chunked) response.ContentLength = data.Length; await response.Stream.WriteAsync(data, 0, data.Length); } }; }
public void WireToMethod_Called_ExpectNamelessRoutesAreReturnedWithSamePathAndMethodForEachVerb(string path, MethodInfo method) { var attribute = new RouteAttribute(path, Verbs.TakeAtLeastOneItem()); attribute.WireToMethod(method).ShouldBeEquivalentTo(attribute.Verbs.Select(v => new Route(v, attribute.Path, method))); }
public void WireToMethod_CalledWithNullMethod_ExpectArgumentNullExceptionWithCorrectParamName(RouteAttribute attribute) { attribute.Invoking(x => x.WireToMethod(null)) .ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("method"); }
private RouteValueDictionary GetConstraints(RouteAttribute attribute) { var constraints = _javaScriptSerializer.Deserialize<IDictionary<string, object>>(attribute.Constraints ?? string.Empty); return new RouteValueDictionary(constraints ?? new object()); }
private string ResolveRoute(RouteAttribute attribute, RouteValueDictionary defaults) { // An explict URL trumps everything string routeUrl = attribute.Pattern; // If one doesn't exist, try to figure it out if (string.IsNullOrEmpty(routeUrl)) routeUrl = _routes.GetVirtualPath(_requestContext, defaults).VirtualPath; if ((routeUrl ?? string.Empty).StartsWith("/")) routeUrl = routeUrl.Substring(1); return routeUrl; }