/// <summary> /// Creates a <see cref="RoutePattern"/> from its string representation along /// with provided default values and parameter policies. /// </summary> /// <param name="pattern">The route pattern string to parse.</param> /// <param name="defaults"> /// Additional default values to associated with the route pattern. May be null. /// The provided object will be converted to key-value pairs using <see cref="RouteValueDictionary"/> /// and then merged into the parsed route pattern. /// </param> /// <param name="parameterPolicies"> /// Additional parameter policies to associated with the route pattern. May be null. /// The provided object will be converted to key-value pairs using <see cref="RouteValueDictionary"/> /// and then merged into the parsed route pattern. /// Multiple policies can be specified for a key by providing a collection as the value. /// </param> /// <returns>The <see cref="RoutePattern"/>.</returns> public static RoutePattern Parse(string pattern, object?defaults, object?parameterPolicies) { if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); } var original = RoutePatternParser.Parse(pattern); return(PatternCore(original.RawText, Wrap(defaults), Wrap(parameterPolicies), requiredValues: null, original.PathSegments)); }
private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate) { var serviceId = _serviceIdGenerator.GenerateServiceId(method); var attributes = method.GetCustomAttributes().ToList(); var serviceDescriptor = new ServiceDescriptor { Id = serviceId, RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name) }; var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>(); foreach (var descriptorAttribute in descriptorAttributes) { descriptorAttribute.Apply(serviceDescriptor); } var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault(); if (authorization != null) { serviceDescriptor.EnableAuthorization(true); } if (authorization != null) { serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType) ?? AuthorizationType.AppSecret); } var fastInvoker = GetHandler(serviceId, method); return(new ServiceEntry { Descriptor = serviceDescriptor, RoutePath = serviceDescriptor.RoutePath, MethodName = method.Name, Type = method.DeclaringType, Attributes = attributes, Func = (key, parameters) => { var instance = _serviceProvider.GetInstances(key, method.DeclaringType); var list = new List <object>(); foreach (var parameterInfo in method.GetParameters()) { var value = parameters[parameterInfo.Name]; var parameterType = parameterInfo.ParameterType; var parameter = _typeConvertibleService.Convert(value, parameterType); list.Add(parameter); } var result = fastInvoker(instance, list.ToArray()); return Task.FromResult(result); } }); }
public void Parse_OptionalParameter() { // Arrange var template = "{p?}"; var expected = Pattern(template, Segment(ParameterPart("p", null, RoutePatternParameterKind.Optional))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_SingleParameter() { // Arrange var template = "{p}"; var expected = Pattern(template, Segment(ParameterPart("p"))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void ParseRouteParameter_ThrowsIf_ParameterContainsSpecialCharacters( string template, string parameterName) { // Arrange var expectedMessage = "The route parameter name '" + parameterName + "' is invalid. Route parameter " + "names must be non-empty and cannot contain these characters: '{', '}', '/'. The '?' character " + "marks a parameter as optional, and can occur only at the end of the parameter. The '*' character " + "marks a parameter as catch-all, and can occur only at the start of the parameter."; // Act & Assert ExceptionAssert.Throws <RoutePatternException>(() => RoutePatternParser.Parse(template), expectedMessage); }
public void Parse_MultipleLiterals() { // Arrange var template = "cool/awesome/super"; var expected = Pattern( template, Segment(LiteralPart("cool")), Segment(LiteralPart("awesome")), Segment(LiteralPart("super"))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_MultipleParameters() { // Arrange var template = "{p1}/{p2}/{*p3}"; var expected = Pattern( template, Segment(ParameterPart("p1")), Segment(ParameterPart("p2")), Segment(ParameterPart("p3", null, RoutePatternParameterKind.CatchAll))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_ComplexSegment_LP() { // Arrange var template = "cool-{p1}"; var expected = Pattern( template, Segment( LiteralPart("cool-"), ParameterPart("p1"))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
[InlineData(@"{p1:regex(([{{(])\w+)}", @"regex(([{(])\w+)")] // Not balanced { public void Parse_RegularExpressions(string template, string constraint) { // Arrange var expected = Pattern( template, Segment( ParameterPart( "p1", null, RoutePatternParameterKind.Standard, Constraint(constraint)))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_ComplexSegment_OptionalParameterFollowingPeriod_PeriodAfterSlash() { // Arrange var template = "{p2}/.{p3?}"; var expected = Pattern( template, Segment(ParameterPart("p2")), Segment( SeparatorPart("."), ParameterPart("p3", null, RoutePatternParameterKind.Optional))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
public void Parse_ComplexSegment_ParametersFollowingPeriod() { // Arrange var template = "{p1}.{p2}"; var expected = Pattern( template, Segment( ParameterPart("p1"), LiteralPart("."), ParameterPart("p2"))); // Act var actual = RoutePatternParser.Parse(template); // Assert Assert.Equal <RoutePattern>(expected, actual, new RoutePatternEqualityComparer()); }
private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate) { var serviceId = _serviceIdGenerator.GenerateServiceId(method); var attributes = method.GetCustomAttributes().ToList(); var serviceDescriptor = new ServiceDescriptor { Id = serviceId, RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name) }; return(new ServiceEntry { Descriptor = serviceDescriptor, RoutePath = serviceDescriptor.RoutePath, MethodName = method.Name, Type = method.DeclaringType, Attributes = attributes, }); }
private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate) { var serviceId = _serviceIdGenerator.GenerateServiceId(method); var attributes = method.GetCustomAttributes().ToList(); var serviceDescriptor = new ServiceDescriptor { Id = serviceId, RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name) }; var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>(); foreach (var descriptorAttribute in descriptorAttributes) { descriptorAttribute.Apply(serviceDescriptor); } serviceDescriptor.EnableAuthorization(!serviceDescriptor.EnableAuthorization() ? attributes.Any(p => p is AuthorizationFilterAttribute) : serviceDescriptor.EnableAuthorization()); var fastInvoker = FastInvoke.GetMethodInvoker(method); return(new ServiceEntry { Descriptor = serviceDescriptor, Attributes = attributes, Func = (key, parameters) => { var instance = _serviceProvider.GetInstances(key, method.DeclaringType); var list = new List <object>(); foreach (var parameterInfo in method.GetParameters()) { var value = parameters[parameterInfo.Name]; var parameterType = parameterInfo.ParameterType; var parameter = _typeConvertibleService.Convert(value, parameterType); list.Add(parameter); } var result = fastInvoker(instance, list.ToArray()); //method.Invoke(instance, list.ToArray()); return Task.FromResult(result); } }); }
/// <summary> /// Creates the service entry. /// </summary> /// <param name="service">The service.</param> /// <returns>DnsServiceEntry.</returns> public DnsServiceEntry CreateServiceEntry(Type service) { DnsServiceEntry result = null; var routeTemplate = service.GetCustomAttribute <ServiceBundleAttribute>(); var objInstance = _serviceProvider.GetInstances(service); var behavior = objInstance as DnsBehavior; var path = RoutePatternParser.Parse(routeTemplate.RouteTemplate, service.Name); if (path.Length > 0 && path[0] != '/') { path = $"/{path}"; } if (behavior != null) { result = new DnsServiceEntry { Behavior = behavior, Type = behavior.GetType(), Path = path } } ; return(result); }
private RoutePatternMatcher CreateMatcher(string template, object defaults = null) { return(new RoutePatternMatcher( RoutePatternParser.Parse(template), new RouteValueDictionary(defaults))); }
public void InvalidTemplate_WithRepeatedParameter() { var ex = ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("{Controller}.mvc/{id}/{controller}"), "The route parameter name 'controller' appears more than one time in the route template."); }
private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate, bool routeIsReWriteByServiceRoute = false) { var serviceId = _serviceIdGenerator.GenerateServiceId(method); var attributes = method.GetCustomAttributes().ToList(); var serviceDescriptor = new ServiceDescriptor { Id = serviceId, RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name, routeIsReWriteByServiceRoute) }; var httpMethodAttributes = attributes.Where(p => p is HttpMethodAttribute).Select(p => p as HttpMethodAttribute).ToList(); var httpMethods = new List <string>(); foreach (var httpAttribute in httpMethodAttributes) { httpMethods.AddRange(httpAttribute.HttpMethods); } if (!httpMethods.Any()) { var paramTypes = GetParamTypes(method); if (paramTypes.All(p => p.Value.IsValueType || p.Value == typeof(string) || p.Value.IsEnum)) { httpMethods.Add(HttpMethod.GET.ToString()); } else { httpMethods.Add(HttpMethod.POST.ToString()); } } serviceDescriptor.HttpMethod(httpMethods); var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault(); if (authorization != null) { serviceDescriptor.EnableAuthorization(true); } if (authorization != null) { serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType) ?? AuthorizationType.AppSecret); } else { serviceDescriptor.EnableAuthorization(true); serviceDescriptor.AuthType(AuthorizationType.JWT); } var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>(); foreach (var descriptorAttribute in descriptorAttributes) { descriptorAttribute.Apply(serviceDescriptor); } var fastInvoker = GetHandler(serviceId, method); return(new ServiceEntry { Descriptor = serviceDescriptor, RoutePath = serviceDescriptor.RoutePath, Methods = httpMethods, MethodName = method.Name, Type = method.DeclaringType, Attributes = attributes, ParamTypes = GetParamTypes(method), CacheKeys = GetCackeKeys(method), Func = (key, parameters) => { object instance = null; if (AppConfig.ServerOptions.IsModulePerLifetimeScope) { instance = _serviceProvider.GetInstancePerLifetimeScope(key, method.DeclaringType); } else { instance = _serviceProvider.GetInstances(key, method.DeclaringType); } var list = new List <object>(); foreach (var parameterInfo in method.GetParameters()) { if (parameters.ContainsKey(parameterInfo.Name)) { var value = parameters[parameterInfo.Name]; var parameterType = parameterInfo.ParameterType; var parameter = _typeConvertibleService.Convert(value, parameterType); list.Add(parameter); } //加入是否有默认值的判断,有默认值,并且用户没传,取默认值 else if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name)) { list.Add(parameterInfo.DefaultValue); } else { list.Add(null); } } var result = fastInvoker(instance, list.ToArray()); return Task.FromResult(result); } }); }
public void InvalidTemplate_CannotContainQuestionMark() { ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("foor?bar"), "The literal section 'foor?bar' is invalid. Literal sections cannot contain the '?' character."); }
public void InvalidTemplate_CatchAllMarkedOptional() { ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("{a}/{*b?}"), "A catch-all parameter cannot be marked optional."); }
public void InvalidTemplate_CannotStartWithTilde() { ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("~foo"), "The route template cannot start with a '~' character unless followed by a '/'."); }
public void InvalidTemplate_CannotHaveMoreThanOneCatchAll() { ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("{*p1}/{*p2}"), "A catch-all parameter can only appear as the last segment of the route template."); }
public void InvalidTemplate_WithCatchAllNotAtTheEndThrows() { ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("foo/{p1}/{*p2}/{p3}"), "A catch-all parameter can only appear as the last segment of the route template."); }
public void InvalidTemplate_InvalidParameterNameWithOpenBracketThrows() { ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("{a}/{a{aa}/{z}"), "In a route parameter, '{' and '}' must be escaped with '{{' and '}}'."); }
private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate) { var serviceId = _serviceIdGenerator.GenerateServiceId(method); var attributes = method.GetCustomAttributes().ToList(); var serviceDescriptor = new ServiceDescriptor { Id = serviceId, RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name) }; serviceDescriptor = SetPorts(serviceDescriptor); serviceDescriptor.EnableAuthorization(true); serviceDescriptor.AuthType(AuthorizationType.JWT); var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>(); foreach (var descriptorAttribute in descriptorAttributes) { descriptorAttribute.Apply(serviceDescriptor); } //var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault(); //if (authorization != null) //{ // serviceDescriptor.EnableAuthorization(true); // serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType) // ?? AuthorizationType.AppSecret); //} var fastInvoker = GetHandler(serviceId, method); return(new ServiceEntry { Descriptor = serviceDescriptor, RoutePath = serviceDescriptor.RoutePath, MethodName = method.Name, Type = method.DeclaringType, Attributes = attributes, Func = (key, parameters) => { var instance = _serviceProvider.GetInstances(key, method.DeclaringType); var list = new List <object>(); foreach (var parameterInfo in method.GetParameters()) { if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name)) { list.Add(parameterInfo.DefaultValue); continue; } var value = parameters[parameterInfo.Name]; var parameterType = parameterInfo.ParameterType; var parameter = _typeConvertibleService.Convert(value, parameterType); list.Add(parameter); } if (parameters.ContainsKey("payload")) { if (RpcContext.GetContext().GetAttachment("payload") == null) { var serializer = ServiceLocator.GetService <ISerializer <string> >(); var payloadString = serializer.Serialize(parameters["payload"], true); RpcContext.GetContext().SetAttachment("payload", payloadString); } } var result = fastInvoker(instance, list.ToArray()); return Task.FromResult(result); } }); }
private ServiceEntry Create(MethodInfo method, string serviceName, string routeTemplate) { var serviceId = _serviceIdGenerator.GenerateServiceId(method); var attributes = method.GetCustomAttributes().ToList(); var serviceDescriptor = new ServiceDescriptor { Id = serviceId, RoutePath = RoutePatternParser.Parse(routeTemplate, serviceName, method.Name) }; var httpMethodAttributes = attributes.Where(p => p is HttpMethodAttribute).Select(p => p as HttpMethodAttribute).ToList(); var httpMethods = new List <string>(); StringBuilder httpMethod = new StringBuilder(); foreach (var attribute in httpMethodAttributes) { httpMethods.AddRange(attribute.HttpMethods); if (attribute.IsRegisterMetadata) { httpMethod.AppendJoin(',', attribute.HttpMethods).Append(","); } } if (httpMethod.Length > 0) { httpMethod.Length = httpMethod.Length - 1; serviceDescriptor.HttpMethod(httpMethod.ToString()); } var authorization = attributes.Where(p => p is AuthorizationFilterAttribute).FirstOrDefault(); if (authorization != null) { serviceDescriptor.EnableAuthorization(true); } if (authorization != null) { serviceDescriptor.AuthType(((authorization as AuthorizationAttribute)?.AuthType) ?? AuthorizationType.AppSecret); } else { serviceDescriptor.EnableAuthorization(true); serviceDescriptor.AuthType(AuthorizationType.JWT); } var descriptorAttributes = method.GetCustomAttributes <ServiceDescriptorAttribute>(); foreach (var descriptorAttribute in descriptorAttributes) { descriptorAttribute.Apply(serviceDescriptor); } var fastInvoker = GetHandler(serviceId, method); return(new ServiceEntry { Descriptor = serviceDescriptor, RoutePath = serviceDescriptor.RoutePath, Methods = httpMethods, MethodName = method.Name, Type = method.DeclaringType, Attributes = attributes, Func = (key, parameters) => { object instance = null; if (AppConfig.ServerOptions.IsModulePerLifetimeScope) { instance = _serviceProvider.GetInstancePerLifetimeScope(key, method.DeclaringType); } else { instance = _serviceProvider.GetInstances(key, method.DeclaringType); } var list = new List <object>(); foreach (var parameterInfo in method.GetParameters()) { //加入是否有默认值的判断,有默认值,并且用户没传,取默认值 if (parameterInfo.HasDefaultValue && !parameters.ContainsKey(parameterInfo.Name)) { list.Add(parameterInfo.DefaultValue); continue; } var value = parameters[parameterInfo.Name]; var parameterType = parameterInfo.ParameterType; var parameter = _typeConvertibleService.Convert(value, parameterType); list.Add(parameter); } var result = fastInvoker(instance, list.ToArray()); return Task.FromResult(result); } }); }
public void InvalidTemplate_SameParameterTwiceAndOneCatchAllThrows() { ExceptionAssert.Throws <RoutePatternException>( () => RoutePatternParser.Parse("{aaa}/{*AAA}"), "The route parameter name 'AAA' appears more than one time in the route template."); }