如何解析 ODATA 错误


<?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

我有这个XML结构从WEB API 2 ODATA源返回。我需要在服务器上解析此错误,然后将新错误传递给客户端。我尝试将其反序列化为各种异常类型,但是异常实现 IDICTIONARY 的事实阻止了这一点。如何将其反序列化为强类型对象?

如果以上不容易下来,我想我的另一个问题是what is best practice for handling these errors

关于如何处理您收到的这些错误消息,我的建议是创建一个外观相似的类结构,而不是尝试将信息序列化为 Exception 对象。

这为您提供了更大的灵活性,以防 XML 的源决定更改其错误消息的结构而不是基于异常的结构,此外,它还消除了尝试并弄清楚如何反序列化异常对象的要求(根据一些搜索,这有点复杂)。

因此,使用 Visual Studio 中的工具将 XML 文本转换为 C# 类(位于"编辑 =>选择性粘贴 => 将 XML 粘贴为类"下),将获得以下类结构。
实际结构是从该工具生成的结构修改的,因为它喜欢使类膨胀很多。

[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; }
}

利用此类结构,您可以轻松地将接收到的 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
  }
}

现在,您还可以自由地为变量指定任何对您/您的团队更具描述性的名称,并使用 XmlElement 属性将您的属性链接到 XML 中的实际名称。

还有一个

关于使异常可序列化的非常有趣和很好的问答,我也建议阅读:
使自定义 .NET 异常可序列化的正确方法是什么?

最新更新