3

我正在尝试使用 REST API 来通过 httpclient 获取数据,遇到了解析问题,{“第 1 行位置 95 中的错误。期望来自命名空间的元素'工作流'' http://schemas.datacontract.org/2004/07/ '.. 遇到名为 'workflow'、命名空间 '' 的 'Element'。“}

客户端代码是

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);
                });

数据类

/// <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;
        }
    }
}

并且响应xml文件是这种格式

<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>

我可以通过使用 response.Content.ReadAsStringAsync() 获取字符串并将其保存到 xml 文件,然后,我将其反序列化为集合,可以成功,但需要和 serizliazer 的默认命名空间

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

任何人都可以在这方面提供帮助

4

3 回答 3

4

您不应该触摸从 xsd.exe 工具生成的文件。

只需通过设置明确设置您要使用的XmlSerializer而不是DataContractSerializer默认使用XmlMediaTypeFormatterUseXmlSerializer = true

所以你必须像这样创建一个特定的类型格式化程序:

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

并将其用作ReadAsAsync方法的参数:

private async Task<T> ReadAsync<T>(HttpResponseMessage response)
=> await response.Content.ReadAsAsync<T>(formatters);
于 2018-04-20T17:58:57.853 回答
3

您的命名空间不匹配;您的 xml 为原子地址声明了一个命名空间别名( ns2),但集合元素的命名空间仍然为空,因为它不使用该别名(它不是ns2:collection)。xml 错误或代码错误。如果无法更改 xml,则只需将名称空间设置[XmlRoot(...)]为空字符串。如果 C# 正确且 xml 错误,则将其设为命名空间而不是别名:

<collection xmlns="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>

或同样:

<ns2: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>
  </ns2:collection>
于 2013-04-12T10:33:19.910 回答
2

从我的 web api 读取数据时,我遇到了完全相同的问题。为我解决的问题是使用 [DataContract(Namespace="namespacefromyourwebapi")] 属性装饰客户端中的类,并使用 [DataMember] 属性对类中的每个属性进行装饰。

于 2015-04-01T09:43:27.550 回答