简体   繁体   中英

XML DeSerialization returning Null values

I have a POST method in a web api that has a RequestAppointment paramater. For example:

 // POST: api/RequestAppointment
            public HttpResponseMessage Post([FromBody]RequestAppointment httpRequest)
            {
                var response = Appointment.CreateAppointment(httpRequest);

                return Request.CreateResponse<ResponseRequest>(System.Net.HttpStatusCode.Created, response); 
            } 

RequestAppoint class has this structure:

public partial class RequestAppointment
    {
        public RequestAppointmentAppointmentInformation appointmentInformation { get; set; }      
    }
    public partial class RequestAppointmentAppointmentInformation
    {
        public string AppointmentCcEmail { get; set; }        
        public string ClaimType { get; set; }       
        public RequestAppointmentAppointmentInformationClaimant Claimant { get; set; }

    }
    public partial class RequestAppointmentAppointmentInformationClaimant
    {
        public System.DateTime DateOfBirth { get; set; }        
    }

Two requests are possible to be made: 1st one is :

<RequestAppointment>
  <appointmentInformation>
    <AppointmentCcEmail>x.x.com</AppointmentCcEmail>   
    <ClaimType>A</ClaimType>
    <Claimant>
      <DateOfBirth>1961-12-25</DateOfBirth>
    </Claimant>
  </appointmentInformation>
</RequestAppointment>

2nd Request is:

<RequestAppointment>
  <appointmentInformation>
    <AppointmentCcEmail>x.x.com</AppointmentCcEmail>   
    <ClaimType>A</ClaimType>   
  </appointmentInformation>
</RequestAppointment>

The difference between the two request XML is that #1 has Claimant tag while the #2 does not have.

The 2nd request does not have because the claimant is not supplied when users call the web service from data interface. While the first will always have when Claimant is supplied.

On my testing using Fiddler, my #1 request returns data. That is, it is able to deserialize into the object RequestAppointment, while #2 request returns null values.

What can I do to resolve this issue? The request will always come in those two formats and they will always use the same model structure.

What can I do to solve this issue? I tested the scenario in Fiddler.

First of all, step 1. if you have RequestAppointment XSD file, the best solution is to generate class using xsd.exe see haw to use it , if not you can create XSD yourself and do step 1, or finally you should make changes and point explicit attributes making your class XML serializable. There is a lot of article about it.

This class generated with xsd.exe , I create sample schema from you XML, made changes only in tag <Claimant> making it optional, and class looks like this. Pay attention how tool generates optional field Claimant

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.6.1055.0.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class RequestAppointment {

    private RequestAppointmentAppointmentInformation appointmentInformationField;

    /// <remarks/>
    public RequestAppointmentAppointmentInformation appointmentInformation {
        get {
            return this.appointmentInformationField;
        }
        set {
            this.appointmentInformationField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class RequestAppointmentAppointmentInformation {

    private string appointmentCcEmailField;

    private string claimTypeField;

    private RequestAppointmentAppointmentInformationClaimant claimantField;

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

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

    /// <remarks/>
    public RequestAppointmentAppointmentInformationClaimant Claimant {
        get {
            return this.claimantField;
        }
        set {
            this.claimantField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class RequestAppointmentAppointmentInformationClaimant {

    private System.DateTime dateOfBirthField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(DataType="date")]
    public System.DateTime DateOfBirth {
        get {
            return this.dateOfBirthField;
        }
        set {
            this.dateOfBirthField = value;
        }
    }
}

XSD example

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="RequestAppointment">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="appointmentInformation">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="AppointmentCcEmail" type="xs:string" />
              <xs:element name="ClaimType" type="xs:string" />
              <xs:element name="Claimant" minOccurs="0">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="DateOfBirth" type="xs:date" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Thanks for all your suggestions. They are great! Seyran's answers really proved awesome. But in the case of my question, I solved it by nil="true" (nullable=true) to all the elements. And I used the xsd to generate the classes for my request xml.

Thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM