Rest – ReadAsAsync,Expecting element from namespace ‘http://schemas.datacontract.org/2004/07/”,Encountered ‘Element’ with name ‘workflow’, namespace ”

httpclientrestserializationwcfxml-serialization

I am trying to consume a REST API to Get data by httpclient, encountered a parsing problem ,{"Error in line 1 position 95. Expecting element 'workflow' from namespace 'http://schemas.datacontract.org/2004/07/'.. Encountered 'Element' with name 'workflow', namespace ''. "}

the client code is

string baseUri = "/rest/workflows/";
            client = CreateClient(baseUri);

            HttpRequestMessage request = CreateRequest(baseUri);
            var task = client.SendAsync(request);
            HttpResponseMessage response = task.Result;
            response.EnsureSuccessStatusCode();

            response.Content.ReadAsAsync<collection>().ContinueWith(wf =>
                {
                    Console.WriteLine(wf.Result.workflow.Length);
                });

the data classes

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2005/Atom", IsNullable = false)]
public partial class collection
{

    private workflow[] workflowField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("workflow", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public workflow[] workflow
    {
        get
        {
            return this.workflowField;
        }
        set
        {
            this.workflowField = value;
        }
    }
}

and the response xml file is in this format

<collection xmlns:ns2="http://www.w3.org/2005/Atom">
    <workflow uuid="5ffbde8c-c430-4851-9c83-164c102a4d68">
        <name>Remove a Volume</name>
        <categories>
            <category>Decommissioning</category>
        </categories>
    </workflow>
  </collection>

I can get the string by using response.Content.ReadAsStringAsync() and save it to xml file, then ,i deserilize it to collection,can succeed ,but need and a default namespace to the serizliazer

XmlSerializer serializer = new XmlSerializer(typeof(collection), "xmlns:ns2=\"http://www.w3.org/2005/Atom\"");
            c = serializer.Deserialize(stream) as collection;

anyone can help on this

Best Answer

You should not touch the generated file from xsd.exe tool.

Just explicitly set that you want to use the XmlSerializer instead of the DataContractSerializer used by default with XmlMediaTypeFormatter by setting UseXmlSerializer = true.

So you must create a specific type formatter like this :

var formatters = new List<MediaTypeFormatter>() {
                new XmlMediaTypeFormatter(){ UseXmlSerializer = true } };

And use it as a parameter of the ReadAsAsync method :

private async Task<T> ReadAsync<T>(HttpResponseMessage response)
=> await response.Content.ReadAsAsync<T>(formatters);
Related Topic