XML&WCF POST请求:部分参数已读取,其他未读取
XML&WCF POST request: some parameters are read, other not
我在 IIS 服务器上有一个 wcf restful 服务。
我做了一些API,可以叫既发xml又发json。
我制作了我的 C# 类,然后,我正在测试它。使用 JSON 是完美的,但我对 XML 请求仍有一些问题。
我想用 post 发送 xml 这是我发送的 xml:
<?xml version="1.0" encoding="utf-8" ?>
<SetClientiXML
xmlns="http://tempuri.org/">
<dati>
<ArrayOfWrapClienti
xmlns="http://schemas.datacontract.org/2004/07/MultipayOnline"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<WrapClienti>
<CODRETE>0018</CODRETE>
<CODICE>20685</CODICE>
<NOME>A.T.E.R. Azienda Territoriale</NOME>
<INDIRIZZO>PIAZZA POZZA</INDIRIZZO>
<CITTA>Verona</CITTA>
<CAP>37123</CAP>
<PROV>VR</PROV>
<CODICEFISCALE>00223640236</CODICEFISCALE>
<PIVA>223640236</PIVA>
<EMAIL/>
<ESPOSIZ_CONTABILE>937,02</ESPOSIZ_CONTABILE>
<STATO>FALSE</STATO>
</WrapClienti>
</ArrayOfWrapClienti>
</dati>
<retista>3303903</retista>
<hashedString>oklkokokokok</hashedString>
</SetClientiXML>
wcf 读得很好 "retista" 和 "hashedString",但是 "dati" 是空的(0 个元素),而我希望它已经得到我发送的 "wrapClienti" 对象。
这是我的原型 API:
[OperationContract]
[WebInvoke(UriTemplate = "SetClienti.xml", Method = "POST", BodyStyle=WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Xml)]
GenericResponse SetClientiXML(List<WrapClienti> dati, string retista, string hashedString);
所以,问题是列表是空的.. 为什么?如何编写 xml 以使列表可读?
问我是否可以给你更多细节。
更新:更奇怪!!
有了这个xml:
<?xml version="1.0" encoding="utf-8" ?><SetClientiXML xmlns="http://tempuri.org/">
<dati>
<WrapClienti xmlns="http://schemas.datacontract.org/2004/07/MultipayOnline" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CODRETE>0018</CODRETE>
<CODICE>20685</CODICE>
<NOME>A.T.E.R. Azienda Territoriale</NOME>
<INDIRIZZO>PIAZZA POZZA</INDIRIZZO>
<CITTA>Verona</CITTA>
<CAP>37123</CAP>
<PROV>VR</PROV>
<CODICEFISCALE>00223640236</CODICEFISCALE>
<PIVA>223640236</PIVA>
<EMAIL/>
<ESPOSIZ_CONTABILE>937,02</ESPOSIZ_CONTABILE>
<STATO>FALSE</STATO>
</WrapClienti>
</dati>
<retista>3303903</retista>
<hashedString>oklkokokokok</hashedString>
</SetClientiXML>
wcf读取了List的一些属性,其他的..都是nul!!!
我的 WrapClienti 我有很多属性。其中两个是:
private string p_CAP { get; set; }
public string CAP
{
get
{
if (model == null)
return p_CAP.ToSafeString();
else
return this.model.CAP.ToSafeString();
}
set { p_CAP = value; }
}
private string p_PROV { get; set; }
public string PROV
{
get
{
if (model == null)
return p_PROV.ToSafeString();
else
return this.model.PROV.ToSafeString();
}
set { p_PROV = value; }
}
问题是,上面的xml和两个set方法上的两个断点,只调用了PROV的set和CAP的set,没有!!!为什么?现在我真的快疯了...为什么会这样??
这与 XML 中字段的顺序有关。这听起来很奇怪,但是 WCF DataContractSerializer 对字段在 XML 中遇到的顺序真的很挑剔,但更糟糕的是, 与它们在代码中的定义方式相比 。
你看,序列化器希望字段按字母顺序定义,如果你序列化你的 class 的实例,你会发现生成的 XML 字段是按字母顺序排列的.但是,在反序列化时,序列化程序发现您要反序列化的类型具有在 "wrong" 顺序中定义的字段。在这种情况下,行为似乎是随机的,但我认为这与 CAP 应该是遇到的第一个字段,而 PROV 应该是最后一个字段(按字母顺序排列)这一事实有关。
所以你有两个选择:
重新排序您的 XML 和 class 中的字段以按字母顺序排列,或者
用 DataMemeber 属性 装饰你的 class 成员,并定义序列化的顺序。
你可以这样做 2:
[DataContract]
public class WrapClienti
{
[DataMember(Order=1)]
public string CAP { get; set; }
[DataMember(Order=2)]
public string PROV { get; set; }
...etc
}
我在 IIS 服务器上有一个 wcf restful 服务。
我做了一些API,可以叫既发xml又发json。
我制作了我的 C# 类,然后,我正在测试它。使用 JSON 是完美的,但我对 XML 请求仍有一些问题。
我想用 post 发送 xml 这是我发送的 xml:
<?xml version="1.0" encoding="utf-8" ?>
<SetClientiXML
xmlns="http://tempuri.org/">
<dati>
<ArrayOfWrapClienti
xmlns="http://schemas.datacontract.org/2004/07/MultipayOnline"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<WrapClienti>
<CODRETE>0018</CODRETE>
<CODICE>20685</CODICE>
<NOME>A.T.E.R. Azienda Territoriale</NOME>
<INDIRIZZO>PIAZZA POZZA</INDIRIZZO>
<CITTA>Verona</CITTA>
<CAP>37123</CAP>
<PROV>VR</PROV>
<CODICEFISCALE>00223640236</CODICEFISCALE>
<PIVA>223640236</PIVA>
<EMAIL/>
<ESPOSIZ_CONTABILE>937,02</ESPOSIZ_CONTABILE>
<STATO>FALSE</STATO>
</WrapClienti>
</ArrayOfWrapClienti>
</dati>
<retista>3303903</retista>
<hashedString>oklkokokokok</hashedString>
</SetClientiXML>
wcf 读得很好 "retista" 和 "hashedString",但是 "dati" 是空的(0 个元素),而我希望它已经得到我发送的 "wrapClienti" 对象。 这是我的原型 API:
[OperationContract]
[WebInvoke(UriTemplate = "SetClienti.xml", Method = "POST", BodyStyle=WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Xml)]
GenericResponse SetClientiXML(List<WrapClienti> dati, string retista, string hashedString);
所以,问题是列表是空的.. 为什么?如何编写 xml 以使列表可读?
问我是否可以给你更多细节。
更新:更奇怪!!
有了这个xml:
<?xml version="1.0" encoding="utf-8" ?><SetClientiXML xmlns="http://tempuri.org/">
<dati>
<WrapClienti xmlns="http://schemas.datacontract.org/2004/07/MultipayOnline" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CODRETE>0018</CODRETE>
<CODICE>20685</CODICE>
<NOME>A.T.E.R. Azienda Territoriale</NOME>
<INDIRIZZO>PIAZZA POZZA</INDIRIZZO>
<CITTA>Verona</CITTA>
<CAP>37123</CAP>
<PROV>VR</PROV>
<CODICEFISCALE>00223640236</CODICEFISCALE>
<PIVA>223640236</PIVA>
<EMAIL/>
<ESPOSIZ_CONTABILE>937,02</ESPOSIZ_CONTABILE>
<STATO>FALSE</STATO>
</WrapClienti>
</dati>
<retista>3303903</retista>
<hashedString>oklkokokokok</hashedString>
</SetClientiXML>
wcf读取了List的一些属性,其他的..都是nul!!!
我的 WrapClienti 我有很多属性。其中两个是:
private string p_CAP { get; set; }
public string CAP
{
get
{
if (model == null)
return p_CAP.ToSafeString();
else
return this.model.CAP.ToSafeString();
}
set { p_CAP = value; }
}
private string p_PROV { get; set; }
public string PROV
{
get
{
if (model == null)
return p_PROV.ToSafeString();
else
return this.model.PROV.ToSafeString();
}
set { p_PROV = value; }
}
问题是,上面的xml和两个set方法上的两个断点,只调用了PROV的set和CAP的set,没有!!!为什么?现在我真的快疯了...为什么会这样??
这与 XML 中字段的顺序有关。这听起来很奇怪,但是 WCF DataContractSerializer 对字段在 XML 中遇到的顺序真的很挑剔,但更糟糕的是, 与它们在代码中的定义方式相比 。
你看,序列化器希望字段按字母顺序定义,如果你序列化你的 class 的实例,你会发现生成的 XML 字段是按字母顺序排列的.但是,在反序列化时,序列化程序发现您要反序列化的类型具有在 "wrong" 顺序中定义的字段。在这种情况下,行为似乎是随机的,但我认为这与 CAP 应该是遇到的第一个字段,而 PROV 应该是最后一个字段(按字母顺序排列)这一事实有关。
所以你有两个选择:
重新排序您的 XML 和 class 中的字段以按字母顺序排列,或者
用 DataMemeber 属性 装饰你的 class 成员,并定义序列化的顺序。
你可以这样做 2:
[DataContract]
public class WrapClienti
{
[DataMember(Order=1)]
public string CAP { get; set; }
[DataMember(Order=2)]
public string PROV { get; set; }
...etc
}