t;remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string name1 {
get {
return this.name1Field;
}
set {
this.name1Field = value;
}
}
/// <remarks/>
public string name2 {
get {
return this.name2Field;
}
set {
this.name2Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string name3 {
get {
return this.name3Field;
}
set {
this.name3Field = value;
}
}
/// <remarks/>
public string name4 {
get {
return this.name4Field;
}
set {
this.name4Field = value;
}
}
}
分析:
id1:可空类型、特性:IsNullable=true、生成了对应的id1Specified
id2:值类型、特性:IsNullable=false、生成了对应的id2Specified
id3:可空类型、特性:IsNullable=true
id4:值类型、特性:IsNullable=false
name1:引用类型、特性:IsNullable=true
name2:引用类型、特性:IsNullable=false
name3:引用类型、特性:IsNullable=true
name4:引用类型、特性:IsNullable=false
3.1.3 查看SOAP报文
将可为null的属性都置位null,然后查看SOAP报文是什么样子的
C#代码1:
Person p=new Person();
p.id1 = null;
p.id2 = 123;
p.id3 = null;
p.id4 = 456;
p.name1 = null;
p.name2 = null;
p.name3 = null;
p.name4 = null;
C#代码2:
Person p=new Person();
p.id1 = null;
p.id1Specified = true;
request.id2 = 123;
p.id1Specified = true;
p.id3 = null;
p.id4 = 456;
p.name1 = null;
p.name2 = null;
p.name3 = null;
p.name4 = null;
SOAP报文1:对应C#代码1,只贴出Person部分:
<Person>
<id3 xsi:nil="true" />
<id4>456</id4>
<name1 xsi:nil="true" />
<name3 xsi:nil="true" />
</Person>
SOAP报文2:对应C#代码2,只贴出Person部分:
<Person>
<id1 xsi:nil="true" />
<id2>123</id2>
<id3 xsi:nil="true" />
<id4>456</id4>
<name1 xsi:nil="true" />
<name3 xsi:nil="true" />
</Person>
3.1.4 得出结论
其一:对于值类型和包装类型
minOccurs="0" 组合nillable="true"时:
会生成包装类型(id1),同时会生成对应的id1Specified属性,为什么会生成带Specified的属性呢?这是因为minOccurs="0"的缘故,minOccurs=0意味着元素节点可以不出现,那到底是出现呢?还是不出现呢?工具自己没了主意,所以生成了一个xxxSpecified属性,该属性默认值为false,只有给它指定true的时候[元素节点]才会出现到soap报文中。
minOccurs="0"组合nillable="false"时:
会生成值类型(id2),同时会生成对应的id2Specified属性(原因同上)
minOccurs="1" 组合nillable="true"时:
会生成包装(id3),不会生成Specified属性(因为元素节点必输)。
minOccurs=“1”组合nillable=“false”时:
会生成值类型(id4),不会生成Specified属性(因为元素节点必输)。
其二:对于普通引用类型
name1、name3:
只要nillable=true不管minOccurs等于什么,[null对象]序列化的时候都以[元素取值]为空方式来体现这是一个空对象。
name2、name4:
只要nillable=false不管minOccurs等于什么,[null对象]序列化时都以[元素节点]不出现的方式来体现这是一个空对象。(上面实验时,Server端对soap报文进行了schema验证,所以name4传null会报错的)
总结:
* .NET在wsdl_2_C# 和C#_2_wsdl时的思路其实是一致的,1、生成值类型还是包装类型先看nillable属性、然后再看minOccurs属性来控制是否生成xxxSpecified属性;2、而生成普通引用类型时只关心nillable属性,nillable=true就采用nil=true的方式发送null对象,nillabe=false则采用[元素节点]不出现的方式发送null对象,压根就不关心minOccurs是神马。
* 前面说到name4=null时,Server端会报错,所以 对于引用类型:minOccurs=1和nillable=false的组合是没有意义的,这种组合无法让空对象传输过来
3.2 再看Java的规则
3.2.1 定义WSDL,限于篇幅