启用S​​ilverlight的WCF服务异常处理

时间:2011-07-26 08:32:50

标签: silverlight wcf exception-handling

我已经启用了支持Silverlight的WCF Web服务,并且我从Silverlight应用程序连接到它。

不使用ASync模式编写服务,但Silverlight会自动生成异步方法。

我有一个方法,在我的服务中有可能抛出异常我可以捕获此异常,但我不确定处理此异常的最佳方法,我注意到已完成的事件args方法包含错误属性。

是否可以设置此错误属性的值?

示例方法

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

最后,如果服务处于脱机状态或者超时,那么在它到达App.xaml中的UnhandledException方法之前是否仍然会捕获此异常?

由于

2 个答案:

答案 0 :(得分:2)

由于silverlight正在异步使用服务,因此您不会获得同步异常抛出,而是将其存储在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,Silverlight 4的SOAP故障,以便成功处理故障。如何做到这一点概述如下。请注意,这将使服务不符合SOAP协议,因为SOAP需要400或500范围内的响应代码才能发生故障。如果服务是WCF服务,则可以创建插入消息检查器的端点行为,该状态代码将状态代码更改为200.然后,您可以专门为Silverlight消耗创建端点,并在其中应用该行为。您的其他端点仍将保持SOAP兼容。

Faults in silverlight

答案 1 :(得分:-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;
        }
    }
}

我希望成功的项目