如何解析 ODATA 错误
How To Parse ODATA Error
<?xml version="1.0" encoding="utf-8"?>
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code />
<m:message xml:lang="en-US">An error occurred while processing this request.</m:message>
<m:innererror>
<m:message>Exception has been thrown by the target of an invocation.</m:message>
<m:type>System.Reflection.TargetInvocationException</m:type>
<m:stacktrace></m:stacktrace>
<m:internalexception>
<m:message>An error occurred while executing the command definition. See the inner exception for details.</m:message>
<m:type>System.Data.Entity.Core.EntityCommandExecutionException</m:type>
<m:stacktrace></m:stacktrace>
<m:internalexception>
<m:message>Cannot insert duplicate key row in object 'XXXX' with unique index 'XXXXXX'. The duplicate key value is (XXXXX)</m:message>
<m:type>System.Data.SqlClient.SqlException</m:type>
<m:stacktrace></m:stacktrace>
</m:internalexception>
</m:internalexception>
</m:innererror>
</m:error>" System.Data.Services.Client.DataServiceClientException
我有一个从 WEB API 2 ODATA 源返回的 XML 结构。我需要在服务器上解析此错误,然后将一个新错误传递给 client.I 已尝试将其反序列化为各种异常类型,但 Exception Implement IDICTIONARY 阻止了这一点。如何将其反序列化为强类型对象?
如果上面的问题不容易解决,我想我的另一个问题是what is best practice for handling these errors
关于如何处理您收到的这些错误消息,我的建议是创建一个外观相似的 class 结构,而不是尝试将信息序列化到 Exception
对象中。
这为您提供了更多的灵活性,以防您的 XML 源决定更改其错误消息的结构,而不是基于异常的结构,此外,它还删除了尝试找出如何反序列化 Exception 对象的要求(根据一些搜索,这有点复杂)。
所以使用Visual Studio中的工具将XML文本转换成C#classes(在Edit下找到=>Paste Special => Paste XML as 类),得到下面的class结构
实际结构是根据该工具生成的内容修改的,因为它喜欢使 classes 膨胀很多。
[XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
[XmlRootAttribute(ElementName = "error", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata", IsNullable = false)]
public partial class ODATAException
{
public string code { get; set; }
public ODATAErrorMessage message { get; set; }
public ODATAInternalException innererror { get; set; }
}
[XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
public partial class ODATAErrorMessage
{
[XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/XML/1998/namespace")]
public string lang { get; set; }
[XmlTextAttribute()]
public string Value { get; set; }
}
[XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
public partial class ODATAInternalException
{
public string message { get; set; }
public string type { get; set; }
public string stacktrace { get; set; }
public ODATAInternalException internalexception { get; set; }
}
利用这个 class 结构,您可以轻松地将收到的 XML 反序列化为强类型对象,并以您喜欢的任何方式进一步使用它。
using (TextReader sampleTextReader = new StringReader(txtInput.Text)) // Change this whereever you get the XML string from
{
XmlSerializer sampleXmlSeri = new XmlSerializer(typeof(ODATAException));
ODATAException newExc = sampleXmlSeri.Deserialize(sampleTextReader) as ODATAException;
if (newExc != null)
{
// Do something with the error
}
}
您现在还可以自由地为变量提供任何更能描述 yourself/your 团队的名称,并使用 XmlElement
属性将您的属性 link 设置为内部的实际名称XML.
关于使异常可序列化,还有一个非常有趣和好的 Q/A,我也推荐阅读:
What is the correct way to make a custom .NET Exception serializable?
<?xml version="1.0" encoding="utf-8"?>
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code />
<m:message xml:lang="en-US">An error occurred while processing this request.</m:message>
<m:innererror>
<m:message>Exception has been thrown by the target of an invocation.</m:message>
<m:type>System.Reflection.TargetInvocationException</m:type>
<m:stacktrace></m:stacktrace>
<m:internalexception>
<m:message>An error occurred while executing the command definition. See the inner exception for details.</m:message>
<m:type>System.Data.Entity.Core.EntityCommandExecutionException</m:type>
<m:stacktrace></m:stacktrace>
<m:internalexception>
<m:message>Cannot insert duplicate key row in object 'XXXX' with unique index 'XXXXXX'. The duplicate key value is (XXXXX)</m:message>
<m:type>System.Data.SqlClient.SqlException</m:type>
<m:stacktrace></m:stacktrace>
</m:internalexception>
</m:internalexception>
</m:innererror>
</m:error>" System.Data.Services.Client.DataServiceClientException
我有一个从 WEB API 2 ODATA 源返回的 XML 结构。我需要在服务器上解析此错误,然后将一个新错误传递给 client.I 已尝试将其反序列化为各种异常类型,但 Exception Implement IDICTIONARY 阻止了这一点。如何将其反序列化为强类型对象?
如果上面的问题不容易解决,我想我的另一个问题是what is best practice for handling these errors
关于如何处理您收到的这些错误消息,我的建议是创建一个外观相似的 class 结构,而不是尝试将信息序列化到 Exception
对象中。
这为您提供了更多的灵活性,以防您的 XML 源决定更改其错误消息的结构,而不是基于异常的结构,此外,它还删除了尝试找出如何反序列化 Exception 对象的要求(根据一些搜索,这有点复杂)。
所以使用Visual Studio中的工具将XML文本转换成C#classes(在Edit下找到=>Paste Special => Paste XML as 类),得到下面的class结构
实际结构是根据该工具生成的内容修改的,因为它喜欢使 classes 膨胀很多。
[XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
[XmlRootAttribute(ElementName = "error", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata", IsNullable = false)]
public partial class ODATAException
{
public string code { get; set; }
public ODATAErrorMessage message { get; set; }
public ODATAInternalException innererror { get; set; }
}
[XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
public partial class ODATAErrorMessage
{
[XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/XML/1998/namespace")]
public string lang { get; set; }
[XmlTextAttribute()]
public string Value { get; set; }
}
[XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
public partial class ODATAInternalException
{
public string message { get; set; }
public string type { get; set; }
public string stacktrace { get; set; }
public ODATAInternalException internalexception { get; set; }
}
利用这个 class 结构,您可以轻松地将收到的 XML 反序列化为强类型对象,并以您喜欢的任何方式进一步使用它。
using (TextReader sampleTextReader = new StringReader(txtInput.Text)) // Change this whereever you get the XML string from
{
XmlSerializer sampleXmlSeri = new XmlSerializer(typeof(ODATAException));
ODATAException newExc = sampleXmlSeri.Deserialize(sampleTextReader) as ODATAException;
if (newExc != null)
{
// Do something with the error
}
}
您现在还可以自由地为变量提供任何更能描述 yourself/your 团队的名称,并使用 XmlElement
属性将您的属性 link 设置为内部的实际名称XML.
关于使异常可序列化,还有一个非常有趣和好的 Q/A,我也推荐阅读:
What is the correct way to make a custom .NET Exception serializable?