我喜欢在using
块中实例化我的WCF服务客户端,因为它几乎是使用实现的资源的标准方法IDisposable
:
using (var client = new SomeWCFServiceClient())
{
//Do something with the client
}
Run Code Online (Sandbox Code Playgroud)
但是,正如本MSDN文章中所述,在using
块中包装WCF客户端可能会掩盖导致客户端处于故障状态的任何错误(如超时或通信问题).简而言之,当调用Dispose()时,客户端的Close()方法会触发,但会因为处于故障状态而抛出错误.然后,第二个异常掩盖了原始异常.不好.
MSDN文章中建议的解决方法是完全避免使用using
块,而是实例化您的客户端并使用它们,如下所示:
try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}
Run Code Online (Sandbox Code Playgroud)
与using
块相比,我认为这很难看.每次需要客户端时都需要编写很多代码.
幸运的是,我发现了一些其他的解决方法,例如IServiceOriented上的这个.你从:
public delegate void UseServiceDelegate<T>(T proxy);
public static class Service<T>
{
public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>("");
public static void Use(UseServiceDelegate<T> codeBlock)
{ …
Run Code Online (Sandbox Code Playgroud) 我正在尝试将应用程序(客户端)连接到公开的WCF服务,但不是通过应用程序配置文件,而是通过代码.
我应该怎么做呢?
我正在尝试实现一个纯WCF场景,我想在不依赖SDK帮助程序类的情况下调用Dynamics CRM WCF服务.基本上,我想使用.net框架中的本机WCF支持对Dynamics CRM 2011实施联合身份验证.
我这样做的原因是我想稍后将这个场景移植到BizTalk上.
我已成功使用SvcUtil生成代理类,但部分策略和安全性断言与配置架构不兼容.SvcUtil建议从代码构建绑定,这正是我想要做的.
结果代码在这里:
private static void CallWcf()
{
OrganizationServiceClient client = null;
try
{
// Login Live.com Issuer Binding
var wsHttpBinding = new WSHttpBinding();
wsHttpBinding.Security = new WSHttpSecurity();
wsHttpBinding.Security.Mode = SecurityMode.Transport;
// Endpoint Binding Elements
var securityElement = new TransportSecurityBindingElement();
securityElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDes;
securityElement.IncludeTimestamp = true;
securityElement.KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
securityElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
securityElement.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
var securityTokenParameters = new IssuedSecurityTokenParameters();
securityTokenParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
securityTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
securityTokenParameters.RequireDerivedKeys = false;
securityTokenParameters.TokenType = …
Run Code Online (Sandbox Code Playgroud) 我得到这个例外:
通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态.
WCF服务使用默认的wsHttpBinding.无论我在哪里使用它,我都会以下列方式使用WCF:
using (var proxy = new CAGDashboardServiceClient())
{
proxy.Open();
var result = proxy.GetSiteForRegion(ddlRegions.SelectedValue);
ddlSites.DataSource = result;
ddlSites.DataBind();
proxy.Close();
}
Run Code Online (Sandbox Code Playgroud)
消息中显示的错误行似乎是在last proxy.close之后.不确定发生了什么.我正在视觉工作室08内推出这项服务.
这是跟踪信息:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Server stack trace:
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase`1.Close()
at System.ServiceModel.ClientBase`1.System.IDisposable.Dispose()
at CAGDashboard.UserControls.ucVolunteerCRUDGrid.ddlRegions_SelectedIndexChanged(Object sender, EventArgs e) in C:\Documents and Settings\rballalx\My Documents\Visual …
Run Code Online (Sandbox Code Playgroud) 我的第一个WCF示例正在运行.我有一个网站上的主机有很多绑定.因此,我已将此添加到我的web.config中.
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
Run Code Online (Sandbox Code Playgroud)
这是我的默认绑定http://id.web,它使用以下代码.
EchoServiceClient client = new EchoServiceClient();
litResponse.Text = client.SendEcho("Hello World");
client.Close();
Run Code Online (Sandbox Code Playgroud)
我现在正在尝试在运行时设置端点地址.即使它与上述代码的地址相同.
EchoServiceClient client = new EchoServiceClient();
client.Endpoint.Address = new EndpointAddress("http://id.web/Services/EchoService.svc");
litResponse.Text = client.SendEcho("Hello World");
client.Close();
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
The request for security token could not be satisfied because authentication failed.
Run Code Online (Sandbox Code Playgroud)
请建议我如何在运行时更改端点地址?
另外这里是我的客户配置,由Ladislav Mrnka提出要求
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IEchoService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None" /> …
Run Code Online (Sandbox Code Playgroud) 在为我公司购买的产品消费网络服务时,我遇到了一个奇怪的问题.该产品名为Campaign Commander,由一家名为Email Vision的公司制作.我们正在尝试使用"Data Mass Update SOAP API".
每当我尝试调用webservice上的任何方法时,调用实际上都会成功,但是客户端在处理响应时失败并且我得到一个异常.
错误的详细信息如下,感谢您提供的任何帮助.
当将服务作为Web引用使用时,我得到一个InvalidOperationException
用于我所做的任何调用,并带有以下消息:
Client found response content type of 'multipart/related; type="application/xop+xml"; boundary="uuid:170e63fa-183c-4b18-9364-c62ca545a6e0"; start="<root.message@cxf.apache.org>"; start-info="text/xml"', but expected 'text/xml'.
The request failed with the error message:
--
--uuid:170e63fa-183c-4b18-9364-c62ca545a6e0
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:openApiConnectionResponse xmlns:ns2="http://api.service.apibatchmember.emailvision.com/" xmlns:ns3="http://exceptions.service.apibatchmember.emailvision.com/">
<return>DpKTe-9swUeOsxhHH9t-uLPeLyg-aa2xk3-aKe9oJ5S9Yymrnuf1FxYnzpaFojsQSkSCbJsZmrZ_d3v2-7Hj</return>
</ns2:openApiConnectionResponse>
</soap:Body>
</soap:Envelope>
--uuid:170e63fa-183c-4b18-9364-c62ca545a6e0--
--.
Run Code Online (Sandbox Code Playgroud)
如您所见,响应soap信封看起来有效(这是一个有效的响应并且调用成功),但客户端似乎遇到内容类型问题并生成异常.
当我将服务作为服务引用使用时,我得到一个ProtocolException
用于我所做的任何调用,并带有以下消息:
The content type multipart/related; type="application/xop+xml"; boundary="uuid:af66440a-012e-4444-8814-895c843de5ec"; start="<root.message@cxf.apache.org>"; start-info="text/xml" of the response message does not match the content type …
Run Code Online (Sandbox Code Playgroud) 我可以在basicHttpBinding中的WCF传入/传出消息中添加自定义SOAP标头,就像我们可以在ASMX Web服务中添加自定义身份验证标头一样吗?应使用.net 2.0/1.1 Web服务客户端(可通过WSDL.EXE工具访问)访问这些自定义SOAP标头.
我是WCF的新手.最初,我创建了一个WCF服务,并使用生成的客户端代理来使用来自客户端的服务.因此,每当我在服务上执行某些操作时,所有按顺序执行的操作都会同步调用操作.我将并发模式更改为多个,但操作仍然是同步进行的.然后我为我的操作生成了异步方法,并使用了开始/结束模式,因此我猜测它"释放"了通道并让操作并行/异步地增加了我的应用程序的吞吐量.
然后我用来ChannelFactory
创建一个通道并执行操作,因为客户端和服务器可以共享合同(同一个项目).但IClientChannel
只提供BeginOpen/EndOpen/BeignClose/EndClose
.它不具备ClientBase
的BeginOperation/EndOperation
方法.所以基本上我不能在通道上异步执行操作来释放,以便我可以使用该通道执行其他操作.
我只是为每个操作创建了通道,它解决了这个问题
所以我的问题是:
哪个更好(ClientBase vs. ChannelFactory
)wrt到我的场景特别是我想同时用多个线程对服务对象执行多个操作
是否建议为每个操作创建一个通道?
事实上,我认为我们在两个端点(客户端/服务)之间只能有一个通道.但我可以创建尽可能多的频道.例如:我能够创建通道的Int16.MaxValue.所以不确定这个限制和建议是什么.
Service[] channels = new IService[Int16.MaxValue];
for(int i = 0; i<Int16.MaxValue; i++)
{
channels[i] = factory.CreateChannel();
}
Run Code Online (Sandbox Code Playgroud)所以基本上你能告诉我有关频道,推荐和技巧的基础知识......等等.:)
我在这里遇到一种奇怪的情况.我搞定了,但我不明白为什么.情况如下:
我的应用程序(网站)必须调用WCF服务.WCF服务公开netTcpBinding并需要传输安全性(Windows).客户端和服务器位于同一个域中,但位于不同的服务器上.
因此生成客户端会导致以下配置(主要是默认值)
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="MyTcpEndpoint" ...>
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0"
binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint"
contract="Service.IMyService" name="TcpEndpoint"/>
</client>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)
当我运行网站并调用该服务时,我收到以下错误:
System.ServiceModel.Security.SecurityNegotiationException: Either the target name is incorrect or the server has rejected the client credentials. ---> System.Security.Authentication.InvalidCredentialException: Either the target name is incorrect or the server has rejected the client credentials. ---> System.ComponentModel.Win32Exception: The logon attempt failed
--- End of inner exception stack trace …
Run Code Online (Sandbox Code Playgroud) 我正在从WinRT应用程序调用WCF服务.该服务要求为身份验证设置一些标头.问题是如果我同时多次调用服务,我会得到以下异常:
此OperationContextScope正在按顺序处理.
当前代码如下所示:
public async Task<Result> CallServerAsync()
{
var address = new EndpointAddress(url);
var client = new AdminServiceClient(endpointConfig, address);
using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = GetHeader();
var request = new MyRequest(...);
{
context = context,
};
var result = await client.GetDataFromServerAsync(request);
}
}
Run Code Online (Sandbox Code Playgroud)
我从文档中找到了以下评论:
不要在OperationContextScope块中使用异步"await"模式.当继续发生时,它可以在不同的线程上运行,而OperationContextScope是特定于线程的.如果需要为异步调用调用"await",请在OperationContextScope块之外使用它.
所以我似乎错误地调用了该服务.但是正确的方法是什么?
wcf-client ×10
wcf ×9
c# ×6
wcf-binding ×2
wcf-security ×2
.net ×1
asynchronous ×1
dns ×1
exception ×1
using ×1
vb.net ×1