【问题标题】:DataContract won't deserialize Id DataMemberDataContract 不会反序列化 Id DataMember
【发布时间】:2016-06-03 04:59:41
【问题描述】:

使用 DataContract 序列化程序时,它无法反序列化 Id 值,如下例所示:

using System;
using System.Runtime.Serialization;
using System.Xml.Linq;

public class Program
{
    private const string SAMPLE_VALIDATION_RESULT_XML = @"    <ValidationResult>
      <Message>The FooBar record has duplicate key values.</Message>
      <Id>Microsoft.LightSwitch.EntityObject.DuplicateKey</Id>
      <Target>http://localhost:55815/ApplicationData.svc/FooBar(0)</Target>
    </ValidationResult>";

    [DataContract(Name = "ValidationResult", Namespace = "")]
    public class ValidationResult
    {
        [DataMember]
        public string Message { get; set; }
        [DataMember]
        public string Id { get; set; }
        [DataMember]
        public string Target { get; set; }
    }


    public static void Main()
    {
        var doc = XDocument.Parse(SAMPLE_VALIDATION_RESULT_XML);
        using (var reader = doc.CreateReader())
        {
            reader.MoveToContent();
            var res = (new DataContractSerializer(typeof(ValidationResult))).ReadObject(reader) as ValidationResult;
            Console.WriteLine($"res.Id = \"{res.Id}\", expected \"Microsoft.LightSwitch.EntityObject.DuplicateKey\"");
        }
    }
}

我猜这与参照完整性功能有关,但我只找到了一个禁用该功能的选项(在 DataContractSerializer 上),它不影响结果。

我无法更改 Id 字段的名称,因为它是第三方 API,我该如何访问该值?

【问题讨论】:

  • 此代码ReadObject(reader) as ValidationResult 被视为错误格式。由于您知道它始终是 ValidationResult,因此您应该使用显式转换。

标签: c# datacontractserializer


【解决方案1】:

指定成员的顺序

[DataContract(Name = "ValidationResult", Namespace = "")]
public class ValidationResult
{
    [DataMember(Order = 0)]
    public string Message { get; set; }
    [DataMember(Order = 1)]
    public string Id { get; set; }
    [DataMember(Order = 2)]
    public string Target { get; set; }
}

如果不指定顺序,DataContractSerializer 预计成员将按字母顺序排列。见Basic rules。很明显,服务提供者建立的顺序。所以你必须指定它。

【讨论】:

  • 这似乎有点脆弱 - 我不确定 API 提供者是否会始终以正确的顺序返回它们。
  • 呃,太糟糕了。我很惊讶他们添加了这个限制。
【解决方案2】:

改用这个。 XmlSerializer 不关心顺序。

var xml = new XmlSerializer(typeof(ValidationResult));
var res = (ValidationResult)xml.Deserialize(reader);

【讨论】:

  • 我可能会使用这种方法,但是,我将另一种方法标记为答案,因为它回答了隐含的问题(“为什么这不起作用?”)。
  • 我也会这样做。我的回答,无论多么有用,都是一种变通方法。
猜你喜欢
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多