我们有一些代码表现出一些奇怪的行为。它与第三方组件交互,这可能是罪魁祸首。为了调试这个,我添加了一个方法,将所有对第三方组件的调用记录为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[] {}));
}
}
}
}