locked
How do I get errors back from REST service using WebClient? RRS feed

  • Question

  • I have a service that I call from Silverlight.  It is both WCF and REST. My Silverlight client calls it fine, however, when it is a WebClient call, an exception in the service does not come back to the client. I only get "Server not found", not the error message. For the WCF call, I use a SilverlightFaultBehavior on the server and that DOES get the error message of the exception back.

    But either that SilverlightFaultBehavior is goofing up the REST exception, or I need to do something different.

    Here is the REST call and completed event handler (in Oxygene language):

       function ViewModel.GetRESTVSDSInfo : VSDS.Data.DataContracts.VSDSInfo;
          begin
          IsBusy := true;
    
          VSDSInfo := nil;
    
          var wc := new WebClient;
    
          if UseJson 
             then wc.Headers[HttpRequestHeader.Accept] := "application/json"
             else wc.Headers[HttpRequestHeader.Accept] := "application/xml";
        
          var uri := new Uri( Application.Current.Host.Source, '../../Service.svc/Rest/VSDSInfo' );
    
          wc.DownloadStringCompleted += wcRestVSDSInfoDownloadStringCompleted;
          wc.DownloadStringAsync( uri );
          end;
    
       method ViewModel.wcRestVSDSInfoDownloadStringCompleted(sender: Object; e: DownloadStringCompletedEventArgs);
          begin
          IsBusy := false;
    
          var wc := WebClient( sender );
          wc.DownloadStringCompleted -= wcRestVSDSInfoDownloadStringCompleted;
          
          if e.Error <> nil then begin
             MessageBox.Show( 'Error: ' + e.Error.Message  );
             exit;
             end;
    
          if UseJson 
             then self.VSDSInfo := SerializationHelper.FromJson<VSDS.Data.DataContracts.VSDSInfo>( e.Result )
             else self.VSDSInfo := SerializationHelper.FromXml<VSDS.Data.DataContracts.VSDSInfo>( e.Result );
    
          SurveyHeader.VSDSInfo := self.VSDSInfo;
          InitData;
          end;
    

    Here is the WCF call and completion handler:

       function ViewModel.GetWCFVSDSInfo : VSDS.Data.DataContracts.VSDSInfo;
          begin
    
          IsBusy := true;
    
          VSDSInfo          := nil;
    
          Proxy := ServiceProxy.NewClient;
          Proxy.GetVSDSInfoCompleted += ProxyGetWCFVSDSInfoCompleted;
          Proxy.GetVSDSInfoAsync;
          end;
    
       method ViewModel.ProxyGetWCFVSDSInfoCompleted(sender: Object; e: GetVSDSInfoCompletedEventArgs );
          begin
          IsBusy := False;
          if sender <> nil then begin
             Proxy.GetVSDSInfoCompleted -= ProxyGetWCFVSDSInfoCompleted;
             Proxy.CloseAsync;
             end;
    
          if e.Error <> nil then begin
             MessageBox.Show( 'Error: ' + e.Error.Message  );
             exit;
             end;
    
          self.VSDSInfo         := e.Result;
          SurveyHeader.VSDSInfo := self.VSDSInfo;
          InitData;
          end;
    

    And here is the service code:

       function  VSDSService.GetVSDSInfo: VSDSInfo;
          begin
          try
             using db := new Database( 'VSDS' ) do begin
                result := db.GetVSDSInfo;
                end;
    
          except
             on e: Exception do begin
                raise new System.Data.Services.DataserviceException( e.Message );
                end;
             end;
          end;
    

    I've tried a few different exception types.  Just a plain Exception, a WebFaultException, etc.  Nothing made a difference.

    Here is the relevant web.config section for the SilverlightFaultBehavior:

        <extensions>
          <behaviorExtensions>
            <add name="silverlightFaults" type="Silverlight.ServiceFaults.SilverlightFaultBehavior, SilverlightFaultBehavior"/>
          </behaviorExtensions>
        </extensions>
        <behaviors>
          <endpointBehaviors>
            <behavior name="SilverlightFaultBehavior">
              <silverlightFaults/>
            </behavior>
            <behavior name="VSDSRestfulBehavior">
              <webHttp helpEnabled="true" automaticFormatSelectionEnabled="true"/>
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </endpointBehaviors>
          <serviceBehaviors>
            <behavior name="VSDSBehavior">
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <serviceMetadata httpGetEnabled="true"/>
              <!--<serviceMetadata httpsGetEnabled="true"/>-->
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    

    Tuesday, December 8, 2015 2:40 PM

All replies

  • If you look in fiddler, is there definitely no more info returned than server not found?

    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Tuesday, December 8, 2015 4:35 PM
    Moderator
  • I haven't tried putting Fiddler on this Win10 box, but the debuggers of both IE 11 and FF 42.0 only show 400 Bad Request when poking around with what they present.
    Wednesday, December 9, 2015 9:48 AM
  • Hi mltiede,

    400 Bad Request is a common error, we need more detailed information to check this problem. I suggest you using Fiddler on watch what happened when WebClient call the service. And then share the detailed information here to help us figure out this problem.

    Best Regards,
    Weiwei

    Thursday, December 17, 2015 10:34 AM
    Moderator
  • I finally got back to this error handling nuisance. And I got Fiddler installed and running.

    I see this in the Raw view:

    HTTP/1.1 400 Bad Request

    Cache-Control: private

    Transfer-Encoding: chunked

    Content-Type: application/json; charset=utf-8

    Server: Microsoft-IIS/10.0

    X-AspNet-Version: 4.0.30319

    X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcTWFya1xEb2N1bWVudHNcVmlzdWFsIFN0dWRpbyAyMDEzXFByb2plY3RzXFNXXFZTRFNSZXN0XFZTRFNSZXN0LldlYlxTZXJ2aWNlLnN2Y1xSZXN0XFZTRFNJbmZv?=

    X-Powered-By: ASP.NET

    Date: Tue, 05 Jan 2016 17:22:11 GMT

    17

    {"ErrorMessage":"test"}

    0


    That last bit is the error message in a Custom WebFaultException that I raised for testing like this:

     
    try
       raise new Exception( 'test' ); 
    except
       on e: exception do begin
          var myFault := new VSDSFault;
          myFault.ErrorMessage := e.Message;
          raise new WebFaultException<VSDSFault>( myFault, HttpStatusCode.BadRequest );
          end;
       end;
    
    So Fiddler DOES see it.  Now how can I get access to it in my WebClient?

    Tuesday, January 5, 2016 5:28 PM
  • It's a long time since I implemented such error handling in a Silverlight app.

    I don't think it was REST but I'm not sure that matters.

    Check this out:

    https://msdn.microsoft.com/en-us/library/ee844556%28v=vs.95%29.aspx?f=255&MSPPError=-2147217396

    and

    http://joymonscode.blogspot.co.uk/2012/02/handling-wcf-faultcontract.html


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Tuesday, January 5, 2016 6:59 PM
    Moderator
  • I'm already doing SilverlightFaultBehavior for the WCF service and get back the error messages. As far as I can tell, it is the WebClient with REST that doesn't seem to be able to see the results.

    I need to see an example that works with REST.

    Tuesday, January 5, 2016 10:06 PM
  • No one else have a suggestion?
    Monday, January 25, 2016 2:21 PM
  • thanks for the url that is quite helpful.
    Monday, January 25, 2016 2:33 PM