C#调用Bodet KELIO SOAP服务时的身份验证与连接问题求助
C#调用Bodet KELIO SOAP服务时的身份验证与连接问题求助
看起来你遇到的核心问题是身份验证失败,而且有几个明显的小错误导致了403错误,我帮你一步步梳理解决方法:
首先,最容易忽略的错误:密码写错了!
你提到SOAPUI测试用的密码是ws-sandbox,但你的代码里不管是WCF客户端还是HttpClient,都写成了api-sandbox——这直接导致Basic认证通不过,服务器返回403是必然的!先把这个错误修正,再看其他问题。
针对WCF客户端(VS生成的代码)的修复
除了修正密码,还要确保WCF的绑定配置正确启用Basic认证,因为默认生成的绑定可能没有开启安全设置。
修改后的代码:
void SalarieTEst() { Salaries.LightEmployeeServicePortTypeClient client = new Salaries.LightEmployeeServicePortTypeClient(); // 修正密码:把api-sandbox改成ws-sandbox client.ClientCredentials.UserName.UserName = "api-ws"; client.ClientCredentials.UserName.Password = "ws-sandbox"; // 手动配置绑定的安全模式(如果config里没配置的话) if (client.Endpoint.Binding is BasicHttpBinding basicBinding) { // 因为用的是HTTPS,所以安全模式选Transport basicBinding.Security.Mode = BasicHttpSecurityMode.Transport; // 指定用Basic认证 basicBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; } var toto = client.exportLightEmployees("", ""); }
更推荐的方式:在配置文件里绑定安全设置
你也可以直接在app.config或web.config里配置绑定,这样代码里不用额外写逻辑:
<bindings> <basicHttpBinding> <binding name="LightEmployeeServicePort"> <security mode="Transport"> <transport clientCredentialType="Basic" /> </security> </binding> </basicHttpBinding> </bindings>
针对HttpClient调用的修复
同样先修正密码,还要注意几个SOAP服务的必填项:
修改后的代码:
async Task TestSoap() { var url = @"https://sandbox-ws.kelio.io/open/services/LightEmployeeService"; // 注意:把方法名改成和WCF一致的exportLightEmployees,避免服务端无法识别 var soapEnveloppe = @"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:ech=""http://echange.service.open.bodet.com""> <soapenv:Header/> <soapenv:Body> <ech:exportLightEmployees> <!--Optional:--> <ech:exportFilter> <!--Zero or more repetitions:--> <ech:AskedPopulation> <!--Optional:--> <ech:populationFilter>Kelio Démonstration</ech:populationFilter> <!--Optional:--> <ech:groupFilter>Cadres</ech:groupFilter> <!--Optional:--> <ech:populationMode>0</ech:populationMode> </ech:AskedPopulation> </ech:exportFilter> </ech:exportLightEmployees> </soapenv:Body> </soapenv:Envelope>"; string username = "api-ws"; // 修正密码 string password = "ws-sandbox"; var authToken = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); using (var client = new HttpClient()) { client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authToken); var request = new HttpRequestMessage(HttpMethod.Post, url); request.Content = new StringContent(soapEnveloppe, Encoding.UTF8, "text/xml"); // 必须添加SOAPAction头!绝大多数SOAP服务都要求这个 request.Headers.Add("SOAPAction", "http://echange.service.open.bodet.com/LightEmployeeService/exportLightEmployees"); var response = await client.SendAsync(request); // 强制检查响应状态,方便排查错误 response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(); Console.WriteLine(responseContent); } }
关键注意点:
- SOAPAction头:这个是很多SOAP服务的必填项,缺少的话服务器可能直接返回403或400错误。
- 方法名匹配:你之前的信封里用了
exportLightEmployeesList,但VS生成的方法是exportLightEmployees,必须和服务端暴露的方法名一致。 - 避免重复发送请求:你原来的代码里先创建了
request,然后又调用PostAsync(url, request.Content),这相当于发送了两个不同的请求,应该用SendAsync(request)来发送完整的请求对象。
额外排查技巧
如果还是有问题,建议用Fiddler抓包对比SOAPUI的请求和代码的请求,重点看:
- 请求头里的Authorization是否正确
- 是否包含SOAPAction头
- SOAP信封的内容和命名空间是否一致
- 请求的Content-Type是否为
text/xml
这样就能快速定位到差异点,解决问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

