如何在序列化时忽略错误?

时间:2013-12-13 14:56:17

标签: c# serialization

我们有一些代码表现出一些奇怪的行为。它与第三方组件交互,这可能是罪魁祸首。为了调试这个,我添加了一个方法,将所有对第三方组件的调用记录为XML。该方法如下所示:

    protected override void OnUnload(EventArgs e)
    {
        if (_twLog != null)
        {
            _twLog.Flush();
            _twLog.Close(); 
            _twLog.Dispose();
        }
        _twLogDisposed = true;

        base.OnUnload(e);
    }

    private TextWriter _twLog;
    private bool _twLogDisposed;
    private void Log(string methodName, object returnValue, object[] paramaters)
    {
        if (!_twLogDisposed && Directory.Exists(HttpContext.Current.Server.MapPath("~/crmlogs/")))
        {
            if (_twLog == null)
            {
                string path =
                    HttpContext.Current.Server.MapPath("~/crmlogs/" + HttpContext.Current.Request.UserHostAddress.Replace(":",string.Empty) +".xml");
                _twLog = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write));
            }

object returnValueToSerialize = returnValue;                 if(returnValue是DataTable)                 {                     StringWriter sw = new StringWriter();                     ((数据表)的returnValue).WriteXml(SW);                     returnValueToSerialize = sw.ToString();                     sw.Dispose();                 }

            var crmEvent = new CrmEvent(methodName, returnValueToSerialize, paramaters);
            var xs = new XmlSerializer(typeof (CrmEvent));
            xs.Serialize(_twLog, crmEvent);
        }
    }

    public class CrmEvent
    {
        public CrmEvent()
        {
        }

        public CrmEvent(string methodName, object returnValue, object[] paramaters)
        {
            MethodName = methodName;
            ReturnValue = returnValue ?? string.Empty;
            Paramaters = paramaters;
            Date = DateTime.Now;
        }
        public string MethodName { get; set; }
        public object ReturnValue { get; set; }
        public object[] Paramaters { get; set; }
        public DateTime Date { get; set; }
    }

我已经使用正则表达式进行了查找和替换,并确保在每次调用组件后调用此方法。我唯一关心的是这个组件是否返回无法序列化的对象。如果发生这种情况,我想记录尽可能多的数据,而不仅仅是失败。这样做的最佳方式是什么?

谢谢,

好的,这是我的丑陋,因为地狱解决方案似乎有效。希望有更好的方法来做到这一点。

    private void Log(string methodName, object returnValue, object[] paramaters)
    {
            if (!_twLogDisposed && Directory.Exists(HttpContext.Current.Server.MapPath("~/crmlogs/")))
            {
                if (_twLog == null)
                {
                    string path =
                        HttpContext.Current.Server.MapPath("~/crmlogs/" +
                                                           HttpContext.Current.Request.UserHostAddress.Replace(":",
                                                                                                               string
                                                                                                                   .Empty) +
                                                           ".xml");
                    _twLog = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write));
                }

                object returnValueToSerialize;
                try
                {
                    var sw = new StringWriter();
                    if (returnValue is DataTable)
                    {
                        var dt = (DataTable) returnValue;
                        if (string.IsNullOrEmpty(dt.TableName))
                        {
                            dt.TableName = "tempname"; // WriteXml requires this to be set
                        }
                        dt.WriteXml(sw);

                    }
                    else
                    {
                        var retValXs = new XmlSerializer(returnValue.GetType());
                        retValXs.Serialize(sw, returnValue);
                    }

                    returnValueToSerialize = sw.ToString();
                    sw.Dispose();
                }
                catch (Exception ex)
                {
                    returnValueToSerialize = "Could not seriaize " + returnValue.GetType().Name + ": " + ex.Message;
                }


                var crmEvent = new CrmEvent(methodName, returnValueToSerialize, paramaters);
                var xs = new XmlSerializer(typeof (CrmEvent));
                try
                {
                    xs.Serialize(_twLog, crmEvent);
                }
                catch
                {
                    // Because we handle un serializable returnvalues above this must be an unserializable paramater
                    for (int i = 0; i < crmEvent.Paramaters.Length; i++)
                    {
                        var curParam = crmEvent.Paramaters[i];
                        if (!curParam.GetType().IsPrimitive)
                        {
                            var xsParam = new XmlSerializer(curParam.GetType());
                            var sw = new StringWriter();
                            try
                            {
                                xsParam.Serialize(sw, curParam);
                                crmEvent.Paramaters[i] = sw.ToString();
                            }
                            catch (Exception ex)
                            {
                                crmEvent.Paramaters[i] = "Could not seriaize " + curParam.GetType().Name + ": " +
                                                         ex.Message;
                            }
                        }
                    }
                    try
                    {
                        xs.Serialize(_twLog, crmEvent);
                    }
                    catch
                    {
                        xs.Serialize(_twLog, new CrmEvent(methodName, "Error serializing", new object[] {}));
                    }
                }


            }
    }

0 个答案:

没有答案