using Apewer; using Apewer.Internals.QrCode; using Apewer.Network; using System; using System.Collections.Generic; using System.Collections.Specialized; namespace Apewer.Web { /// public class ApiClient { private const int DefaultTimeout = 30000; /// public string ApiUrl { get; set; } /// public string Random { get; set; } /// public string Ticket { get; set; } /// public string Session { get; set; } /// public string Page { get; set; } /// public string UserAgent { get; set; } /// public int Timeout { get; set; } = DefaultTimeout; /// public static Result Return(byte[] bytes, Action succeed = null, Action failed = null) { var text = TextUtility.FromBinary(bytes); var json = Json.Parse(text); return Return(json, succeed, failed); } /// 解析响应并返回。 public static Result Return(Json json, Action succeed = null, Action failed = null) { if (json != null && json.Available) { var status = json["status"]; if (status == "ok") { var data = json.GetProperty("data") ?? Json.NewObject(); succeed?.Invoke(data); return new Result(data); } else { var message = json["message"]; return Return(message, failed); } } return Return("响应为空。", failed); } /// 返回错误。 public static Result Return(string error, Action failed = null) { var error2 = error.IsEmpty() ? "未知错误。" : error; failed?.Invoke(error2); return Result.Error(error2); } /// 发起请求。 public Result Send(string url, byte[] body = null, Action succeed = null, Action failed = null, int timeout = DefaultTimeout) { if (url.IsEmpty()) return Return("参数 URL 无效。", failed); var client = new HttpClient(); client.Request.Url = url; if (UserAgent.NotEmpty()) client.Request.UserAgent = UserAgent; if (body == null || body.Length < 1) { client.Request.Method = HttpMethod.GET; } else { client.Request.Method = HttpMethod.POST; client.Request.Data = body; } var ex = client.Send(); return ex == null ? Return(client.Response.Data, succeed, failed) : Return(ex.Message); } private string MergeUrl(string application = null, string function = null, IEnumerable> args = null) { var ts = new TextSet(true); ts["application"] = application; ts["function"] = function; if (Random.NotEmpty()) ts["random"] = Random; if (Page.NotEmpty()) ts["page"] = Random; if (Session.NotEmpty()) ts["session"] = Random; if (Ticket.NotEmpty()) ts["ticket"] = Random; if (args != null) { foreach (var i in args) { if (i.Key.IsEmpty()) continue; if (i.Key == "application") continue; if (i.Key == "function") continue; if (i.Value.IsEmpty()) continue; ts[i.Key] = i.Value; } } var url = TextUtility.AssureEnds(ApiUrl, true, "/"); var query = HttpClient.MergeForm(ts); if (query.NotEmpty()) url = url.Append("?", query); return url; } private Json MergePost(string application = null, string function = null, Json data = null) { var json = Json.NewObject(); json.SetProperty("application", application); json.SetProperty("function", function); json.SetProperty("random", Random); json.SetProperty("page", Page); json.SetProperty("session", Session); json.SetProperty("ticket", Ticket); json.SetProperty("data", data); return json; } // GET /// public Result Get(string application = null, string function = null, IEnumerable> args = null, Action succeed = null, Action failed = null) { var url = MergeUrl(application, function, args); return Send(url, null, succeed, failed, Timeout); } /// public Result Get(string application = null, string function = null, TextSet args = null, Action succeed = null, Action failed = null) { var url = MergeUrl(application, function, args == null ? null : args.Origin); return Send(url, null, succeed, failed, Timeout); } // POST /// public Result Post(string application = null, string function = null, IEnumerable> args = null, byte[] body = null, Action succeed = null, Action failed = null) { var url = MergeUrl(application, function, args); return Send(url, body, succeed, failed, Timeout); } /// public Result Post(string application = null, string function = null, TextSet args = null, byte[] body = null, Action succeed = null, Action failed = null) { var url = MergeUrl(application, function, args == null ? null : args.Origin); return Send(url, body, succeed, failed, Timeout); } /// public Result Post(string application = null, string function = null, Json data = null, Action succeed = null, Action failed = null) { var json = MergePost(application, function, data); var bytes = json.ToString().GetBytes(); return Send(ApiUrl, bytes, succeed, failed, Timeout); } } }