Pregunta

I am Calling a WCF Service Method from my Silverlight Application. Wcf Service is returning a Fault Exception on Failure. I am able to throw the fault exception from my WCF Service. But it is not receiving to my Silverlight Application(.xaml.cs). Instead I am getting an exception "Communication Exception was unhandled by User, the remote server returned an Error:NotFound" in References.cs file(AutoGenerated File)

I am calling the WCF Service Method in my .Xaml.cs file like below

      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
        }

Here is my Service Method

 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"));

        }
    }

Here My WCf Service is interacting with Data Access Layer and throwing the Fault Exception Successfully but it is not receiving to my client Method, Instead I am getting an unhandled Exception like "Communication Exception was unhandled by User, the remote server returned an Error:NotFound" in References.cs code shown below

 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;
        }

Here is the Web.config of Wcf Service

    <?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>

Below is my ServiceReferences.ClientConfig file

 <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>

Please Suggest me someway to catch the faultException in my SilverlightClient

Thanks in Advance

¿Fue útil?

Solución

You should have chosen Silverlight Enabled WCF Service when you created your service first time. It would have created all the infrastructure for you.

But you can still add the necessary code manually to the WCF Service project.

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)
    {
    }
}

Service1.cs

[SilverlightFaultBehaviorAttribute]
public class Service1 : IService1
{
...
}

And on the client you should check the e.Error property inside the callback function. Try/catch from your example will not work.

The Silverlight Client

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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top