HttpClient与WCF中#字符传递被截断的问题求助
问题原因
#在URL中是**片段标识符(Fragment Identifier)**的起始标记,即便你手动将其转义为%23,如果客户端构建Uri的方式不当,.NET的Uri类会自动把%23解码回#,导致服务端接收到的URL中包含原始#字符。而WCF的{*id}通配符默认只会捕获#之前的内容作为路径参数,后续部分会被识别为片段而忽略,最终出现截断。
解决方案
方案1:修正客户端URL构建逻辑
核心是确保转义后的%23不会被Uri类自动解码,正确做法是依托Uri类组合路径,而非手动拼接字符串:
修改后的客户端代码:
HttpClientHandler handler = new HttpClientHandler(); handler.UseProxy = false; HttpClient client = new HttpClient(handler); string link = string.Format("https://{0}:{1}/", host, port); System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; client.BaseAddress = new Uri(link); string serviceName = "Service"; string restPart = "rest"; string method = "GetCase"; string valueToSearch = "TEST#12345"; // 对单个路径段进行标准转义 string escapedValue = Uri.EscapeDataString(valueToSearch); // 基于BaseAddress构建完整Uri,保证转义字符不被解码 Uri fullRequestUri = new Uri(client.BaseAddress, $"{serviceName}/{restPart}/{method}/{escapedValue}"); client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await client.GetAsync(fullRequestUri);
此方式构建的Uri会保留%23的转义状态,服务端接收到完整的TEST%2312345后,WCF会自动解码为TEST#12345并传递给id参数。
方案2:改用查询字符串传递参数(兼容性更强)
如果路径参数方式仍有问题,可将参数改为查询字符串形式,这种方式对特殊字符的处理更稳定:
服务端代码修改:
[OperationContract] [WebGet( RequestFormat = WebMessageFormat.Json, UriTemplate = "/GetCase?id={id}" )] string[] GetCase( string id );
客户端代码修改:
// 其他代码保持不变 string valueToSearch = "TEST#12345"; string escapedValue = Uri.EscapeDataString(valueToSearch); // 构建带查询参数的请求Uri Uri fullRequestUri = new Uri(client.BaseAddress, $"{serviceName}/{restPart}/{method}?id={escapedValue}"); var response = await client.GetAsync(fullRequestUri);
查询参数中的转义字符不会被当作片段标识符,服务端能完整获取到TEST#12345。
额外配置验证
若使用路径参数方式,需确保WCF的WebHttpBehavior配置正确,允许通配符参数捕获完整路径段。可在服务配置文件中添加:
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="WebBehavior"> <webHttp helpEnabled="true" automaticFormatSelectionEnabled="false"/> </behavior> </endpointBehaviors> </behaviors> <!-- 其他服务配置 --> </system.serviceModel>
内容的提问来源于stack exchange,提问作者M.Pievani
相关产品推荐
相关产品推荐

