After looking at this for a while,I thought it might be a configuration issue on my development Box. However,after doing a clean download of the source code to a different development machine,I’m still getting this issue.
我有一个Silverlight客户端异步调用WCF服务.间歇性地,我将获得一个通用的NotFound异常.异常(这是众所周知的缺乏细节)间歇性地发生在我呼叫的几乎任何服务上.
这就是事情.通过明智地设置断点,我已经能够确定服务端正常执行.正在检索和返回数据.这个问题似乎更多地出现在客户端.
这就是问题……如果我让服务执行超过10秒,我可以始终如一地发生异常.当我这样做时,它永远不会回到我完成的回调.相反,我在服务的客户端Reference.cs中获得异常:
public System.Collections.ObjectModel.ObservableCollection<Project.Ui.SilverLight.ServiceName.ModelName> EndGetService(System.IAsyncResult result) { object[] _args = new object[0]; System.Collections.ObjectModel.ObservableCollection<roject.Ui.SilverLight.ServiceName.ModelName> _result = ((System.Collections.ObjectModel.ObservableCollection<roject.Ui.SilverLight.ServiceName.ModelName>)(base.EndInvoke("GetService",_args,result))); return _result; }
我得到的例外是(不是很有帮助):
System.ServiceModel.CommunicationException was unhandled by user code Message=The Remote Server returned an error: NotFound. StackTrace: at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result) at System.ServiceModel.Channels.ServiceChannel.EndCall(String action,Object[] outs,IAsyncResult result) at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName,Object[] args,IAsyncResult result) at Project.Ui.SilverLight.Service.ServicesClient.ServicesClientChannel.EndGetxxxxx(IAsyncResult result) at Project.Ui.SilverLight.Service.ServicesClient.Project.Ui.SilverLight.Service.IServices.EndGetxxxx(IAsyncResult result) at Project.Ui.SilverLight.Service.ServicesClient.OnEndGet(IAsyncResult result) at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result) InnerException: System.Net.WebException Message=The Remote Server returned an error: NotFound. StackTrace: at System.Net.browser.AsyncHelper.BeginonUI(SendOrPostCallback beginMethod,Object state) at System.Net.browser.browserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result) InnerException: System.Net.WebException Message=The Remote Server returned an error: NotFound. StackTrace: at System.Net.browser.browserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult) at System.Net.browser.browserHttpWebRequest.<>c__displayClass5.<EndGetResponse>b__4(Object sendState) at System.Net.browser.AsyncHelper.<>c__displayClass2.<BeginonUI>b__0(Object sendState) InnerException:
绑定信息(名称已更改,但它们与正在执行的服务匹配)
<binding name="Project.WebUI.Services.xxxxxServices.customBinding0" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"> <binaryMessageEncoding/> <httpTransport /> </binding> ... <service name="Project.WebUI.Services.xxxxxServices"> <endpoint address="" binding="customBinding" bindingConfiguration="Project.WebUI.Services.xxxxxServices.customBinding0" contract="Project.WebUI.Services.xxxxxServices" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service>
我相信我已经检查了相关的超时.通道的operationTimeout设置为至少一分钟,ReceiveTimeout和OpenTimeout也是如此.是否有一些关于Silverlight异步WCF调用的问题需要设置为告诉它超过十秒?
解决方法
我提到了silverlight,但这不是一个特定于银色的问题.
由于产生错误代码的方式,存在未找到的错误.您需要拦截任何故障并更改错误代码 – 这将导致错误报告正确并且不会因安全性而被彻底清除.
如果您考虑一下,则找不到服务器,因为该调用是异步的,并且由于代码中的异常而导致死亡.
我在我的wcf服务中使用这个类来插件 – 我通过web.config这样做,但是不难改变它,以便它在服务本身上完成了ha类级属性.
你可能想要删除所有合同的东西.它正用于我正在进行的项目中,但与此问题无关.
[AttributeUsage(AttributeTargets.Class)] public class FaultBehavior : Attribute,IServiceBehavior,IEndpointBehavior { public class SilverlightFaultMessageInspector : IdispatchMessageInspector { public void BeforeSendReply(ref Message reply,object correlationState) { Contract.Assume(reply !=null ); if (reply.IsFault) { HttpResponseMessageProperty property = new HttpResponseMessageproperty(); // Here the response code is changed to 200. property.StatusCode = System.Net.HttpStatusCode.OK; Contract.Assume(reply.Properties != null); reply.Properties[HttpResponseMessageProperty.Name] = property; } } public object AfterReceiveRequest(ref Message request,IClientChannel channel,InstanceContext instanceContext) { // Do nothing to the incoming message. return null; } } #region IServiceBehavior Members void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase,Collection<ServiceEndpoint> endpoints,BindingParameterCollection bindingParameters) { } void IServiceBehavior.ApplydispatchBehavior(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase) { Contract.Assume( serviceHostBase != null); Contract.Assume(serviceHostBase.Channeldispatchers != null); foreach (Channeldispatcher cdispatcher in serviceHostBase.Channeldispatchers) { Contract.Assume(cdispatcher != null); Contract.Assume(cdispatcher.Endpoints != null ); foreach (Endpointdispatcher endpointdisbatcher in cdispatcher.Endpoints) { Contract.Assume(endpointdisbatcher != null); Contract.Assume(endpointdisbatcher.dispatchRuntime != null); Contract.Assume(endpointdisbatcher.dispatchRuntime.MessageInspectors != null); endpointdisbatcher.dispatchRuntime.MessageInspectors.Add(new SilverlightFaultMessageInspector()); } } } void IServiceBehavior.Validate(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase) { } #endregion #region IEndpointBehavior Members void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint,BindingParameterCollection bindingParameters) { } void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint,ClientRuntime clientRuntime) { } void IEndpointBehavior.ApplydispatchBehavior(ServiceEndpoint endpoint,Endpointdispatcher endpointdispatcher) { Contract.Assume(endpointdispatcher != null); Contract.Assume(endpointdispatcher.dispatchRuntime != null); Contract.Assume(endpointdispatcher.dispatchRuntime.MessageInspectors != null); SilverlightFaultMessageInspector inspector = new SilverlightFaultMessageInspector(); endpointdispatcher.dispatchRuntime.MessageInspectors.Add(inspector); } void IEndpointBehavior.Validate(ServiceEndpoint endpoint) { } #endregion }
然后你需要定义将出现在web.config中的元素
public class FaultHandlerElement : BehaviorExtensionElement { protected override object CreateBehavior() { return new FaultBehavior(); } public override Type BehaviorType { get { return typeof(FaultBehavior); } } }
然后在Web配置中,您需要将其添加到服务模型部分 – 故障异常将在其下面有一条波浪线;)
<system.serviceModel> <extensions> <behaviorExtensions> <add name="faultBehavIoUrExtension" type="copSilverlight.Web.FaultHandlerElement,copSilverlight.Web,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"/> </behaviorExtensions> </extensions
然后,您可以将您的行为挂钩,以便像这样使用它
<serviceBehaviors> <behavior name="basicHttpBehavIoUr"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <faultBehavIoUrExtension /> </behavior>
另一种“修复”是打开wcf服务中的跟踪
需要注意的是,如果你不创建目录,它就不会产生日志
<system.diagnostics> <sources> <source name="System.ServiceModel" switchValue="information,ActivityTracing" propagateActivity="true"> <listeners> <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\logs\appName\wcf.svclog" /> </listeners> </source> </sources> </system.diagnostics>
虽然日志记录是不理想的 – 第一个解决方案实际上解决了问题.
我已经实现了这两个,现在我得到异常冒泡到我的silverlight应用程序,如你所料.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。