C#反序列化null元素

时间:2014-07-02 08:43:19

标签: c# xml deserialization

我正在尝试反序列化以下XML:

@"<Activity type=""WOActivity"">
<ActionID>1</ActionID> 
<ActionLog></ActionLog> 
<ActionLogSummary>Add subcomponent</ActionLogSummary> 
<UserID></UserID> 
<FlexFields> 
    <FlexField mappedTo=""STATUS"" id=""0"">WAPPR</FlexField> 
    <FlexField mappedTo=""WOSEQUENCE"" id=""0"">10</FlexField> 
    <FlexField mappedTo=""OWNERGROUP"" id=""0"">V-PSB-DE-HLC-HWSUPPORT</FlexField> 
</FlexFields> 

我也有以下类,它是由xsd:

生成的
 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2", IsNullable = false)]
public partial class Activity {

    private string actionIDField;

    private string actionLogField;

    private string actionLogSummaryField;

    private System.DateTime logDateTimeField;

    private bool logDateTimeFieldSpecified;

    private System.DateTime scheduledStartDateTimeField;

    private bool scheduledStartDateTimeFieldSpecified;

    private System.DateTime scheduledEndDateTimeField;

    private bool scheduledEndDateTimeFieldSpecified;

    private System.DateTime workBeginDateTimeField;

    private bool workBeginDateTimeFieldSpecified;

    private System.DateTime workEndDateTimeField;

    private bool workEndDateTimeFieldSpecified;

    private string userIDField;

    private string userNameField;

    private FlexFieldsFlexField[] flexFieldsField;

    private string activityTypeField;

    private string typeField;

    private string indexField;

    /// <remarks/>

    public string ActionID {
        get {
            return this.actionIDField;
        }
        set {
            this.actionIDField = value;
        }
    }

    /// <remarks/>
    public string ActionLog {
        get {
            return this.actionLogField;
        }
        set {
            this.actionLogField = value;
        }
    }
    /// <remarks/>
    /// 
    [System.Xml.Serialization.XmlElement]
    public string ActionLogSummary {
        get {
            return this.actionLogSummaryField;
        }
        set {
            this.actionLogSummaryField = value;
        }
    }

    /// <remarks/>
    public System.DateTime LogDateTime {
        get {
            return this.logDateTimeField;
        }
        set {
            this.logDateTimeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool LogDateTimeSpecified {
        get {
            return this.logDateTimeFieldSpecified;
        }
        set {
            this.logDateTimeFieldSpecified = value;
        }
    }

    /// <remarks/>
    public System.DateTime ScheduledStartDateTime {
        get {
            return this.scheduledStartDateTimeField;
        }
        set {
            this.scheduledStartDateTimeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool ScheduledStartDateTimeSpecified {
        get {
            return this.scheduledStartDateTimeFieldSpecified;
        }
        set {
            this.scheduledStartDateTimeFieldSpecified = value;
        }
    }

    /// <remarks/>
    public System.DateTime ScheduledEndDateTime {
        get {
            return this.scheduledEndDateTimeField;
        }
        set {
            this.scheduledEndDateTimeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool ScheduledEndDateTimeSpecified {
        get {
            return this.scheduledEndDateTimeFieldSpecified;
        }
        set {
            this.scheduledEndDateTimeFieldSpecified = value;
        }
    }

    /// <remarks/>
    public System.DateTime WorkBeginDateTime {
        get {
            return this.workBeginDateTimeField;
        }
        set {
            this.workBeginDateTimeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool WorkBeginDateTimeSpecified {
        get {
            return this.workBeginDateTimeFieldSpecified;
        }
        set {
            this.workBeginDateTimeFieldSpecified = value;
        }
    }

    /// <remarks/>
    public System.DateTime WorkEndDateTime {
        get {
            return this.workEndDateTimeField;
        }
        set {
            this.workEndDateTimeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool WorkEndDateTimeSpecified {
        get {
            return this.workEndDateTimeFieldSpecified;
        }
        set {
            this.workEndDateTimeFieldSpecified = value;
        }
    }

    /// <remarks/>
    public string UserID {
        get {
            return this.userIDField;
        }
        set {
            this.userIDField = value;
        }
    }

    /// <remarks/>
    public string UserName {
        get {
            return this.userNameField;
        }
        set {
            this.userNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("FlexField", IsNullable = false)]
    public FlexFieldsFlexField[] FlexFields {
        get {
            return this.flexFieldsField;
        }
        set {
            this.flexFieldsField = value;
        }
    }

    /// <remarks/>
    public string ActivityType {
        get {
            return this.activityTypeField;
        }
        set {
            this.activityTypeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string type {
        get {
            return this.typeField;
        }
        set {
            this.typeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
    public string index {
        get {
            return this.indexField;
        }
        set {
            this.indexField = value;
        }
    }
}

我做了一个单元测试,但它失败了,因为所有元素都是null(第二个断言)。 type属性被反序列化了。

可能出现什么问题?

PS:我曾尝试将命名空间“http://b2b.ibm.com/schema/B2B_CDM_Incident/R2_2”添加到序列化程序中但没有成功...

PS2:序列化似乎对这个类很好用

感谢。

                string result = @"<Activity type=""WOActivity"">
    <ActionID>1</ActionID> 
    <ActionLog></ActionLog> 
    <ActionLogSummary>Add subcomponent</ActionLogSummary> 
    <UserID></UserID> 
    <FlexFields> 
        <FlexField mappedTo=""STATUS"" id=""0"">WAPPR</FlexField> 
        <FlexField mappedTo=""WOSEQUENCE"" id=""0"">10</FlexField> 
        <FlexField mappedTo=""OWNERGROUP"" id=""0"">V-PSB-DE-HLC-HWSUPPORT</FlexField> 
    </FlexFields> 
 </Activity>";
    var serializer = new XmlSerializer(typeof (Activity), new XmlRootAttribute("Activity"));
            var first = (Activity)serializer.Deserialize(new XmlTextReader(new StringReader(result)));
            Assert.AreEqual("WOActivity", first.type);
            Assert.AreEqual("Add subcomponent", first.ActionLogSummary);
            Assert.IsNotNull(first.FlexFields);
            Assert.AreEqual(4, first.FlexFields.Count());

2 个答案:

答案 0 :(得分:1)

只需将根元素放入正确的命名空间:

string xml = @"<Activity type=""WOActivity""
       xmlns=""http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2"">
    ...
    </Activity>";

请注意,因为名称空间是继承的,所以其他所有内容也都使用该元素。

这样可行:

var ser = new XmlSerializer(typeof(Activity));
var activity = (Activity)ser.Deserialize(new StringReader(xml));
System.Console.WriteLine(activity.ActionID);
System.Console.WriteLine(activity.ActionLogSummary);
System.Console.WriteLine(activity.type);

带输出:

1
Add subcomponent
WOActivity

在其他情况下,您可能需要引用多个名称空间,或多次提及相同的名称空间。然后声明别名会很有用;以下内容与本答案中的第一个示例在语义上相同:

string xml = @"<b2b:Activity type=""WOActivity""
       xmlns:b2b=""http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2"">
<b2b:ActionID>1</b2b:ActionID> 
<b2b:ActionLog></b2b:ActionLog> 
<b2b:ActionLogSummary>Add subcomponent</b2b:ActionLogSummary> 
              ...
              </b2b:Activity>";

唯一的区别是我们现在可以使用b2b:作为任何元素的前缀,作为说xmlns=""http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2""的替代方法。另请注意,基于 alias 的命名空间继承,与xmlns=命名空间不同。

答案 1 :(得分:1)

删除两个生成的行:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2", IsNullable = false)]