1

I am writing a simple API using .Net's Web API. I have defined the following Model:

public class VehicleUpdate
{
    [Required(ErrorMessage = "DealerID Required")]
    public int DealerID { get; set; }

    [Required(ErrorMessage = "VIN Required")]
    [StringLength(17, ErrorMessage = "VIN Must be 17 characters", MinimumLength = 17)]
    public string VIN { get; set; }

    [StringLength(8000, ErrorMessage = "Comments must be less than 8,000 characters")]
    public string Comments { get; set; }

    public double Retail { get; set; }
}

I tried to test it by doing an HTTP Post with the following XML

<VehicleUpdate>
    <DealerID>30</DealerID>
    <VIN>1FMRU17L0WLA62356</VIN>
    <Comments>This is a test.</Comments>
    <Retail>1000</Retail>
</VehicleUpdate>

When I do this, I get the following SerializationException:

System.Runtime.Serialization.SerializationException: Error in line 1 position 16. Expecting element 'VehicleUpdate' from namespace 'http://schemas.datacontract.org/2004/07/API.Models'.. Encountered 'Element' with name 'VehicleUpdate', namespace ''. at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlReader reader) at System.Net.Http.Formatting.XmlMediaTypeFormatter.<>c_DisplayClass3.b_2()

Can someone please tell me what I am doing wrong? I thought this would be a valid XML message.

2 Answers 2

6

Two things:

AS the error says, DataContractSerializer expects the XML to provide a proper namespace, and your XML doesn't have it. You can either pass the namespace:

<VehicleUpdate xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/API.Models">
 // properties
</VehicleUpdate>

Or switch to XmlSerializer in your Web API configuration:

config.Formatters.XmlFormatter.UseXmlSerializer = true;

Then you can pass the exact XML you are passing now.

You might run into another issue, when using [Required] on non nullable type i.e. int. This is a known problem since int will be always 0 instead of null if not passsed. In that case you might have to change your model to have excplicit DataContract definition:

  [DataContract]
    public class VehicleUpdate
    {
        [DataMember(IsRequired = true)]
        [Required(ErrorMessage = "DealerID Required")]
        public int DealerID { get; set; }

        [DataMember]
        [Required(ErrorMessage = "VIN Required")]
        [StringLength(17, ErrorMessage = "VIN Must be 17 characters", MinimumLength = 17)]
        public string VIN { get; set; }

        [DataMember]
        [StringLength(8000, ErrorMessage = "Comments must be less than 8,000 characters")]
        public string Comments { get; set; }

        [DataMember]
        public double Retail { get; set; }
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I added a reference and using statement to System.Runtime.Serialization
Then I updated my model with the DataContract and DataMember declarations and it worked. Thanks!
2
public static class WebApiConfig
    {
//....
        public static void Register(HttpConfiguration config)
        {  config.Formatters.XmlFormatter.UseXmlSerializer = true;
        GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling =
        Newtonsoft.Json.PreserveReferencesHandling.Objects;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.