【问题标题】:DataContractSerializer returning null for all values when using CollectionDataContract使用 CollectionDataContract 时 DataContractSerializer 为所有值返回 null
【发布时间】:2018-01-25 17:20:12
【问题描述】:

我这里引用了一些数据http://docs.microsofttranslator.com/text-translate.html#!/default/post_TranslateArray

<ArrayOfTranslateArrayResponse 
    xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2" 
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <TranslateArrayResponse>
        <From>en</From>
        <OriginalTextSentenceLengths 
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>14</a:int>
        </OriginalTextSentenceLengths>
        <TranslatedText>Esto es una prueba</TranslatedText>
        <TranslatedTextSentenceLengths 
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>18</a:int>
        </TranslatedTextSentenceLengths>
    </TranslateArrayResponse>
    <TranslateArrayResponse>
        <From>en</From>
        <OriginalTextSentenceLengths 
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>22</a:int>
        </OriginalTextSentenceLengths>
        <TranslatedText>Hola, yo tengo una manzana</TranslatedText>
        <TranslatedTextSentenceLengths 
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>26</a:int>
        </TranslatedTextSentenceLengths>
    </TranslateArrayResponse>
</ArrayOfTranslateArrayResponse>

我正在尝试使用 DataContractSerializer 反序列化此数据。集合中的所有值均为空。我可以使用相同的结构进行序列化,结果与本文相同,但不会反序列化。这是代码。

void Main()
{
    var xmlString = "<ArrayOfTranslateArrayResponse xmlns=\"http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><TranslateArrayResponse><From>language-code</From><OriginalTextSentenceLengths xmlns:a=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\"><a:int>int-value</a:int></OriginalTextSentenceLengths><State/><TranslatedText>string-value</TranslatedText><TranslatedTextSentenceLengths xmlns:a=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\"><a:int>int-value</a:int></TranslatedTextSentenceLengths></TranslateArrayResponse></ArrayOfTranslateArrayResponse>";
    var dcs = new DataContractSerializer(typeof(TranslateArrayResponseCollection));

    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    {
        writer.Write(xmlString);
        writer.Flush();
        stream.Position = 0;

        dcs.ReadObject(stream).Dump();
    }
}

[CollectionDataContract(Name = "ArrayOfTranslateArrayResponse", Namespace = "http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2")]
public class TranslateArrayResponseCollection : List<TranslateArrayResponse> { }

[DataContract(Name = "TranslateArrayResponse", Namespace = "")]
public class TranslateArrayResponse
{
    [DataMember]
    public string Error { get; set; }

    [DataMember]
    public string From { get; set; }

    [DataMember]
    public int[] OriginalSentenceLengths { get; set; }

    [DataMember]
    public string TranslatedText { get; set; }

    [DataMember]
    public int[] TranslatedSentenceLengths { get; set; }

    [DataMember]
    public string State { get; set; }
}

【问题讨论】:

  • 尝试使用docs.microsoft.com/en-us/dotnet/framework/wcf/…自动生成数据类并检查名称/命名空间的差异在哪里。
  • 这是一个非常酷的功能!但它对我没有任何作用。我正在使用 .NET Core 2.0 项目,所以也许这就是它不起作用的原因。
  • 该页面某处有一条评论,它仅适用于 .net 4.5 项目。因此,您需要打开新的 4.5 项目,从 xml 创建类并将文件复制到您的原始项目中。不过有点乱。我不明白为什么 MS 设置了这个限制。

标签: c# serialization datacontractserializer


【解决方案1】:

在您的 XML 数据数组中命名为 OriginalTextSentenceLengths 和 TranslatedTextSentenceLengths。但在您的数据合同中,它们是OriginalSentenceLengths 和TranslatedSentenceLengths。您应该在数据合同中重命名它们:

[DataMember]
public string TranslatedText { get; set; }

[DataMember]
public int[] TranslatedTextSentenceLengths { get; set; }

另一个问题是缺少元素的命名空间。在我向所有元素添加空命名空间xmlns="" 后,数据被正确反序列化。这是修改后的 XML:

<ArrayOfTranslateArrayResponse 
    xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2" 
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <TranslateArrayResponse>
        <From xmlns="">en</From>
        <OriginalTextSentenceLengths xmlns=""
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>14</a:int>
        </OriginalTextSentenceLengths>
        <TranslatedText xmlns="">Esto es una prueba</TranslatedText>
        <TranslatedTextSentenceLengths xmlns=""
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>18</a:int>
        </TranslatedTextSentenceLengths>
    </TranslateArrayResponse>
    <TranslateArrayResponse>
        <From xmlns="">en</From>
        <OriginalTextSentenceLengths xmlns=""
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>22</a:int>
        </OriginalTextSentenceLengths>
        <TranslatedText xmlns="">Hola, yo tengo una manzana</TranslatedText>
        <TranslatedTextSentenceLengths xmlns=""
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a:int>26</a:int>
        </TranslatedTextSentenceLengths>
    </TranslateArrayResponse>
</ArrayOfTranslateArrayResponse>

我认为这是DataContractSerializer 的限制。检查此question 与完全相同的问题。您应该通过添加命名空间来修改源 XML,或者使用应该处理这种情况的 XmlSerializer。

【讨论】:

  • 抱歉,这是该链接中的示例。我输入了现在从服务返回给我的实际文本。
  • 您的文字也适用于我,但不是服务返回的实际文字。
  • 谢谢。这真的很糟糕。我确实看到 DCS 也会生成所有空的命名空间。我真的希望只有一些对象,但看起来我必须改用XmlSerializer 或XElement。
猜你喜欢
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 2020-11-04
  • 2021-04-14
  • 2021-07-02
  • 1970-01-01
  • 2017-10-26
  • 2021-05-09
相关资源
最近更新 更多