2011-07-26 118 views
1

我已经启用了一个启用Silverlight的WCF Web服务,并从我的Silverlight应用程序连接到它。启用Silverlight WCF服务异常处理

该服务不是使用ASync模式编写的,而是Silverlight自动生成异步方法。

我有一个方法,在我的服务中,有可能抛出异常我可以捕获这个异常,但我不知道处理这个异常的最佳方式,我注意到事件参数完成的方法包含一个错误属性。

可以设置这个错误属性的值吗?

示例方法

public class service 
{ 
    [OperationContract] 
    public Stream getData(string filename) 
    { 
     string filepath = HostingEnvironment.MapPath(filename); 
     FileInfo fi = new FileInfo(filenpath); 

     try 
     { 
      Stream s = fi.Open(FileMode.Open); 

      return s; 
     } 
     catch (IOException e) 
     { 
      return null; 
     } 
    } 
} 

的Silverlight代码

btnFoo_Click(object sender, RoutedEventArgs e) 
{ 
    ServiceClient svc = new ServiceClient(); 

    svc.getDataCompleted += new EventHandler<getDataCompletedEventArgs>(getData_Completed); 
    svc.getDataAsync("text.txt"); 
} 

void getData_Completed(object sender, getDataCompletedEventArgs e) 
{ 
    e.Error //how can i set this value on the service? 
} 

最后,如果服务是脱机或超时反正是有它到达内应用的UnhandledException方法之前捕获此异常.XAML?

感谢

回答

2

由于Silverlight是使用服务asyncronously你没有得到同步异常抛出,而是它存储在e.Error财产,你需要在你的ServiceCallCompleted方法检查。

要回答你的问题

如何设置对服务这个价值?

只要在服务器上抛出一个异常,在给出其他几个条件的情况下就足够了。

您可能希望在您的WCF服务方法中引入FaultContract,并抛出FaultException<T>这是处理WCF中的错误的常用方法。

但是,返回代码500和silverlight将无法获得响应,并且无法获得对Fault对象的响应,即使将该属性添加到服务也是如此。

这可以使用几种方法来解决。

  • 使用替代客户端HTTP堆栈:可以通过使用使用RegisterPrefix方法注册的替代HTTP栈。请参阅下面的关于如何做到这一点的大纲。 Silverlight 4提供了使用客户端HTTP堆栈的选项,该堆栈与默认浏览器HTTP堆栈不​​同,允许您处理SOAP兼容的错误消息。但是,切换到替代HTTP堆栈的潜在问题是浏览器存储的信息(如身份验证cookie)将不再可用于Silverlight,因此涉及安全服务的某些情况可能会停止工作,或者需要额外的代码才能工作。
  • 修改HTTP状态码:您可以修改服务以返回HTTP状态码为200的SOAP错误,Silverlight 4,以便成功处理错误。如何做到这一点概述如下。请注意,这会使服务不符合SOAP协议,因为SOAP需要400或500范围内的响应代码才能解决错误。如果该服务是WCF服务,则可以创建一个端点行为,插入将状态代码更改为200的消息检查器。然后,您可以专门为Silverlight消耗创建端点,并在其中应用该行为。您的其他端点仍将保持SOAP兼容。

Faults in silverlight

-2

Creating and Handling Faults in Silverlight

OR


    [DataContract] 
    public class MyError 
    { 
     [DataMember] 
     public string Code { get; set; } 
     [DataMember] 
     public string Message { get; set; } 
     [DataMember] 
     public DateTime Time { get; set; } 
    } 


public class service 
{ 
    [OperationContract] 
    public Stream getData(string filename, out MyError myError) 
    { 
     myError = null; 
     string filepath = HostingEnvironment.MapPath(filename); 
     FileInfo fi = new FileInfo(filenpath); 

     try 
     { 
      Stream s = fi.Open(FileMode.Open); 
      return s; 
     } 
     catch (IOException e) 
     { 
      myError = new MyError() { Code = "000", Message = ex.Message, Time = DateTime.Now }; 
      return null; 
     } 
    } 
} 

我想成功的项目