none
Передача деталей исключения RRS feed

  • Вопрос

  • Есть WCF-сервис, и метод, в котором может произойти ошибка. Эту ошибку я отлавливаю и мне нужно дополнить ее кучей дополнительной информации, например какие параметры в метод предавались и т.д. Как передать все это дело на клиента (Silverlight)?
    Пробовал создавать исключение типа Exception, в качестве InnerException передавать пойманное исключение. а в поле Data писать детали. Исключение передается клиенту, вложенное исключение тоже есть, а вот деталей нет. Как решать проблему?
    7 декабря 2011 г. 9:15

Ответы

  • Добрый день.

    Очень просто, создавать свой класс описывающий все нужные вам данные, и использовать FaultContract.

    В общем виде выглядит так:

     

        [DataContract]
        public class MyException
        {
            [DataMember]
            public string Exception;
            [DataMember]
            public string StackTrace;
            [DataMember]
            public string Method;
            [DataMember]
            public int Parameter;
        }
     
        [ServiceContract]
        public interface IMyContract
        {
            [OperationContract]
            [FaultContract(typeof(MyException))]
            int Test(int param);
        }
     
        public class MyService : IMyContract
        {
            public int Test(int param)
            {
                try
                {
                    // process
                }
                catch(Exception ee)
                {
                    MyException myEx = new MyException();
                    myEx.Exception = ee.InnerException.ToString();
                    myEx.StackTrace = ee.StackTrace.ToString();
                    myEx.Method = "Test";
                    myEx.Parameter = param;
                    
                    ///.....
     
                    throw new FaultException<MyException>(myEx, "some comment...");
                }
     
                return 0;
            }
     
     
            ///На клиенте
            try
            {
                // call service
            }
            catch (FaultException<MyService.MyException> ee)
            {
                //Process the Exception
            }

     

     


    8 декабря 2011 г. 10:11

Все ответы

  • Добрый день.

    Очень просто, создавать свой класс описывающий все нужные вам данные, и использовать FaultContract.

    В общем виде выглядит так:

     

        [DataContract]
        public class MyException
        {
            [DataMember]
            public string Exception;
            [DataMember]
            public string StackTrace;
            [DataMember]
            public string Method;
            [DataMember]
            public int Parameter;
        }
     
        [ServiceContract]
        public interface IMyContract
        {
            [OperationContract]
            [FaultContract(typeof(MyException))]
            int Test(int param);
        }
     
        public class MyService : IMyContract
        {
            public int Test(int param)
            {
                try
                {
                    // process
                }
                catch(Exception ee)
                {
                    MyException myEx = new MyException();
                    myEx.Exception = ee.InnerException.ToString();
                    myEx.StackTrace = ee.StackTrace.ToString();
                    myEx.Method = "Test";
                    myEx.Parameter = param;
                    
                    ///.....
     
                    throw new FaultException<MyException>(myEx, "some comment...");
                }
     
                return 0;
            }
     
     
            ///На клиенте
            try
            {
                // call service
            }
            catch (FaultException<MyService.MyException> ee)
            {
                //Process the Exception
            }

     

     


    8 декабря 2011 г. 10:11
  • > ошибку я отлавливаю и мне нужно дополнить ее кучей дополнительной информации, например какие параметры в метод предавались и т.д. Как передать все это дело на клиента (Silverlight)?
     
     
    как вариант: через out; см. public string Test(out ErrorInfo error);
    ниже пример, который создает хост сервиса в форме.
    в форме также создается браузер, в который загружается .xap-файл (silverlight приложение).
     
     
    [Silverlight - client]

    <UserControl x:Class="SilverlightApplication1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        FontSize="16">
        <StackPanel>
            <Button Content="Test" Click="Test_Click" VerticalAlignment="Top" HorizontalAlignment="Left" />
            <TextBlock x:Name="tb" />
        </StackPanel>
    </UserControl>
    
    
    using System;
    using System.Net;
    using System.Windows.Controls;
    
    namespace SilverlightApplication1
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
            private void Test_Click(object sender, System.Windows.RoutedEventArgs e)
            {
                var c = new WebClient();
                c.UploadStringCompleted += (_s, _e) => 
                    tb.Text = _e.Error == null ? _e.Result : _e.Error.Message + "\n" + _e.Error.InnerException;
                c.UploadStringAsync(new Uri("http://localhost:8845/test/"), "data=123");
            }
        }
    }
    
     
     
    [WinForm - server]

    using System;
    using System.Drawing;
    using System.IO;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication9
    { 
        public partial class Form1 : Form
        {
            public Form1()
            {
                var url = "http://localhost:8845";
                var h = new WebServiceHost(new Service(), new Uri(url));
                h.Open();
                this.FormClosing += (s, e) => h.Close();
                this.Size = new Size(800, 300);
                new WebBrowser { Parent = this, Dock = DockStyle.Fill, }
                    .Navigate(url);
            }
        }
    
        [DataContract]
        public class ErrorInfo
        {
            [DataMember]
            public string Message { get; set; }
            [DataMember]
            public int Type { get; set; }
        }
    
        [ServiceContract, ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        public class Service
        {
            [OperationContract, WebInvoke(UriTemplate = "/test/", Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
            public string Test(out ErrorInfo error)
            {
                error = null;
                var dt = DateTime.Now;
                if (dt.Ticks % 2 == 0)
                    error = new ErrorInfo { Message = "12345", Type = dt.Millisecond };
    
                return dt.Second + "." + dt.Millisecond;
            }
            [OperationContract, WebGet(UriTemplate = "/")]
            public Stream Load()
            {
                var ret = @"
                <html>
                    <head>
                    <script type='text/javascript'>function onSilverlightError(sender, args) { alert(args.ErrorMessage); }</script>
                    </head>
                    <body>
                        <object data='data:application/x-silverlight-2,' type='application/x-silverlight-2' width='100%' height='100%'>
                            <param name='source' value='app.xap'/>
                            <param name='onError' value='onSilverlightError' />
                        </object>
                    </body>
                </html>";
                WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
                return ToStream(ret);
            }
            [OperationContract, WebGet(UriTemplate = "/{app}")]
            public Stream App(string app)
            {
                return File.OpenRead("SilverlightApplication1.xap"); // путь: "\bin\Debug\"
            }
            static Stream ToStream(string s)
            {
                var ret = new MemoryStream();
                var bytes = System.Text.Encoding.Default.GetBytes(s);
                ret.Write(bytes, 0, bytes.Length);
                ret.Position = 0L;
                return ret;
            }
        }
    }
    
    
     

    8 декабря 2011 г. 14:42