wcfria,[Silverlight入门系列]使用WCF Ria Service和Log4net在服务器端记录异常日志/ExceptionLog

本文系Mainz在博客园的原创(http://www.cnblogs.com/mainz/),若您在银光中国(SilverlightChina)或其它网站看到本文,请注意是转载,文中很多链接已经丢失。言归正传,今天谈下在Silverlight中如何进行异常处理,用WCF Ria Service在服务器端记录异常日志,后台用log4net组件处理logging,前台给用户弹出一个友好的框,用户也可以在客户端保存异常log到本地,就这么点内容。废话不说,开始了!
Silverlightwcfria,[Silverlight入门系列]使用WCF Ria Service和Log4net在服务器端记录异常日志/ExceptionLog
1. 后台实现Wcf Ria service + log4net记录异常日志
在SilverlightApplication1.Web项目添加一个空的Domain Service,名字叫LoggingService,里面加一个写一个Invoke的方法。注意这个DomainService需要加[Invoke]属性标明这不是一个Entity相关的操作。详细解释请参考MSDN这个页面。
Silverlightwcfria,[Silverlight入门系列]使用WCF Ria Service和Log4net在服务器端记录异常日志/ExceptionLogSilverlightwcfria,[Silverlight入门系列]使用WCF Ria Service和Log4net在服务器端记录异常日志/ExceptionLogDomain Service 1 [EnableClientAccess()] 2 public class LoggingService : DomainService 3 { 4 [Invoke] 5 public void LogException(string message, string stackTrace) 6 { 7 Logger.LogException(message, stackTrace); 8 } 9 }

2. 后台加个Logger静态类用log4net写log
Logger 1 using log4net; 2 3 public class Logger 4 { 5 static ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 6 7 public static void LogException(string message, string stackTrace) 8 { 9 log.Debug(string.Format("Exception occured: {0}, stack trace: {1}", message, stackTrace)); 10 } 11 12 public static void LogInfo(string info) 13 { 14 log.Info(info); 15 } 16 }

3. 添加log4net的dll引用,web.config配置记录log的log4net部分
首先下载log4net,然后在SilverlightApplication1.Web项目添加log4net的dll引用,添加一个Global.asax,在Global.asax.cs里面添加以下代码来初始化log4net配置:
Global.asax.cs 1 protected void Application_Start(object sender, EventArgs e) 2 { 3 log4net.Config.XmlConfigurator.Configure(); 4 }

配置web.config的log4net部分 1 2 3
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 23 24 25 26 27

4. 前台SilverlightApplication1调用Wcf Ria Service的Domain Context
刚才我们在SilverlightApplication1.Web项目添加了DomainService,编译之后会在有RiaLink的前台项目自动生成客户端代理Generated_Code\*.web.g.cs。如果你有很多WCF Ria Service Class Library,那么需要检查RiaLink,它们之间的对应关系。可以查看项目属性,见下图:
RiaLinkSilverlightwcfria,[Silverlight入门系列]使用WCF Ria Service和Log4net在服务器端记录异常日志/ExceptionLog
我们在App.xaml.cs里面处理UnhandledException:
App.xaml.cs 1 public App() 2 { 3 this.UnhandledException += this.Application_UnhandledException; 4 5 InitializeComponent(); 6 } 7 8 private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) 9 { 10 11 if (!Debugger.IsAttached) 12 { 13 14 //记录log到服务器:调用WCF Ria Service 15 LogExceptionToServer(e.ExceptionObject); 16 17 //弹出用户友好窗口 18 ShowUserFriendlyExceptionWindow(e.ExceptionObject); 19 20 e.Handled = true; 21 22 } 23 24 } 25 26 private void LogExceptionToServer(Exception e) 27 { 28 var logDomainContext = new LoggingContext(); 29 30 logDomainContext.LogException(e.Message, e.StackTrace, 31 invokeOperation => 32 { 33 if (invokeOperation.HasError) 34 { 35 //.... 36 } 37 },null); 38 } 39 40 private void ShowUserFriendlyExceptionWindow(Exception e) 41 { 42 var exceptionDialog = new ExceptionWindow(); 43 exceptionDialog.UserFriendlyException = e.Message; 44 exceptionDialog.DetailedException = e.ToString(); 45 exceptionDialog.Error = e; 46 exceptionDialog.Show(); 47 }

5. 发生未知异常显示用户友好的界面
SilverlightException
如果发生异常显示用户友好的界面,可以保存异常到本地,这个ExceptionWindow的代码如下:
Exception ChildWindow 1 public partial class ExceptionWindow : ChildWindow 2 { 3 private Exception _exception; 4 5 public ExceptionWindow() 6 { 7 InitializeComponent(); 8 } 9 10 public string UserFriendlyException 11 { 12 get { return userFriendlyMessageTextBlock.Text; } 13 set 14 { 15 if (!String.IsNullOrEmpty(value) && value.Length > 65) 16 userFriendlyMessageTextBlock.Text = value.Substring(0, 65) + "..."; 17 else 18 userFriendlyMessageTextBlock.Text = value; 19 } 20 } 21 22 public string DetailedException 23 { 24 get { return detailedInforTextBox.Text; } 25 set { detailedInforTextBox.Text = value; } 26 } 27 28 public Exception Error 29 { 30 set { _exception = value; } 31 } 32 33 private void closeButton_Click(object sender, RoutedEventArgs e) 34 { 35 this.DialogResult = false; 36 } 37 38 private void saveLogButton_Click(object sender, RoutedEventArgs e) 39 { 40 SaveLogOnClientDisc(FormatMessage()); 41 } 42 43 private string FormatMessage() 44 { 45 string originalException = string.Empty; 46 47 if (_exception != null) 48 originalException = _exception.ToString(); 49 50 return string.Format("{0} - {1}\n\nDetailed Message:\n{2}\n\nOriginal Exception:\n{3}", 51 DateTime.Now.ToString(), 52 UserFriendlyException, 53 DetailedException, 54 originalException); 55 } 56 57 private void SaveLogOnClientDisc(string errorMessage) 58 { 59 var saveLogDialog = new SaveFileDialog(); 60 61 saveLogDialog.DefaultExt = ".log"; 62 saveLogDialog.Filter = "Text Files|*.txt|Log Files|*.log|All Files|*.*"; 63 saveLogDialog.FilterIndex = 2; 64 65 bool? dialogResult = saveLogDialog.ShowDialog(); 66 67 if (dialogResult == true) 68 { 69 try 70 { 71 var contents = Encoding.Unicode.GetBytes(errorMessage); 72 73 using (var fileStream = saveLogDialog.OpenFile()) 74 { 75 fileStream.Write(contents, 0, contents.Length); 76 fileStream.Close(); 77 MessageBox.Show("File successfully saved!"); 78 } 79 } 80 catch (Exception ex) 81 { 82 MessageBox.Show("Can't save file: " + ex.Message); 83 } 84 } 85 } 86 }

ExceptionWindow的xaml代码
Exception Window.xaml 1 8 9 10 11 12 13 14 15 21 22 23 29 30 31 32

最新评论

发表评论