我正在尝试使用REST API来通过httpclient获取数据,遇到解析问题,{“第1行中的错误位置95.期望来自命名空间'http://schemas.datacontract.org/2004/07/的元素'工作流''遇到'元素'with name'workflow',namespace''。“}
客户端代码是
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文件中,然后,我将其deserilize为集合,可以成功,但需要和serizliazer的默认命名空间
XmlSerializer serializer = new XmlSerializer(typeof(collection), "xmlns:ns2=\"http://www.w3.org/2005/Atom\"");
c = serializer.Deserialize(stream) as collection;
任何人都可以提供帮助
答案 0 :(得分:4)
您不应该从xsd.exe工具触摸生成的文件。
通过设置XmlSerializer
,明确设置您要使用DataContractSerializer
代替XmlMediaTypeFormatter
默认使用的UseXmlSerializer = 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);
答案 1 :(得分:3)
您的命名空间不匹配;你的xml为原子地址声明一个名称空间别名(ns2
),但是collection元素的名称空间仍然是空的,因为它不使用别名(不是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>
答案 2 :(得分:1)
从网络API中读取数据时,我遇到了完全相同的问题。解决这个问题的方法是使用[DataContract(Namespace =&#34; namespacefromyourwebapi&#34;)]属性在客户端中修饰类,并为类中的每个属性用[DataMember]属性修饰它。