C#页面间拼接方式数据传递-含特殊字符(记录篇)

本文介绍了在JavaScript中用于URL编码的`encodeURI()`和`encodeURIComponent()`函数,详细阐述了它们的区别和使用场景。通过示例展示了如何在C#页面间通过编码特殊字符来传递数据,以及在接收端如何解码并使用`decodeURIComponent()`来获取原始信息。此外,还提及了通过Ajax将编码后的参数传递给后台,并进行数据库查询的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先了解一下js两个常用编码函数

1、encodeURI()

它着眼于对整个URL进行编码,因此除了常见的符号以外,对其他一些在网址中有特殊含义的符号“; / ? : @ & = + $ , #”,也不进行编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。

它对应的解码函数是decodeURI()。

需要注意的是,它不对单引号'编码。

2、encodeURIComponent()

最后一个Javascript编码函数是encodeURIComponent()。与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。

因此,“; / ? : @ & = + $ , #”,这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码。至于具体的编码方法,两者是一样。

它对应的解码函数是decodeURIComponent()。

encodeURIComponent()相比encodeURI()要更加彻底。

例子:有个参数dName的值含特殊字符  ---- 测试(1#、2#、3#、F区域)

用js在div上添加一个链接

var htmlString = '<a href="testPage.aspx?dName='+encodeURIComponent(obj[i].deptName)+'" class="item-link"></a>';

$("#div").html(htmlString);

然后点击链接,跳转到下一个aspx页面,获取该参数

$(function(){
  var dName = decodeURIComponent(GetQueryString("dName"));

  console.log("dName="+dName);

 queryData(dName);

});

接着通过Ajax将该参数传入后台查询数据库信息

function queryData(dName){

$.ajax({
       url:"function.ashx?fun=beginCheck&dName="+encodeURIComponent(dName),
       type: "POST",
       dataType: 'text',
       success: function (response) { 
           var obj=eval('('+response+')');
           //拿到返回数据展示
       }
   });

}

接收参数查询数据库

string dName = HttpUtility.UrlDecode(Request["dName"].ToString());
string dList = "";
            DataTable dt1 = new DataTable();
            SqlDataAdapter sda = new SqlDataAdapter("SELECT top 10 * FROM T_ORG_DNAME WHERE F_DNAME LIKE '%" + dName + "%'", conn);
            sda.Fill(dt1);
            dList = JsonConvert.SerializeObject(dt1, new DataTableConverter());  //结果直接转json
            string res = "{'state':'100','data':" + dList + "}";
            sda.Dispose();

            if (conn.State == ConnectionState.Open) { conn.Close(); conn.Dispose(); }
            Response.Write(res); Response.End();

关于如何用ashx访问数据库看文章https://blog.youkuaiyun.com/nzzl54/article/details/85052908,如果已经掌握数据库配置就不用看了

<think>我们通常使用HttpClient类来调用API。为了标准化和复用,我们可以创建一个API调用方法类,用于处理GET、POST等请求,并支持自定义请求头、超时设置等。 以下是一个标准的API调用方法类,包括使用HttpClient发送请求,自己拼接JSON字符串,并处理响应。 注意:在实际使用中,我们通常会使用Newtonsoft.Json或System.Text.Json来序列化和反序列化对象,但这里按照要求自己拼接JSON字符串。 我们将创建以下内容: 1. 一个HttpClientHelper类,封装常用的HTTP方法(GET, POST, PUT, DELETE等)。 2. 使用StringBuilder或直接字符串拼接来构建JSON字符串(仅用于演示,实际开发建议使用JSON库)。 3. 处理异常和错误响应。 由于自己拼接JSON容易出错,所以这里只适用于简单的JSON结构。复杂的JSON结构建议使用JSON库。 下面是一个示例代码:</think>### C# API 调用标准方法类(JSON 手动拼接方案) 以下是完整的 API 调用工具类实现,支持 GET/POST/PUT/DELETE 方法,包手动 JSON 拼接、错误处理和重试机制: ```csharp using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; public class ApiClient { private readonly string _baseUrl; private readonly HttpClient _httpClient; private readonly int _maxRetries; private readonly int _retryDelayMs; /// <summary> /// API 客户端构造函数 /// </summary> /// <param name="baseUrl">API 基础地址</param> /// <param name="timeoutSeconds">超时时(秒)</param> /// <param name="maxRetries">最大重试次数</param> /// <param name="retryDelayMs">重试延迟(毫秒)</param> public ApiClient(string baseUrl, int timeoutSeconds = 30, int maxRetries = 3, int retryDelayMs = 1000) { if (string.IsNullOrWhiteSpace(baseUrl)) throw new ArgumentException("API 基础地址不能为空", nameof(baseUrl)); _baseUrl = baseUrl.TrimEnd('/'); _maxRetries = maxRetries; _retryDelayMs = retryDelayMs; // 配置 HttpClient _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(timeoutSeconds) }; // 设置默认请求头 _httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); _httpClient.DefaultRequestHeaders.Add("User-Agent", "ApiClient/1.0"); } /// <summary> /// 添加全局请求头 /// </summary> public void AddDefaultHeader(string name, string value) { if (_httpClient.DefaultRequestHeaders.Contains(name)) { _httpClient.DefaultRequestHeaders.Remove(name); } _httpClient.DefaultRequestHeaders.Add(name, value); } /// <summary> /// 执行 GET 请求 /// </summary> public async Task<string> GetAsync(string endpoint, Dictionary<string, string> queryParams = null) { var url = BuildUrl(endpoint, queryParams); return await ExecuteWithRetry(async () => { using (var response = await _httpClient.GetAsync(url)) { return await HandleResponse(response); } }); } /// <summary> /// 执行 POST 请求(手动拼接 JSON) /// </summary> public async Task<string> PostAsync(string endpoint, Dictionary<string, object> data) { var url = BuildUrl(endpoint); var json = BuildJson(data); var content = new StringContent(json, Encoding.UTF8, "application/json"); return await ExecuteWithRetry(async () => { using (var response = await _httpClient.PostAsync(url, content)) { return await HandleResponse(response); } }); } /// <summary> /// 执行 PUT 请求(手动拼接 JSON) /// </summary> public async Task<string> PutAsync(string endpoint, Dictionary<string, object> data) { var url = BuildUrl(endpoint); var json = BuildJson(data); var content = new StringContent(json, Encoding.UTF8, "application/json"); return await ExecuteWithRetry(async () => { using (var response = await _httpClient.PutAsync(url, content)) { return await HandleResponse(response); } }); } /// <summary> /// 执行 DELETE 请求 /// </summary> public async Task<string> DeleteAsync(string endpoint) { var url = BuildUrl(endpoint); return await ExecuteWithRetry(async () => { using (var response = await _httpClient.DeleteAsync(url)) { return await HandleResponse(response); } }); } #region 辅助方法 // 构建完整 URL private string BuildUrl(string endpoint, Dictionary<string, string> queryParams = null) { var url = $"{_baseUrl}/{endpoint.TrimStart('/')}"; if (queryParams != null && queryParams.Count > 0) { var queryString = new StringBuilder("?"); foreach (var param in queryParams) { queryString.Append($"{Uri.EscapeDataString(param.Key)}={Uri.EscapeDataString(param.Value)}&"); } url += queryString.ToString().TrimEnd('&'); } return url; } // 手动构建 JSON 字符串 private string BuildJson(Dictionary<string, object> data) { if (data == null || data.Count == 0) return "{}"; var json = new StringBuilder("{"); bool first = true; foreach (var item in data) { if (!first) json.Append(","); first = false; json.Append($"\"{EscapeJsonString(item.Key)}\":"); if (item.Value == null) { json.Append("null"); } else if (item.Value is string strValue) { json.Append($"\"{EscapeJsonString(strValue)}\""); } else if (item.Value is bool boolValue) { json.Append(boolValue ? "true" : "false"); } else if (IsNumericType(item.Value)) { json.Append(item.Value.ToString()); } else if (item.Value is Dictionary<string, object> nestedDict) { json.Append(BuildJson(nestedDict)); } else { // 复杂类型使用 JSON 字符串表示 json.Append($"\"{EscapeJsonString(item.Value.ToString())}\""); } } json.Append("}"); return json.ToString(); } // 处理 JSON 字符串转义 private string EscapeJsonString(string value) { return value .Replace("\\", "\\\\") .Replace("\"", "\\\"") .Replace("\b", "\\b") .Replace("\f", "\\f") .Replace("\n", "\\n") .Replace("\r", "\\r") .Replace("\t", "\\t"); } // 检查是否为数值类型 private bool IsNumericType(object value) { return value is int || value is long || value is float || value is double || value is decimal || value is short || value is byte || value is sbyte || value is ushort || value is uint || value is ulong; } // 处理响应 private async Task<string> HandleResponse(HttpResponseMessage response) { var content = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return content; } throw new ApiException { StatusCode = (int)response.StatusCode, Content = content, ReasonPhrase = response.ReasonPhrase }; } // 带重试的执行方法 private async Task<string> ExecuteWithRetry(Func<Task<string>> action) { int attempt = 0; List<Exception> exceptions = new List<Exception>(); while (attempt <= _maxRetries) { try { return await action(); } catch (Exception ex) { exceptions.Add(ex); // 非重试异常直接抛出 if (!IsRetryableException(ex)) throw; // 达到最大重试次数 if (attempt >= _maxRetries) break; // 等待后重试 await Task.Delay(_retryDelayMs * (int)Math.Pow(2, attempt)); attempt++; } } throw new AggregateException("API 调用失败,重试次数已用完", exceptions); } // 检查是否为可重试的异常 private bool IsRetryableException(Exception ex) { return ex is TaskCanceledException || ex is TimeoutException || (ex is HttpRequestException httpEx && (httpEx.InnerException is WebException webEx && (webEx.Status == WebExceptionStatus.ConnectFailure || webEx.Status == WebExceptionStatus.Timeout))); } #endregion } /// <summary> /// 自定义 API 异常类 /// </summary> public class ApiException : Exception { public int StatusCode { get; set; } public string Content { get; set; } public string ReasonPhrase { get; set; } public override string Message => $"API 请求失败: {StatusCode} {ReasonPhrase}. 响应内容: {Content}"; } ``` ### 使用示例 ```csharp class Program { static async Task Main(string[] args) { try { // 创建 API 客户端 var apiClient = new ApiClient("https://api.example.com", timeoutSeconds: 15); // 添加认证头 apiClient.AddDefaultHeader("Authorization", "Bearer your_token_here"); // 构建请求数据(手动拼接 JSON) var data = new Dictionary<string, object> { ["userId"] = 12345, ["name"] = "John Doe", ["email"] = "john.doe@example.com", ["isActive"] = true, ["preferences"] = new Dictionary<string, object> { ["theme"] = "dark", ["notifications"] = true } }; // 发送 POST 请求 string response = await apiClient.PostAsync("users/create", data); Console.WriteLine($"创建用户成功: {response}"); // 发送 GET 请求 response = await apiClient.GetAsync("users/12345"); Console.WriteLine($"用户信息: {response}"); // 发送 PUT 请求 data["name"] = "Johnathan Doe"; response = await apiClient.PutAsync("users/12345", data); Console.WriteLine($"更新用户成功: {response}"); // 发送 DELETE 请求 response = await apiClient.DeleteAsync("users/12345"); Console.WriteLine($"删除用户成功: {response}"); } catch (ApiException apiEx) { Console.WriteLine($"API 错误: {apiEx.Message}"); } catch (Exception ex) { Console.WriteLine($"发生错误: {ex.Message}"); } } } ``` ### 关键功能说明 1. **手动 JSON 拼接** - `BuildJson` 方法将字典转换为 JSON 字符串 - 支持嵌套对象、基本数据类型和特殊字符转义 ```csharp private string BuildJson(Dictionary<string, object> data) { // 构建 JSON 字符串逻辑 } ``` 2. **请求重试机制** - 自动重试网络故障和超时错误 - 指数退避策略:每次重试等待时翻倍 ```csharp private async Task<string> ExecuteWithRetry(Func<Task<string>> action) { // 重试逻辑 } ``` 3. **自定义异常处理** - `ApiException` 包完整的错误信息 ```csharp public class ApiException : Exception { public int StatusCode { get; set; } public string Content { get; set; } // ... } ``` 4. **安全传输** - 自动处理 URL 编码和参数转义 ```csharp queryString.Append($"{Uri.EscapeDataString(param.Key)}={Uri.EscapeDataString(param.Value)}&"); ``` 5. **灵活的配置** - 可配置超时时、重试次数和延迟 ```csharp public ApiClient(string baseUrl, int timeoutSeconds = 30, int maxRetries = 3, int retryDelayMs = 1000) ``` ### 最佳实践建议 1. **添加日志记录** ```csharp // 在 ExecuteWithRetry 方法中添加 _logger.LogInformation($"尝试 {attempt}/{_maxRetries} 请求: {url}"); ``` 2. **添加性能监控** ```csharp var stopwatch = Stopwatch.StartNew(); try { // 执行请求 } finally { stopwatch.Stop(); _metrics.TrackRequest(stopwatch.ElapsedMilliseconds); } ``` 3. **添加请求签名(安全增强)** ```csharp // 在发送请求前添加签名 string signature = GenerateSignature(json, secretKey); AddDefaultHeader("X-Signature", signature); ``` 4. **添加响应缓存** ```csharp // 在 GetAsync 方法中添加缓存支持 if (_cache.TryGetValue(url, out string cachedResponse)) return cachedResponse; // 执行请求后 _cache.Set(url, response, TimeSpan.FromMinutes(5)); ``` ### 使用场景 1. 需要严格控制 JSON 结构的场景 2. 无法使用 JSON 序列化库的环境 3. 对依赖项有严格限制的项目 4. 需要特殊字符处理的自定义需求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值