解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
11.48 KiB
X
# ApiHttpClient ʹÓÃÊÖ²á ## ¸ÅÊö `ApiHttpClient` ÊÇ NewLife.Core ÌṩµÄ Http Ó¦Óýӿڿͻ§¶Ë£¬ÊǶԶà¸ö·þÎñµØÖ·µÄ°ü×°¡£ËüÔڵײã¹ÜÀí¶à¸ö `HttpClient`£¬ÌṩͳһµÄ¸ºÔؾùºâºÍ¹ÊÕÏ×ªÒÆÄÜÁ¦¡£ ### ºËÐÄÌØÐÔ - **¶àµØÖ·¹ÜÀí**£ºÖ§³ÖÅäÖöà¸ö·þÎñµØÖ·£¬×Ô¶¯½øÐиºÔؾùºâ - **¹ÊÕÏ×ªÒÆ**£º½Úµã²»¿ÉÓÃʱ×Ô¶¯Çл»µ½±¸Óýڵã - **¸ºÔؾùºâ**£ºÖ§³Ö¹ÊÕÏ×ªÒÆ¡¢¼ÓȨÂÖѯ¡¢¾ºËÙµ÷ÓÃÈýÖÖģʽ - **ÁîÅÆ¼øÈ¨**£ºÖ§³Ö Token ºÍ Authentication Á½ÖÖ¼øÈ¨·½Ê½ - **ÏìÓ¦½âÎö**£ºÖ§³Ö×Ô¶¨Òå״̬ÂëºÍÊý¾Ý×Ö¶ÎÃû³Æ£¬ÊÊÅ䲻ͬƽ̨ - **¿ÉÀ©Õ¹ÐÔ**£ºÖ§³Ö×Ô¶¨Òå JsonHost¡¢Filter¡¢Ê¼þµÈ ## ¿ìËÙ¿ªÊ¼ ### »ù´¡Ó÷¨ ```csharp // ´´½¨¿Í»§¶Ë var client = new ApiHttpClient("http://api.example.com"); // GET ÇëÇó var result = await client.GetAsync<UserInfo>("user/info", new { id = 123 }); // POST ÇëÇó var response = await client.PostAsync<ResultModel>("user/create", new { name = "test", age = 18 }); // ͬ²½µ÷Óà var data = client.Get<String>("api/data"); ``` ### ¶àµØÖ·ÅäÖà ```csharp // ¶ººÅ·Ö¸ô¶à¸öµØÖ· var client = new ApiHttpClient("http://api1.example.com,http://api2.example.com,http://api3.example.com"); // »òÕßÊÖ¶¯Ìí¼Ó var client = new ApiHttpClient(); client.Add("primary", "http://api1.example.com"); client.Add("backup", "http://api2.example.com"); ``` ## ¸ºÔؾùºâ ### ÈýÖÖ¸ºÔؾùºâģʽ | ģʽ | ö¾ÙÖµ | ˵Ã÷ | |------|--------|------| | ¹ÊÕÏ×ªÒÆ | `LoadBalanceMode.Failover` | ÓÅÏÈʹÓÃÖ÷½Úµã£¬Ê§°Üʱ×Ô¶¯Çл»µ½±¸Óýڵ㣬¹ýÒ»¶Îʱ¼ä×Ô¶¯ÇÐ»Ø | | ¼ÓȨÂÖѯ | `LoadBalanceMode.RoundRobin` | °´È¨ÖØ·ÖÅäÇëÇóµ½¶à¸ö½Úµã£¬×Ô¶¯ÆÁ±Î²»¿ÉÓýڵã | | ¾ºËÙµ÷Óà | `LoadBalanceMode.Race` | ²¢ÐÐÇëÇó¶à¸ö½Úµã£¬È¡×î¿ìÏìÓ¦£¬È¡ÏûÆäËüÇëÇó | ### ¹ÊÕÏ×ªÒÆÄ£Ê½£¨Ä¬ÈÏ£© ```csharp var client = new ApiHttpClient("http://primary.example.com,http://backup.example.com") { LoadBalanceMode = LoadBalanceMode.Failover, // ĬÈÏÖµ ShieldingTime = 60 // ²»¿ÉÓýڵãÆÁ±Î60Ãë }; // Õý³£Çé¿öʹÓà primary£¬primary ²»¿ÉÓÃʱ×Ô¶¯Çл»µ½ backup // 60Ãëºó»á³¢ÊÔÇÐ»Ø primary var result = await client.GetAsync<Object>("api/data"); ``` ### ¼ÓȨÂÖѯģʽ ```csharp // ¸ñʽ£ºname=weight*url var client = new ApiHttpClient("master=3*http://api1.example.com,slave=7*http://api2.example.com") { LoadBalanceMode = LoadBalanceMode.RoundRobin }; // master È¨ÖØ3£¬slave È¨ÖØ7 // 10´ÎÇëÇóÖУ¬master Ô¼3´Î£¬slave Ô¼7´Î ``` ### ¾ºËÙµ÷ÓÃģʽ ```csharp var client = new ApiHttpClient("http://api1.example.com,http://api2.example.com,http://api3.example.com") { LoadBalanceMode = LoadBalanceMode.Race }; // ²¢ÐÐÇëÇóËùÓнڵ㣬·µ»Ø×î¿ìµÄÏìÓ¦ // ÊÊÓÃÓÚ¶ÔÏìӦʱ¼äÒªÇ󼫸ߵij¡¾° ``` ## Éí·ÝÑéÖ¤ ### Token ÁîÅÆ ```csharp var client = new ApiHttpClient("http://api.example.com") { Token = "your_access_token" }; // ÇëÇóÍ·×Ô¶¯Ìí¼Ó£ºAuthorization: Bearer your_access_token ``` ### Authentication ÊôÐÔ ```csharp var client = new ApiHttpClient("http://api.example.com") { Authentication = new AuthenticationHeaderValue("Bearer", "your_token") }; // »òÕßʹÓà Basic ÈÏÖ¤ client.Authentication = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("user:password"))); ``` ### ·þÎñ½Úµã¶ÀÁ¢ Token ```csharp // ÔÚ URL ÖÐÖ¸¶¨ Token var client = new ApiHttpClient(); client.Add("service1", "http://api1.example.com#token=token_for_api1"); client.Add("service2", "http://api2.example.com#token=token_for_api2"); ``` > **ÓÅÏȼ¶**£º`Token` ÊôÐÔÓÅÏÈÓÚ `Authentication` ÊôÐÔ¡£ ## ÏìÓ¦½âÎö ### ±ê×¼ÏìÓ¦¸ñʽ ĬÈÏÖ§³ÖÒÔÏÂÏìÓ¦¸ñʽ£º ```json { "code": 0, "message": "success", "data": { ... } } ``` ### ×Ô¶¨Òå×Ö¶ÎÃû³Æ ```csharp var client = new ApiHttpClient("http://api.example.com") { CodeName = "status", // ״̬Âë×Ö¶ÎÃû£¬Ä¬ÈÏ×Ô¶¯Ê¶±ð code/errcode/status DataName = "result" // Êý¾Ý×Ö¶ÎÃû£¬Ä¬ÈÏ data }; // ÊÊÅäÏìÓ¦¸ñʽ£º{"status": 0, "result": {...}} ``` ### Ö§³ÖµÄ״̬Âë×Ö¶Î - `code` - `errcode` - `status` ### Ö§³ÖµÄÏûÏ¢×Ö¶Î - `message` - `msg` - `errmsg` - `error` ## Http ·½·¨ ```csharp var client = new ApiHttpClient("http://api.example.com"); // GET - ²ÎÊýÆ´½Óµ½ URL var result = await client.GetAsync<T>("api/users", new { page = 1, size = 10 }); // POST - ²ÎÊý JSON ÐòÁл¯µ½ Body var result = await client.PostAsync<T>("api/users", new { name = "test" }); // PUT var result = await client.PutAsync<T>("api/users/1", new { name = "updated" }); // PATCH var result = await client.PatchAsync<T>("api/users/1", new { name = "patched" }); // DELETE var result = await client.DeleteAsync<T>("api/users/1"); // ͨÓõ÷Óà var result = await client.InvokeAsync<T>(HttpMethod.Post, "api/action", args); ``` ## ¸ß¼¶ÅäÖà ### ³¬Ê±ÉèÖà ```csharp var client = new ApiHttpClient("http://api.example.com") { Timeout = 30_000 // 30Ã룬ĬÈÏ15Ãë }; ``` ### ´úÀíÉèÖà ```csharp var client = new ApiHttpClient("http://api.example.com") { UseProxy = true // ʹÓÃϵͳ´úÀí£¬Ä¬ÈÏfalse }; ``` ### SSLÖ¤ÊéÑéÖ¤ ```csharp var client = new ApiHttpClient("https://api.example.com") { CertificateValidation = false // ²»ÑéÖ¤Ö¤Ê飬ĬÈÏfalse }; ``` ### ×Ô¶¨Òå UserAgent ```csharp var client = new ApiHttpClient("http://api.example.com") { DefaultUserAgent = "MyApp/1.0" }; ``` ### ×Ô¶¨Òå Json ÐòÁл¯ ```csharp var client = new ApiHttpClient("http://api.example.com") { JsonHost = new FastJson() // ×Ô¶¨Òå Json ÐòÁл¯Æ÷ }; ``` ## ʼþÓë¹ýÂËÆ÷ ### OnRequest ʼþ ```csharp var client = new ApiHttpClient("http://api.example.com"); client.OnRequest += (sender, e) => { // Ìí¼Ó×Ô¶¨ÒåÇëÇóÍ· e.Request.Headers.Add("X-Request-Id", Guid.NewGuid().ToString()); e.Request.Headers.Add("X-Timestamp", DateTime.Now.Ticks.ToString()); }; ``` ### OnCreateClient ʼþ ```csharp client.OnCreateClient += (sender, e) => { // ÅäÖà HttpClient e.Client.DefaultRequestHeaders.Add("X-App-Version", "1.0.0"); }; ``` ### Http ¹ýÂËÆ÷ ```csharp // ʹÓÃÄÚÖõÄÁîÅÆ¹ýÂËÆ÷ var filter = new TokenHttpFilter { UserName = "app_id", Password = "app_secret" }; var client = new ApiHttpClient("http://api.example.com") { Filter = filter }; // ¹ýÂËÆ÷»á×Ô¶¯´¦ÀíÁîÅÆµÄ»ñÈ¡ºÍˢР``` ### ×Ô¶¨Òå¹ýÂËÆ÷ ```csharp public class MyHttpFilter : IHttpFilter { public Task OnRequest(HttpClient client, HttpRequestMessage request, Object? state, CancellationToken cancellationToken) { // ÇëÇóǰ´¦Àí request.Headers.Add("X-Custom", "value"); return Task.CompletedTask; } public Task OnResponse(HttpClient client, HttpResponseMessage response, Object? state, CancellationToken cancellationToken) { // ÏìÓ¦ºó´¦Àí return Task.CompletedTask; } public Task OnError(HttpClient client, Exception ex, Object? state, CancellationToken cancellationToken) { // ´íÎó´¦Àí return Task.CompletedTask; } } ``` ## ·þÎñ״̬¼à¿Ø ### ²é¿´µ±Ç°·þÎñ ```csharp var client = new ApiHttpClient("http://api1.example.com,http://api2.example.com"); // µ±Ç°ÕýÔÚʹÓõķþÎñ var current = client.Current; Console.WriteLine($"µ±Ç°·þÎñ£º{current?.Name} - {current?.Address}"); // µ±Ç°·þÎñÃû³Æ Console.WriteLine($"·þÎñÔ´£º{client.Source}"); ``` ### ²é¿´·þÎñÁбí״̬ ```csharp foreach (var svc in client.Services) { Console.WriteLine($"·þÎñ£º{svc.Name}"); Console.WriteLine($" µØÖ·£º{svc.Address}"); Console.WriteLine($" È¨ÖØ£º{svc.Weight}"); Console.WriteLine($" µ÷ÓôÎÊý£º{svc.Times}"); Console.WriteLine($" ´íÎó´ÎÊý£º{svc.Errors}"); Console.WriteLine($" ÊÇ·ñ¿ÉÓãº{svc.IsAvailable()}"); Console.WriteLine($" Ï´οÉÓÃʱ¼ä£º{svc.NextTime}"); } ``` ## Á´Â·×·×Ù ```csharp var client = new ApiHttpClient("http://api.example.com") { Tracer = DefaultTracer.Instance, // ÉèÖÃÁ´Â·×·×ÙÆ÷ SlowTrace = 5_000 // ³¬¹ý5Ãë¼Ç¼Âýµ÷ÓÃÈÕÖ¾ }; ``` ## ÒÀÀµ×¢Èë ### ASP.NET Core ¼¯³É ```csharp // ×¢²á·þÎñ services.AddSingleton<IApiClient>(sp => { var config = sp.GetRequiredService<IConfiguration>(); var client = new ApiHttpClient(config["ApiServer:Urls"]) { Timeout = config.GetValue<Int32>("ApiServer:Timeout"), ServiceProvider = sp }; return client; }); // ʹÓÃÅäÖÃÖÐÐÄ services.AddSingleton<IApiClient>(sp => { return new ApiHttpClient(sp, "ApiServerConfig"); // ´ÓÅäÖÃÖÐÐĶÁÈ¡ }); ``` ### IConfigMapping ½Ó¿Ú ```csharp // ApiHttpClient ʵÏÖÁË IConfigMapping ½Ó¿Ú // ¿ÉÒÔͨ¹ýÅäÖÃÖÐÐĶ¯Ì¬¸üзþÎñµØÖ· var configProvider = services.GetRequiredService<IConfigProvider>(); configProvider.Bind(client, true, "ApiServer"); // °ó¶¨ÅäÖÃ½Ú ``` ## ÎļþÏÂÔØ ```csharp var client = new ApiHttpClient("http://download.example.com"); // ÏÂÔØÎļþ²¢Ð£Ñé¹þÏ£ await client.DownloadFileAsync( requestUri: "files/package.zip", fileName: "D:/downloads/package.zip", expectedHash: "sha256:abc123...", // ¿ÉÑ¡£¬Ö§³Ö md5/sha1/sha256/sha512 cancellationToken: default ); ``` ## Òì³£´¦Àí ### ApiException ```csharp try { var result = await client.GetAsync<Object>("api/data"); } catch (ApiException ex) { // ÒµÎñÒì³££¨·þÎñ¶Ë·µ»ØµÄ´íÎóÂ룩 Console.WriteLine($"´íÎóÂ룺{ex.Code}"); Console.WriteLine($"´íÎóÐÅÏ¢£º{ex.Message}"); } catch (HttpRequestException ex) { // ÍøÂçÒì³£ Console.WriteLine($"ÍøÂç´íÎó£º{ex.Message}"); } ``` ## ×î¼Ñʵ¼ù ### 1. ¸´Óÿͻ§¶ËʵÀý ```csharp // ? ÍÆ¼ö£º×÷Ϊµ¥ÀýʹÓà public class MyService { private static readonly ApiHttpClient _client = new("http://api.example.com"); public Task<T> GetDataAsync<T>() => _client.GetAsync<T>("api/data"); } // ? ±ÜÃ⣺ÿ´ÎÇëÇó´´½¨ÐÂʵÀý public async Task<T> GetDataAsync<T>() { using var client = new ApiHttpClient("http://api.example.com"); // ²»ÍƼö return await client.GetAsync<T>("api/data"); } ``` ### 2. ºÏÀíÉèÖó¬Ê± ```csharp var client = new ApiHttpClient("http://api.example.com") { Timeout = 10_000, // ¸ù¾Ý½Ó¿ÚÌØÐÔÉèÖúÏÀí³¬Ê± SlowTrace = 3_000 // Âýµ÷ÓÃãÐÖµ }; ``` ### 3. ÅäÖùÊÕÏ×ªÒÆ ```csharp var client = new ApiHttpClient("http://primary.example.com,http://backup.example.com") { ShieldingTime = 30, // ¹ÊÕϽڵãÆÁ±Î30Ãë LoadBalanceMode = LoadBalanceMode.Failover }; ``` ### 4. ʹÓÃÁ´Â·×·×Ù ```csharp var client = new ApiHttpClient("http://api.example.com") { Tracer = DefaultTracer.Instance, Log = XTrace.Log // ¿ªÆôÈÕÖ¾ }; ``` ## ÍêÕûʾÀý ```csharp using NewLife.Log; using NewLife.Remoting; // ´´½¨¿Í»§¶Ë var client = new ApiHttpClient("master=3*http://api1.example.com,slave=7*http://api2.example.com") { Token = "your_access_token", Timeout = 15_000, ShieldingTime = 60, LoadBalanceMode = LoadBalanceMode.RoundRobin, CodeName = "code", DataName = "data", Tracer = DefaultTracer.Instance, Log = XTrace.Log }; // Ìí¼ÓÇëÇóÀ¹½Ø client.OnRequest += (sender, e) => { e.Request.Headers.Add("X-Request-Id", Guid.NewGuid().ToString()); }; try { // ·¢ÆðÇëÇó var users = await client.GetAsync<List<UserInfo>>("api/users", new { page = 1, size = 10 }); foreach (var user in users) { Console.WriteLine($"Óû§£º{user.Name}"); } // ²é¿´µ±Ç°Ê¹ÓõķþÎñ Console.WriteLine($"ÇëÇó·þÎñ£º{client.Source} - {client.Current?.Address}"); } catch (ApiException ex) { Console.WriteLine($"ÒµÎñ´íÎó [{ex.Code}]£º{ex.Message}"); } catch (HttpRequestException ex) { Console.WriteLine($"ÍøÂç´íÎó£º{ex.Message}"); } ``` ## Ïà¹ØÀàÐÍ | ÀàÐÍ | ˵Ã÷ | |------|------| | `ApiHttpClient` | Http Ó¦Óýӿڿͻ§¶Ë | | `ServiceEndpoint` | ·þÎñ¶Ëµã£¬°üº¬µØÖ·¡¢È¨ÖØ¡¢×´Ì¬µÈÐÅÏ¢ | | `ILoadBalancer` | ¸ºÔؾùºâÆ÷½Ó¿Ú | | `FailoverLoadBalancer` | ¹ÊÕÏ×ªÒÆ¸ºÔؾùºâÆ÷ | | `WeightedRoundRobinLoadBalancer` | ¼ÓȨÂÖѯ¸ºÔؾùºâÆ÷ | | `RaceLoadBalancer` | ¾ºËÙ¸ºÔؾùºâÆ÷ | | `IHttpFilter` | Http ¹ýÂËÆ÷½Ó¿Ú | | `TokenHttpFilter` | ÁîÅÆ¹ýÂËÆ÷ | | `ApiException` | Api ÒµÎñÒì³£ | ## °æ±¾ÀúÊ· - **v11.0+**£ºÒýÈë¸ºÔØ¾ùºâģʽö¾Ù£¬Ö§³Ö¾ºËÙµ÷Óà - **v10.0+**£ºÖ§³Ö×Ô¶¨Òå CodeName/DataName - **v9.0+**£ºÖ§³ÖÁ´Â·×·×Ù