通常我们调用一个方法,只要try,catch就可以捕捉到抛出的异常。
然而有时调用不固定的类的方法时,需要使用MethodInfo.Invoke方法。
但是该方法并不会原模原样的把抛出的信息返回,而是返回一个TargetInvocationException异常。
对于解决这个问题,我们可以直接使用该异常的InnerException,就可以获取原来的异常。
我们来实现一个中等异常的解析:
假如我们抛出一个FaultException<ClassName>类型的异常,
可以通过以下代码解析出内部的Class对象。
Code
#region ErrorSerialize
/// <summary>
///
/// </summary>
/// <param name="ex"></param>
/// <param name="pSerializeErrorObject"></param>
/// <returns>"":not serialize object "1":serialize object</returns>
public string SerializeErrorObject(System.Exception ex, ref XmlDocument pSerializeErrorObjectDoc)
{
string vRtn = "";
XmlDocument vSerializeErrorObjectDoc = new XmlDocument();
if (!ex.GetType().FullName.StartsWith("System.ServiceModel.FaultException`1"))
{
return vRtn;
}
Type vType = ex.GetType();
//内部对象存放在FaultException<ClassName>.Detail里
PropertyInfo vPropInfo = vType.GetProperty("Detail");
if (vPropInfo == null)
{
return vRtn;
}
object vSerializeErrorObject = vPropInfo.GetValue(ex, null);
if (vSerializeErrorObject == null)
{
return vRtn;
}
Type vErrorObjectType = vSerializeErrorObject.GetType();
//如果该类型在当前Assembly里不存在,那么在加载dll所对应的程序集里应该有指定的
//如果不存在出错类型,返回该出错信息就没有意义了
if (vErrorObjectType == null)
{
string vTypeName = vSerializeErrorObject.ToString();
vErrorObjectType = this.m_LoadAssembly.GetType(vTypeName);
}
if (vErrorObjectType == null)
{
return vRtn;
}
//String不是值类型,是一个特殊对象
if (vSerializeErrorObject.GetType().FullName.Equals("System.String"))
{
XmlNode vImportNode = (XmlNode)vSerializeErrorObjectDoc.CreateElement("ErrorMsg");
vImportNode.InnerText = vSerializeErrorObject.ToString();
vSerializeErrorObjectDoc.AppendChild(vImportNode);
pSerializeErrorObjectDoc = vSerializeErrorObjectDoc;
vRtn = "1";
}
else if (!vPropInfo.PropertyType.IsValueType)
{
vRtn = SerializeClass(vSerializeErrorObject, ref vSerializeErrorObjectDoc);
pSerializeErrorObjectDoc = vSerializeErrorObjectDoc;
}
return vRtn;
}
#endregion
/// <summary>
/// HAVEN'T args
/// </summary>
/// <returns>valuetype:"" isref:"1"</returns>
public string SerializeClass(object pInstanceObj ,ref XmlDocument pSerializeObject)
{
if (pInstanceObj == null)
{
return "";
}
Type vClassType = pInstanceObj.GetType();
if (vClassType == null)
{
return "";
}
else if (vClassType.IsValueType ||
vClassType.Equals(typeof(string)))
{
return "";
}
XmlSerializer vSerializer = new XmlSerializer(vClassType);
MemoryStream vStream = new MemoryStream();
XmlWriter vWriter = XmlWriter.Create(vStream);
vSerializer.Serialize(vWriter, pInstanceObj);
XmlDocument vSerializeObjectDoc = new XmlDocument();
vStream.Seek(0, SeekOrigin.Begin);
vSerializeObjectDoc.Load(vStream);
vWriter.Close();
vStream.Close();
pSerializeObject = vSerializeObjectDoc;
return "1";
}
#region ErrorSerialize
/// <summary>
///
/// </summary>
/// <param name="ex"></param>
/// <param name="pSerializeErrorObject"></param>
/// <returns>"":not serialize object "1":serialize object</returns>
public string SerializeErrorObject(System.Exception ex, ref XmlDocument pSerializeErrorObjectDoc)
{
string vRtn = "";
XmlDocument vSerializeErrorObjectDoc = new XmlDocument();
if (!ex.GetType().FullName.StartsWith("System.ServiceModel.FaultException`1"))
{
return vRtn;
}
Type vType = ex.GetType();
//内部对象存放在FaultException<ClassName>.Detail里
PropertyInfo vPropInfo = vType.GetProperty("Detail");
if (vPropInfo == null)
{
return vRtn;
}
object vSerializeErrorObject = vPropInfo.GetValue(ex, null);
if (vSerializeErrorObject == null)
{
return vRtn;
}
Type vErrorObjectType = vSerializeErrorObject.GetType();
//如果该类型在当前Assembly里不存在,那么在加载dll所对应的程序集里应该有指定的
//如果不存在出错类型,返回该出错信息就没有意义了
if (vErrorObjectType == null)
{
string vTypeName = vSerializeErrorObject.ToString();
vErrorObjectType = this.m_LoadAssembly.GetType(vTypeName);
}
if (vErrorObjectType == null)
{
return vRtn;
}
//String不是值类型,是一个特殊对象
if (vSerializeErrorObject.GetType().FullName.Equals("System.String"))
{
XmlNode vImportNode = (XmlNode)vSerializeErrorObjectDoc.CreateElement("ErrorMsg");
vImportNode.InnerText = vSerializeErrorObject.ToString();
vSerializeErrorObjectDoc.AppendChild(vImportNode);
pSerializeErrorObjectDoc = vSerializeErrorObjectDoc;
vRtn = "1";
}
else if (!vPropInfo.PropertyType.IsValueType)
{
vRtn = SerializeClass(vSerializeErrorObject, ref vSerializeErrorObjectDoc);
pSerializeErrorObjectDoc = vSerializeErrorObjectDoc;
}
return vRtn;
}
#endregion
/// <summary>
/// HAVEN'T args
/// </summary>
/// <returns>valuetype:"" isref:"1"</returns>
public string SerializeClass(object pInstanceObj ,ref XmlDocument pSerializeObject)
{
if (pInstanceObj == null)
{
return "";
}
Type vClassType = pInstanceObj.GetType();
if (vClassType == null)
{
return "";
}
else if (vClassType.IsValueType ||
vClassType.Equals(typeof(string)))
{
return "";
}
XmlSerializer vSerializer = new XmlSerializer(vClassType);
MemoryStream vStream = new MemoryStream();
XmlWriter vWriter = XmlWriter.Create(vStream);
vSerializer.Serialize(vWriter, pInstanceObj);
XmlDocument vSerializeObjectDoc = new XmlDocument();
vStream.Seek(0, SeekOrigin.Begin);
vSerializeObjectDoc.Load(vStream);
vWriter.Close();
vStream.Close();
pSerializeObject = vSerializeObjectDoc;
return "1";
}