Stu*_*rla 23 c# wcf soap .net-core
我正在将一个.net 4.6.2代码移植到一个调用SOAP服务的.net Core项目中.在新代码中我使用C#(由于一些配置原因,我现在还不记得为什么).
但我得到以下例外.
收到对https://someurl.com/ws/Thing.pub.ws:Something的HTTP响应时发生错误.这可能是由于服务端点绑定不使用HTTP协议.这也可能是由于服务器中止HTTP请求上下文(可能是由于服务关闭).请参阅服务器日志以获取更多详
投掷它的代码是
try
{
var binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
var endpoint = new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService"));
var thing= new TheEndpoint.AService_PortTypeClient(binding, endpoint);
thing.ClientCredentials.UserName.UserName = "usrn";
thing.ClientCredentials.UserName.Password = "passw";
var response = await thing.getSomethingAsync("id").ConfigureAwait(false);
}
finally
{
await thing.CloseAsync().ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
基于旧的配置工作调用服务是这样的,我错过了什么?
<bindings>
<basicHttpsBinding>
<binding name="TheEndpoint_pub_ws_AService_Binder" closeTimeout="00:02:00"
openTimeout="00:02:00" receiveTimeout="00:03:00" sendTimeout="00:03:00">
<security mode="Transport">
<transport clientCredentialType="Basic" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpsBinding>
</bindings>
<client>
<endpoint address="https://someurl.com/ws/Thing.pub.ws:AService"
binding="basicHttpsBinding" bindingConfiguration="TheEndpoint_pub_ws_AService_Binder"
contract="TheEndpoint.AService_PortType" name="TheEndpoint_pub_ws_AService_Port" />
</client>
Run Code Online (Sandbox Code Playgroud)
我无法在网上找到很多这方面的信息.希望您能够帮助我.
更新 Per Sixto Saez的建议我得到了端点以显示其错误,它是
HTTP请求未经授权使用客户端身份验证方案"Basic".从服务器接收的认证头是'Basic realm ="Integration Server",encoding ="UTF-8"'.
如果成功,我会尝试找出要做的事情并将结果发布在此处.
更新2
好的,现在我尝试使用此代码转到新语法
ChannelFactory<IAService> factory = null;
IAService serviceProxy = null;
Binding binding = null;
try
{
binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
factory = new ChannelFactory<IAService>(binding, new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.UserName.UserName = "usrn";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
//error caught here
throw;
}
Run Code Online (Sandbox Code Playgroud)
但我仍然得到相同(略有不同)的错误.它现在有'Anonymous'而不是'Basic',现在最后缺少",encoding ="UTF-8".
HTTP请求未经授权,客户端身份验证方案为"匿名".从服务器收到的身份验证标头是'Basic realm ="Integration Server"'.
问题出在我身边还是服务器上?
显然,我的SOAP"技能"现在非常缺乏,但我只是尝试了一下我能用这种新方法想到的每个配置组合而没有运气.希望有人能指出我正确的方向.
Stu*_*rla 24
好的,这个答案适用于那些试图从.net Core项目连接到WCF服务的人.
这是我的问题的解决方案,使用新的.net核心WCF语法/库.
BasicHttpBinding basicHttpBinding = null;
EndpointAddress endpointAddress = null;
ChannelFactory<IAService> factory = null;
IAService serviceProxy = null;
try
{
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
endpointAddress = new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService"));
factory = new ChannelFactory<IAService>(basicHttpBinding, endpointAddress);
factory.Credentials.UserName.UserName = "usrn";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
}
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
finally
{
// *** ENSURE CLEANUP (this code is at the WCF GitHub page *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
Run Code Online (Sandbox Code Playgroud)
UPDATE
我使用上面的代码得到以下异常
此OperationContextScope正在按顺序处理.
所以我必须执行以下操作才能使其工作(基于此GitHub问题)
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
factory = new ChannelFactory<IAService_PortType>(basicHttpBinding, new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.UserName.UserName = "usern";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
var opContext = new OperationContext((IClientChannel)serviceProxy);
var prevOpContext = OperationContext.Current; // Optional if there's no way this might already be set
OperationContext.Current = opContext;
try
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
// cleanup
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
OperationContext.Current = prevOpContext; // Or set to null if you didn't capture the previous context
}
Run Code Online (Sandbox Code Playgroud)
但您的要求可能会有所不同.以下是帮助您连接到WCF服务可能需要的资源:
这些测试给了我很多帮助,但是有些难以找到(我有帮助,感谢Zhenlan 回答我的wcf github问题)
要从 .NET Core 使用 SOAP 服务,从项目 UI 添加连接的服务不起作用。
选项 1: 使用 dotnet-svcutil CLI。先决条件:VS 2017,15.5或以上版本
转到 app.csproj 文件并添加以下引用:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
<PackageReference Include="System.ServiceModel.Http" Version="4.5.3" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="dotnet-svcutil" Version="1.0.*" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)重建解决方案。
选项 2 如果您需要参考多个 SOAP 服务,
对于那些尝试对 NTLM 和 .Net Core 执行相同操作并想知道某些变量的定义是什么的人,我将代码澄清为如下所示:
IAService_PortType是您按照https://joshuachini.com/2017/07/13/calling-a-soap-service-from-asp-net-core-or-net-core/上的指南创建的服务引用
BasicHttpBinding basicHttpBinding =
new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
// Setting it to Transport will give an exception if the url is not https
basicHttpBinding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Ntlm;
ChannelFactory<IAService_PortType> factory =
new ChannelFactory<IAService_PortType>(basicHttpBinding,
new EndpointAddress(
new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.Windows.ClientCredential.Domain = domain;
factory.Credentials.Windows.ClientCredential.UserName = user;
factory.Credentials.Windows.ClientCredential.Password = pass;
IAService_PortType serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
try
{
var result = serviceProxy.getSomethingAsync("id").Result;
}
finally
{
// cleanup
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
Run Code Online (Sandbox Code Playgroud)
小智 5
所以我不得不这样做并使用了WCF Web Service Reference Provider Tool。
根据这里的回应,显然需要与绑定、工厂和代理有关的所有迂回业务似乎很奇怪,考虑到这一切似乎都是导入类的一部分。
无法找到一个简单的官方“HowTo”,我将发布我的发现,关于我能够拼凑起来以满足我对摘要式身份验证的要求的最简单设置:
ServiceName_PortClient client = new ServiceName_PortClient();
//GetBindingForEndpoint returns a BasicHttpBinding
var httpBinding = client.Endpoint.Binding as BasicHttpBinding;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
client.ClientCredentials.HttpDigest.ClientCredential = new NetworkCredential("Username", "Password", "Digest");
var result = await client.GetResultAsync();
Run Code Online (Sandbox Code Playgroud)
现在,如果您不需要进行任何身份验证,只需执行以下操作:
ServiceName_PortClient client = new ServiceName_PortClient();
var result = await client.GetResultAsync();
Run Code Online (Sandbox Code Playgroud)
应该够了。
该ServiceName_PortClient班由导入工具,其中这样产生的ServiceName是我被导入服务的名称。
当然,将配置放在部分ServiceName_PortClient类中似乎更符合导入代码的精神:
public partial class ServiceName_PortClient
{
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials)
{
var httpBinding = serviceEndpoint.Binding as BasicHttpBinding;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
clientCredentials.HttpDigest.ClientCredential = new NetworkCredential("Username", "Password", "Realm");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46596 次 |
| 最近记录: |