无法捕获SilverLight客户端应用程序中WCF服务引发的FaultException
我正在从Silverlight应用程序调用WCF服务方法。Wcf服务在发生故障时返回故障异常。我能够从我的WCF服务中抛出错误异常。但是它没有接收到我的Silverlight应用程序(.xaml.cs)。相反,我收到一个异常“用户未处理通信异常,远程服务器返回错误:NotFound” 在References.cs文件中(自动生成的文件) 我在.Xaml.cs文件中调用WCF服务方法,如下所示无法捕获SilverLight客户端应用程序中WCF服务引发的FaultException,wcf,silverlight,c#-4.0,faultexception,Wcf,Silverlight,C# 4.0,Faultexception,我正在从Silverlight应用程序调用WCF服务方法。Wcf服务在发生故障时返回故障异常。我能够从我的WCF服务中抛出错误异常。但是它没有接收到我的Silverlight应用程序(.xaml.cs)。相反,我收到一个异常“用户未处理通信异常,远程服务器返回错误:NotFound” 在References.cs文件中(自动生成的文件) 我在.Xaml.cs文件中调用WCF服务方法,如下所示 private void btnExecuteQuery_Click(object send
private void btnExecuteQuery_Click(object sender, RoutedEventArgs e)
{
try
{
objService.GetDataTableDataAsync(_DATABASENAME, strQuery);
objService.GetDataTableDataCompleted += new EventHandler<GetDataTableDataCompletedEventArgs>(objService_GetDataTableDataCompleted);
}
catch (FaultException<MyFaultException> ex)
{
lblErrorMessage.Content = "Please Enter a Valid SQL Query";
}
}
And I wrote my GetDataTableDataCompleted event as below
void objService_GetDataTableDataCompleted(object sender, GetDataTableDataCompletedEventArgse)
{
//code
}
private void btnExecuteQuery\u单击(对象发送方,路由目标)
{
尝试
{
GetDataTableDataAsync(_DATABASENAME,strQuery);
objService.GetDataTableDataCompleted+=新事件处理程序(objService\u GetDataTableDataCompleted);
}
捕获(FaultException-ex)
{
lblErrorMessage.Content=“请输入有效的SQL查询”;
}
}
我编写了GetDataTableDataCompleted事件,如下所示
void objService_GetDataTableDataCompleted(对象发送方,GetDataTableDataCompletedEventArgse)
{
//代码
}
这是我的服务方法
public IEnumerable<Dictionary<string, object>> GetDataTableData(string dataBaseName, string query)
{
try
{
IEnumerable<Dictionary<string, object>> objDictionary;
objDictionary = objOptimityDAL.GetDataForSelectQuery(dataBaseName, query);
return objDictionary;
}
catch (Exception ex)
{
MyFaultException fault = new MyFaultException();
fault.Reason = ex.Message.ToString();
throw new FaultException<MyFaultException>(fault, new FaultReason("Incorrect SQL Query"));
}
}
public IEnumerable GetDataTableData(字符串数据库名,字符串查询)
{
尝试
{
IEnumerable对象描述;
objDictionary=objOptimityDAL.GetDataForSelectQuery(dataBaseName,query);
返回对象描述;
}
捕获(例外情况除外)
{
MyFaultException fault=新的MyFaultException();
fault.Reason=ex.Message.ToString();
抛出新的FaultException(错误,新的FaultReason(“不正确的SQL查询”);
}
}
在这里,我的WCf服务与数据访问层交互并成功抛出故障异常,但它没有接收到我的客户机方法,相反,我得到了一个未处理的异常,如
用户未处理通信异常,远程服务器在References.cs代码中返回错误:NotFound,如下所示
public System.Collections.ObjectModel.ObservableCollection<System.Collections.Generic.Dictionary<string, object>> EndGetDataTableData(System.IAsyncResult result) {
object[] _args = new object[0];
System.Collections.ObjectModel.ObservableCollection<System.Collections.Generic.Dictionary<string, object>> _result = ((System.Collections.ObjectModel.ObservableCollection<System.Collections.Generic.Dictionary<string, object>>)(base.EndInvoke("GetDataTableData", _args, result)));
return _result;
}
public System.Collections.ObjectModel.ObservableCollection EndGetDataTableData(System.IAsyncResult结果){
object[]_args=新对象[0];
System.Collections.ObjectModel.ObservableCollection_结果=((System.Collections.ObjectModel.ObservableCollection)(base.EndInvoke(“GetDataTableData”,参数,结果));
返回结果;
}
以下是Wcf服务的Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
下面是我的servicerences.ClientConfig文件
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647"
closeTimeout="01:00:00"
receiveTimeout="01:00:00"
sendTimeout="01:00:00">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:3132/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
请建议我如何捕获SilverlightClient中的faultException
提前感谢当您第一次创建服务时,您应该选择启用Silverlight的WCF服务。它会为您创建所有的基础设施 但是您仍然可以手动将必要的代码添加到WCF服务项目中 SilverlightFaultBehavior.cs
/// <summary>
/// The behavior which enables FaultExceptions for Silverlight clients
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class SilverlightFaultBehaviorAttribute : Attribute, IServiceBehavior
{
private class SilverlightFaultEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new SilverlightFaultMessageInspector());
}
public void Validate(ServiceEndpoint endpoint)
{
}
private class SilverlightFaultMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
if ((reply != null) && reply.IsFault)
{
HttpResponseMessageProperty property = new HttpResponseMessageProperty();
property.StatusCode = HttpStatusCode.OK;
reply.Properties[HttpResponseMessageProperty.Name] = property;
}
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
{
endpoint.Behaviors.Add(new SilverlightFaultEndpointBehavior());
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
[SilverlightFaultBehaviorAttribute]
public class Service1 : IService1
{
...
}
在客户端上,您应该检查回调函数中的e.Error
属性。从您的示例中尝试/捕获将不起作用
Silverlight客户端
objService.GetDataTableDataCompleted += (s, e) =>
{
if(e.Error != null) {
if (e.Error is FaultException) {
lblErrorMessage.Content = "Please Enter a Valid SQL Query";
}
// do something with other errors
}
else {
// success
}
};
objService.GetDataTableDataAsync(_DATABASEName, strQuery);
您应该在第一次创建服务时选择启用Silverlight的WCF服务。它会为您创建所有的基础设施 但是您仍然可以手动将必要的代码添加到WCF服务项目中 SilverlightFaultBehavior.cs
/// <summary>
/// The behavior which enables FaultExceptions for Silverlight clients
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class SilverlightFaultBehaviorAttribute : Attribute, IServiceBehavior
{
private class SilverlightFaultEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new SilverlightFaultMessageInspector());
}
public void Validate(ServiceEndpoint endpoint)
{
}
private class SilverlightFaultMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
if ((reply != null) && reply.IsFault)
{
HttpResponseMessageProperty property = new HttpResponseMessageProperty();
property.StatusCode = HttpStatusCode.OK;
reply.Properties[HttpResponseMessageProperty.Name] = property;
}
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
{
endpoint.Behaviors.Add(new SilverlightFaultEndpointBehavior());
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
[SilverlightFaultBehaviorAttribute]
public class Service1 : IService1
{
...
}
在客户端上,您应该检查回调函数中的e.Error
属性。从您的示例中尝试/捕获将不起作用
Silverlight客户端
objService.GetDataTableDataCompleted += (s, e) =>
{
if(e.Error != null) {
if (e.Error is FaultException) {
lblErrorMessage.Content = "Please Enter a Valid SQL Query";
}
// do something with other errors
}
else {
// success
}
};
objService.GetDataTableDataAsync(_DATABASEName, strQuery);
由于出现通信异常,配置中可能存在一些错误。服务是否接到客户的电话?听起来好像您在尝试调用服务时出错了?也许发布您的web.configs和完整堆栈跟踪?嗨,Jocke,谢谢您的回复,我已经用配置文件编辑了我的帖子,并且我能够成功调用服务方法,该方法会引发异常,但这里的问题是从服务中捕获抛出的异常。您是否执行了
[FaultContract(typeof(MyFaultException))]
?有关更多详细信息,请参阅。由于出现通信异常,可能在配置中出现了一些错误。该服务是否得到客户端调用?听起来您在尝试调用该服务时出错了?可能会发布您的web.configs和完整堆栈跟踪?嗨,Jocke,感谢您的回复,我已使用配置文件编辑了我的帖子s、 我能够成功地调用服务方法,它会抛出一个异常,但这里的问题是从服务中捕获抛出的异常?有关更多详细信息,我正在按钮单击事件中调用objService.GetDataTableDataCompleted事件。那么您的答案的silverlightclient中的(s,e)参数是什么,我如何将其写入我的按钮单击事件中。请您进行电子编辑。我已经编辑了我的post silverlightclient(.xaml.cs),请您仔细阅读并编辑silverlightClient答案。@Sudhakar Byna(s,e)是lambda表达式的输入参数。您可以在此处阅读关于lambda表达式的内容:谢谢。这次我遇到了一个未处理的异常,如在我的服务方法中,“System.ServiceModel.FaultException`1'类型的异常发生在System.ServiceModel.dll中,但未在用户代码中处理”,同时引发错误异常,如引发新的FaultException(Fault,new FaultReason(“不正确的SQL查询”);然后未处理的异常在引用中中断