/// <summary> /// Return true if the path and the route segments match. Any parameters in the path /// get put into parms. The first route that matches will win. /// </summary> protected bool Match(string[] pathSegments, string[] routeSegments, PathParams parms) { // Basic check: # of segments must be the same. bool ret = pathSegments.Length == routeSegments.Length; if (ret) { int n = 0; // Check each segment while (n < pathSegments.Length && ret) { string pathSegment = pathSegments[n]; string routeSegment = routeSegments[n]; ++n; // Is it a parameterized segment (aka "capture segment") ? if (routeSegment.BeginsWith("{")) { string parmName = routeSegment.Between('{', '}'); string value = pathSegment; parms[parmName] = value; } else // We could perform other checks, such as regex { ret = pathSegment == routeSegment; } } } return(ret); }
protected WorkflowState CheckExpirationAndAuthorization(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper wrapper, Session session) { // Inspect the route to see if we should do session expiration and/or session authorization checks. WorkflowState ret = WorkflowState.Continue; RouteEntry entry = null; PathParams parms = null; if (routeTable.TryGetRouteEntry(wrapper.Context.Verb(), wrapper.Context.Path(), out entry, out parms)) { if (entry.SessionExpirationHandler != null) { ret = entry.SessionExpirationHandler(workflowContinuation, wrapper, session, parms); } if (ret == WorkflowState.Continue) { if (entry.AuthorizationHandler != null) { ret = entry.AuthorizationHandler(workflowContinuation, wrapper, session, parms); } } } return(ret); }
/// <summary> /// Parse the browser's path request and match it against the routes. /// If found, return the route entry (otherwise null). /// Also if found, the parms will be populated with any segment parameters. /// </summary> protected RouteEntry Parse(RouteKey key, PathParams parms) { RouteEntry entry = null; // First, check non-parameterized routes. // The most performant way to handle parameters is after the path, // rather than embedding parameters in the URL itself. if (!routes.TryGetValue(key, out entry)) { string[] pathSegments = key.Path.Split('/'); foreach (KeyValuePair <RouteKey, RouteEntry> route in routes) { // Above all else, verbs and, if not wildcarded, content type must match. if ((route.Key.Verb == key.Verb) && ((route.Key.ContentType == "*") || (route.Key.ContentType == key.ContentType))) { string[] routeSegments = route.Key.Path.Split('/'); // Then, segments must match if (Match(pathSegments, routeSegments, parms)) { entry = route.Value; break; } } } } return(entry); }
/// <summary> /// Returns true and populates the route entry and path parameters if the key exists. /// </summary> public bool TryGetRouteEntry(RouteKey key, out RouteEntry entry, out PathParams parms) { parms = new PathParams(); entry = Parse(key, parms); return(entry != null); }
/// <summary> /// Returns true and populates the route entry and path parameters if the key exists. /// </summary> public bool TryGetRouteEntry(string verb, string path, string contentType, out RouteEntry entry, out PathParams parms) { parms = new PathParams(); entry = Parse(NewKey(verb, path, contentType), parms); return(entry != null); }
/// <summary> /// this class models a request that can be sent to a service /// </summary> /// <param name="headers">the headers that should be sent as part of the request</param> /// <param name="httpMethod">the httpMethod of the request</param> /// <param name="pathParameters">any path parameters required</param> /// <param name="queryParameters">any query parameters required</param> /// <param name="requestBody">a request body if required</param> public Request(RESTHeaders headers, RestSharp.Method httpMethod, PathParams pathParameters, IQueryParams queryParameters, IRequestBody requestBody) { this.headers = headers; this.httpMethod = httpMethod; this.pathParameters = pathParameters; this.queryParameters = queryParameters; this.requestBody = requestBody; }
public void path_params_does_not_modify_resource_when_no_params_exist_in_resource() { var resource = "users/Doe/John"; var pathparams = new PathParams(); pathparams.Add("key", "value"); var path = pathparams.ParseResource(resource); path.ShouldBe(resource); }
public void ParsesResourceString() { const string resource = "user/[lastname]/[firstname]"; var pathparams = new PathParams { { "firstname", "John" }, { "lastname", "Doe" } }; var path = pathparams.Stringify(resource); path.ShouldBe("user/Doe/John"); }
public void DoesNotModifyResourceWhenNoParamsExistInResource() { const string resource = "users/Doe/John"; var pathparams = new PathParams { { "key", "value" } }; var path = pathparams.Stringify(resource); path.ShouldBe(resource); }
/// <summary> /// Get the route entry for the verb and path including any path parameters. /// Throws an exception if the route isn't found. /// </summary> public RouteEntry GetRouteEntry(RouteKey key, out PathParams parms) { parms = new PathParams(); RouteEntry entry = Parse(key, parms); if (entry == null) { throw new ApplicationException("The route key " + key.ToString() + " does not exist."); } return(entry); }
public void path_params_parses_resource_string() { var resource = "user/[lastname]/[firstname]"; var pathparams = new PathParams(); pathparams.Add("firstname", "John"); pathparams.Add("lastname", "Doe"); var path = pathparams.ParseResource(resource); path.ShouldBe("user/Doe/John"); }
public void path_params_throws_exception_when_not_all_placeholders_are_parses() { var resource = "user/[lastname]/[firstname]"; var pathparams = new PathParams(); pathparams.Add("firstname", "John"); var exception = Record.Exception(() => pathparams.ParseResource(resource)); exception.ShouldNotBeNull(); exception.ShouldBeOfType <ClientStateException>(); exception.Message.ShouldBe("Not all parameters were replaced in request resource: user/[lastname]/John"); }
public void ThrowsExceptionWhenNotAllPlaceholdersAreParses() { const string resource = "user/[lastname]/[firstname]"; var pathparams = new PathParams { { "firstname", "John" } }; var exception = Record.Exception(() => pathparams.Stringify(resource)); exception.ShouldNotBeNull(); exception.ShouldBeOfType <ClientStateException>(); exception.Message.ShouldNotBeNull(); exception.Message.ShouldBe("Not all parameters were replaced in request resource: user/[lastname]/John"); }
/// <summary> /// Route the request. If no route exists, the workflow continues, otherwise, we return the route handler's continuation state. /// </summary> public WorkflowState Route(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper wrapper) { WorkflowState ret = WorkflowState.Continue; RouteEntry entry = null; Session session = sessionManager != null ? sessionManager[wrapper.Context] : null; PathParams parms = null; // Makes debugging easier to declare these variable here. string verb = wrapper.Context.Verb(); string path = wrapper.Context.Path(); if (routeTable.TryGetRouteEntry(verb, path, wrapper.Context.Request.ContentType, out entry, out parms)) { if (entry.RouteHandler != null) { ret = entry.RouteHandler(workflowContinuation, wrapper, session, parms); } } return(ret); }
public static void Run() { var router = new HttpRouter(); //var getTree= router.GetTree; //var postTree = router.PostTree; //var headTree = router.HeadTree; //var putTree = router.PutTree; //var deleteTree = router.DeleteTree; router.MapGet("/get/index", (req, resp) => Console.WriteLine("/get/index")); //不支持参数约束,前缀,后缀 繁琐而且用处不大 //Not support parameter constraints,prefix,suffix tedious and useless router.MapGet("/get/{param1}/{param2}", (req, resp) => Console.WriteLine("/get/{param1}/{param2}")); router.MapGet("/get/{*catchAll}", (req, resp) => Console.WriteLine("/get/{*catchAll}")); Console.WriteLine("MapGet"); foreach (var item in router.GetTree) { Console.WriteLine(item.Key); } //MapAttribute var compiler = new HandlerCompiler();//See HandlerCompilerSample //compiler.Register() router.MapAttribute(new[] { typeof(TestService) }, compiler); //customize router.MapAttribute(new[] { typeof(TestService) }, compiler, (method, typeHandlers, methodHandlers, handler) => { var handlers = new List <IHttpHandler>(); handlers.Add(HttpHandler.CreateModule((req, handler) => { Console.WriteLine("Before typeHandlers"); return(handler.HandleAsync(req)); })); handlers.AddRange(typeHandlers); handlers.Add(HttpHandler.CreateModule((req, handler) => { Console.WriteLine("Before methodHandlers"); return(handler.HandleAsync(req)); })); handlers.AddRange(methodHandlers); handlers.Add(handler); return(HttpHandler.CreatePipeline(handlers)); }); //router.MapAttribute(compiler); //router.MapAttribute(handlerDelegate) Console.WriteLine(); Console.WriteLine("MapAttribute"); foreach (var item in router.GetTree) { Console.WriteLine(item.Key); } Directory.CreateDirectory("Static"); File.WriteAllText("Static/testFile.txt", "this is file content.BY 张贺", new UTF8Encoding(false)); File.WriteAllText("Static/testHtml1.html", "<h1>testHtml1<h1>", new UTF8Encoding(false)); File.WriteAllText("Static/testHtml2.html", "<h2>testHtml2<h2>", new UTF8Encoding(false)); //MapFile router.MapFile("/testFile1", "Static/testFile.txt", 86400);//CacheControl router.MapFile("/testFile2", "Static/testFile.txt", "text/html; charset=utf-8", 86400); //MapFiles router.MapFiles("/static1/{*path}", "Static", 86400); var customMimeTypes = new MimeTypes(); //var customMimeTypes = new MimeTypes(MimeTypes.Default); customMimeTypes.Add(".html", "text/html; charset=utf-8"); router.MapFiles("/static2/{*customName}", "Static", customMimeTypes, 86400, "customName"); //router.MapFiles("/static2/{*customName}", "Static", MimeTypes.Default, TimeSpan.FromDays(1), "customName"); //MapSlash //尾部/ router.GetTree.MapSlash(); //router.MapSlash(); Console.WriteLine(); Console.WriteLine("MapSlash"); foreach (var item in router.GetTree) { Console.WriteLine(item.Key); } //动态路由 //Dynamic change router //CopyOnWrite(Safe) var newGetTree = new HttpRouter.Tree(); newGetTree.Map("/new/index", HttpHandler.Create((req, resp) => { Console.WriteLine("/new/index"); })); newGetTree.Map("/new/{param1}/{param2}", HttpHandler.Create((req, resp) => { Console.WriteLine("/new/{param1}/{param2}"); })); newGetTree.Map("/new/{*catchAll}", HttpHandler.Create((req, resp) => { Console.WriteLine("/new/{*catchAll}"); })); newGetTree.MapSlash(); newGetTree.MapTree(router.GetTree); router.GetTree = newGetTree; Console.WriteLine(); Console.WriteLine("NewGetTree"); foreach (var item in router.GetTree) { Console.WriteLine(item.Key); } //Match Console.WriteLine(); Console.WriteLine("Match"); var params1 = new PathParams(); var h1 = router.GetTree.Match("/attribute/index", params1); Console.WriteLine(params1.Count); var params2 = new PathParams(); var h2 = router.GetTree.Match("/attribute/p1/x/y", params2); Console.WriteLine(params2.Count); var params3 = new PathParams(); var h3 = router.GetTree.Match("/attribute/catchAll/x/y/z//", params3); Console.WriteLine(params3.Count); //HandleAsync Console.WriteLine(); Console.WriteLine("HandleAsync"); var req1 = new HttpRequest("/attribute/index") { Method = HttpMethod.Get }; var resp1 = router.HandleAsync(req1).Result; var req2 = new HttpRequest("/attribute/p1/x/y") { Method = HttpMethod.Get }; var resp2 = router.HandleAsync(req2).Result; var req3 = new HttpRequest("/attribute/catchAll/x/y/z//") { Method = HttpMethod.Get }; var resp3 = router.HandleAsync(req3).Result; var req4 = new HttpRequest("/testFile1") { Method = HttpMethod.Get }; var resp4 = router.HandleAsync(req4).Result; Console.WriteLine(resp4.Content.ReadStringAsync().Result); var req5 = new HttpRequest("/testFile2") { Method = HttpMethod.Head }; var resp5 = router.HandleAsync(req5).Result; Console.WriteLine(resp5.Content.ReadStringAsync().Result); var req6 = new HttpRequest("/static1/testHtml1.html") { Method = HttpMethod.Get }; var resp6 = router.HandleAsync(req6).Result; Console.WriteLine(resp6.Content.ReadStringAsync().Result); var req7 = new HttpRequest("/static2/testHtml2.html") { Method = HttpMethod.Get }; var resp7 = router.HandleAsync(req7).Result; Console.WriteLine(resp7.Content.ReadStringAsync().Result); //------------------------------------------------------------------------ //router chain(HttpRouter is IHttpHandler) var router1 = new HttpRouter(); var router2 = new HttpRouter();//var tree1 = new HttpRouter.Tree(); router2.MapGet("/{*path}", (req, resp) => { Console.WriteLine(nameof(router2)); Console.WriteLine(req.PathParams().GetValue <string>("path")); }); router1.GetTree.Map("/Images/{*img}", router2); router1.GetTree.Map("/Js/{*js}", HttpHandler.Create( (req) => { Console.WriteLine("Js"); return(router2.HandleAsync(req)); })); Console.WriteLine(); var req8 = new HttpRequest("/Images/123456.png") { Method = HttpMethod.Get }; var resp8 = router1.HandleAsync(req8).Result; var req9 = new HttpRequest("/Js/jq.js") { Method = HttpMethod.Get }; var resp9 = router1.HandleAsync(req9).Result; //------------------------------------------------------------------------ //special // /path1/{param1} Match /path1/ (if not Map /path1/) var router3 = new HttpRouter(); router3.MapGet("/", (req, resp) => { Console.WriteLine("/"); }); router3.MapGet("/{param1}", (req, resp) => { Console.WriteLine("/{param1}"); }); var req10 = new HttpRequest("/") { Method = HttpMethod.Get }; var resp10 = router3.HandleAsync(req10).Result; var router4 = new HttpRouter(); //router4.MapGet("/", (req, resp) => { Console.WriteLine("/"); }); router4.MapGet("/{param1}", (req, resp) => { Console.WriteLine("/{param1}"); }); var req11 = new HttpRequest("/") { Method = HttpMethod.Get }; var resp11 = router4.HandleAsync(req11).Result; // multiple / var router5 = new HttpRouter(); router5.MapGet("////", (req, resp) => { Console.WriteLine("////"); }); var req12 = new HttpRequest("////") { Method = HttpMethod.Get }; var resp12 = router5.HandleAsync(req12).Result; router5.MapGet("/Path1/{param1}/{param2}/", (req, resp) => { Console.WriteLine("/Path1/{param1}/{param2}/"); }); //OR /Path1/{param1}/{param2}/{param3} var req13 = new HttpRequest("/Path1///") { Method = HttpMethod.Get }; var resp13 = router5.HandleAsync(req13).Result; }
/// <summary> /// Get the route entry for the verb and path including any path parameters. /// Throws an exception if the route isn't found. /// </summary> public RouteEntry GetRouteEntry(string verb, string path, string contentType, out PathParams parms) { return(GetRouteEntry(NewKey(verb, path, contentType), out parms)); }
/// <summary> /// Get the route entry for the verb and path including any path parameters. /// Throws an exception if the route isn't found. /// </summary> public RouteEntry GetRouteEntry(string verb, string path, out PathParams parms) { return(GetRouteEntry(NewKey(verb, path), out parms)); }
public override LocalDeclarationStatementSyntax GetSyntax() { var paramArgList = new List <SyntaxNodeOrToken>(); paramArgList.Add(GetLiteralArg("path", Path)); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); if (PathParams.Any()) { paramArgList.Add(GetVariableArg("pathParams", "pathParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (QueryParams.Any()) { paramArgList.Add(GetVariableArg("queryParams", "queryParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (BodyParams.Any()) { paramArgList.Add(GetVariableArg("bodyParams", "bodyParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } paramArgList.Add(GetMemberAccessArg("method", "HttpMethods", HttpMethod)); return(SyntaxFactory.LocalDeclarationStatement( SyntaxFactory.VariableDeclaration( SyntaxFactory.GenericName( SyntaxFactory.Identifier("Func")) .WithTypeArgumentList( SyntaxFactory.TypeArgumentList( SyntaxFactory.SeparatedList <TypeSyntax>( new SyntaxNodeOrToken[] { SyntaxFactory.IdentifierName(ListOptionsName), SyntaxFactory.Token(SyntaxKind.CommaToken), SyntaxFactory.GenericName( SyntaxFactory.Identifier("Task")) .WithTypeArgumentList( SyntaxFactory.TypeArgumentList( SyntaxFactory.SingletonSeparatedList <TypeSyntax>( SyntaxFactory.GenericName( SyntaxFactory.Identifier("ResponsePage")) .WithTypeArgumentList( SyntaxFactory.TypeArgumentList( SyntaxFactory.SingletonSeparatedList <TypeSyntax>( SyntaxFactory.IdentifierName(Returns))))))) })))) .WithVariables( SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>( SyntaxFactory.VariableDeclarator( SyntaxFactory.Identifier("paginatedFunc")) .WithInitializer( SyntaxFactory.EqualsValueClause( SyntaxFactory.ParenthesizedLambdaExpression( getFunctionBlock(paramArgList) ) .WithAsyncKeyword( SyntaxFactory.Token(SyntaxKind.AsyncKeyword)) .WithParameterList( SyntaxFactory.ParameterList( SyntaxFactory.SingletonSeparatedList <ParameterSyntax>( SyntaxFactory.Parameter( SyntaxFactory.Identifier("_options")) .WithType( SyntaxFactory.IdentifierName(ListOptionsName))))))))))); }
public void AddPathParameter(string name, string value) => PathParams.Add(new KeyValuePair <string, string>(name, value));
public GetPaymentInitDetailsRequest(RESTHeaders headers, PathParams pathParameters) : base(headers, Method.POST, pathParameters, null, null) { }
public override StatementSyntax GetSyntax() { var paramArgList = new List <SyntaxNodeOrToken>(); paramArgList.Add(GetLiteralArg("path", Path)); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); if (PathParams.Any()) { paramArgList.Add(GetVariableArg("pathParams", "pathParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (QueryParams.Any()) { paramArgList.Add(GetVariableArg("queryParams", "queryParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (FileParams.Any()) { paramArgList.Add(GetVariableArg("fileParams", "fileParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (FormParams.Any()) { paramArgList.Add(GetVariableArg("formParams", "formParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (BodyParams.Any(b => b.External != true)) { paramArgList.Add(GetVariableArg("bodyParams", "bodyParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (BodyParams.Any(b => b.External == true && !b.Key.EndsWith("request"))) { paramArgList.Add(GetVariableArg("externalBodyParams", "externalBodyParams")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } if (HasRequest) { paramArgList.Add(GetVariableArg("request", "objectToUnpack")); paramArgList.Add(SyntaxFactory.Token(SyntaxKind.CommaToken)); } paramArgList.Add(GetMemberAccessArg("method", "HttpMethods", HttpMethod)); var statementBody = SyntaxFactory.AwaitExpression( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("Client"), SyntaxFactory.GenericName( SyntaxFactory.Identifier("CallApi")) .WithTypeArgumentList( SyntaxFactory.TypeArgumentList( SyntaxFactory.SingletonSeparatedList <TypeSyntax>( SyntaxFactory.IdentifierName(Returns)))))) .WithArgumentList( SyntaxFactory.ArgumentList( SyntaxFactory.SeparatedList <ArgumentSyntax>( paramArgList.ToArray() )))); if (IsVoidTask) { return(SyntaxFactory.ExpressionStatement(statementBody)); } return(SyntaxFactory.ReturnStatement(statementBody)); }
protected List <StatementSyntax> GetMethodBodyParams(bool ignoreQuery = false) { var methodBody = new List <StatementSyntax>(); if (PathParams.Any()) { var pathDeclaration = new DictionaryParamaterLocalDeclarationSyntax { Name = "pathParams", MyParams = PathParams, }.GetSyntax(); methodBody.Add(pathDeclaration); } if (QueryParams.Any() && !ignoreQuery) { var queryParamDeclaration = new DictionaryParamaterLocalDeclarationSyntax { Name = "queryParams", MyParams = QueryParams, }.GetSyntax(); methodBody.Add(queryParamDeclaration); } if (FileParams.Any()) { var fileParamDeclaration = new DictionaryParamaterLocalDeclarationSyntax { Name = "fileParams", MyParams = FileParams, VarType = "Stream", }.GetSyntax(); methodBody.Add(fileParamDeclaration); } if (FormParams.Any()) { var formParamDeclaration = new DictionaryParamaterLocalDeclarationSyntax { Name = "formParams", MyParams = FormParams, }.GetSyntax(); methodBody.Add(formParamDeclaration); } if (BodyParams.Any(b => b.External != true)) { var bodyParamDeclaration = new BodyParameterContainer { Name = "bodyParams", BodyType = UseAnnonBody ? "Annonymous" : Returns, BodyParams = BodyParams.Where(b => b.External != true && !b.Key.EndsWith("request")).ToList(), }.GetSyntax(); methodBody.Add(bodyParamDeclaration); } // add external body params if (BodyParams.Any(b => b.External == true && !b.Key.EndsWith("request"))) { var bodyParamDeclaration = new BodyParameterContainer { Name = "externalBodyParams", BodyType = "Annonymous", BodyParams = BodyParams.Where(b => b.External == true && !b.Key.EndsWith("request")).ToList(), }.GetSyntax(); methodBody.Add(bodyParamDeclaration); } return(methodBody); }
public GetCountryRequest(RESTHeaders headers, PathParams pathParameters) : base(headers, RestSharp.Method.GET, pathParameters, null, null) { }
public static void Run() { var compiler = new HandlerCompiler(); compiler.Register <Object1>(new Object1());//Singleton compiler.Register <Object2>(() => new Object2()); compiler.Register <IHttp2Pusher>(req => req.Pusher()); compiler.RegisterAsync <AsyncObject>(async(req) => { await Task.Delay(1000); return(new AsyncObject()); }); //泛型 //Generic compiler.Register((type, req) => { if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(GenericObject <>)) { return(null); } var ctor = type.GetConstructor(Type.EmptyTypes); return(Expression.New(ctor)); }); compiler.RegisterParameterAsync <string>(p => p.Name == "test", async(req) => { await Task.CompletedTask; return("this is string1"); }); compiler.RegisterProperty <string>(p => p.Name == "TestString", _ => "this is string2"); //compiler.RegisterParameter(); //compiler.RegisterProperty(); compiler.RegisterReturn <string>((value, req, resp) => { resp.Headers.Add(HttpHeaders.ContentType, "text/plain"); resp.Content = StringContent.Create(value); }); compiler.RegisterReturnAsync <byte[]>(async(value, req, resp) => { await Task.CompletedTask; resp.Headers[HttpHeaders.ContentType] = "application/octet-stream"; resp.Content = MemoryContent.Create(value); }); var h1 = compiler.Compile(typeof(TestService).GetMethod("Test1")); var pathParams1 = new PathParams() { { "pathParam1", "ZhangHe" }, { "pathParam2", "9999" } }; var req1 = new HttpRequest().PathParams(pathParams1); var resp1 = h1.HandleAsync(req1).Result; Console.WriteLine(); Console.WriteLine(); var h2 = compiler.Compile(typeof(TestService).GetMethod("Test2")); var resp2 = h2.HandleAsync(new HttpRequest()).Result; Console.WriteLine($"Content:{resp2.Content.ReadStringAsync().Result}"); Console.WriteLine(); Console.WriteLine(); var h3 = compiler.Compile(typeof(TestService).GetMethod("Test3")); var resp3 = h3.HandleAsync(new HttpRequest()).Result; Console.WriteLine($"Content:{resp3.Content.ReadStringAsync().Result}"); Console.WriteLine(); Console.WriteLine(); var h4 = compiler.Compile(typeof(TestService).GetMethod("Test4")); var resp4 = h4.HandleAsync(new HttpRequest()).Result; Console.WriteLine($"Content:{resp4.Content.ReadStringAsync().Result}"); Console.WriteLine(); Console.WriteLine(); var h5 = compiler.Compile(typeof(TestService2).GetMethod("Test")); var resp5 = h1.HandleAsync(new HttpRequest()).Result; foreach (var item in resp5.Headers) { Console.WriteLine($"{item.Key}={item.Value}"); } //------------------------------------------------------------------------ var compiler1 = new HandlerCompiler(); QueryParamAttribute.Register(compiler1); QueryParamsAttribute.Register(compiler1); QueryAndFormAttribute.Register(compiler1); Console.WriteLine(); Console.WriteLine(); var h6 = compiler1.Compile(typeof(TestService).GetMethod("Test5")); var queryParams6 = new QueryParams() { { "Name", "ZhangSan" }, { "Age", "100" } }; var req6 = new HttpRequest().QueryParams(queryParams6); var resp6 = h6.HandleAsync(req6).Result; Console.WriteLine(); Console.WriteLine(); var h7 = compiler1.Compile(typeof(TestService).GetMethod("Test6")); var queryParam7 = new QueryParams() { { "Name", "ZhangSan" } }; var formParams7 = new FormParams() { { "Age", "100" } }; var req7 = new HttpRequest().QueryParams(queryParam7).FormParams(formParams7); var resp7 = h7.HandleAsync(req7).Result; }