XSD simpleContent WCF/Web API
XSD simpleContent with WCF/Web API
在处理 XSD.
中的 simpleContent 标签时,我的 WebService 无法正确生成 XML/JSON
首先,我只有一个 XSD 文件(没有 WSDL),其内容(已简化):
<xs:complexType name="VerticalDataValue">
<xs:simpleContent>
<xs:extension base="NCADevicePublication:Double">
<xs:attribute name="unit" type="NCADevicePublication:VerticalUnitEnum" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="Double">
<xs:restriction base="xs:double" />
</xs:simpleType>
<xs:simpleType name="VerticalUnitEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="ft"></xs:enumeration>
<xs:enumeration value="m"></xs:enumeration>
</xs:restriction>
</xs:simpleType>
然后我使用 Xsd.exe 生成我的 class。
我对这个结构的期望,在 XML 输出上:
<altitudeCoordinate unit="ft">2.1</altitudeCoordinate>
我得到的:
<altitudeCoordinate>
<Value>2.1</Value>
<unit>ft</unit>
<unitSpecified>true</unitSpecified>
</altitudeCoordinate>
JSON 也一样,我预计:
"altitudeCoordinate": {
"@unit": "ft",
"text": "2.1"
}
但我得到:
"altitudeCoordinate":{
"unit": "ft",
"unitSpecified": "true,
"Value": 2.1
我在 MSDN 上看到 Xsd.Exe 无法识别 simpleContent 限制。
有什么方法可以得到这种 "standard" 输出,或者 .Net 做不到?
谢谢
更新
我能够让它为我的 WCF 服务工作。解决方案非常简单......只需将 [XmlSerializerFormat] 放在界面的顶部,然后就可以了。
原因是默认序列化器(DataContractSerializer)无法正确处理xml属性。
另外,请注意 WCFStorm 也使用 DataContractSerializer:我发现即使在使用 XmlSerializer 时,WCFStorm 中的 XML 也很糟糕。然后我检查了 SoapUI,它工作正常! (仍然损失了几个小时)。
那么现在,让我们在我的 Web API 项目上完成这项工作,JSON...
终于想到了解决办法。提醒一下:我的目标是不要触及生成的 class.
对于SOAP/XML
如我的更新所述,解决方案非常简单,我只是将以下属性放在 WCF 接口上:
[XmlSerializerFormat]
对于REST/JSON
解决方案是为未很好转换的 "bothering" classes 定义 MetadataType classes。
例如,这里是 VerticalDataValue class 在自动生成的文件中的定义方式(我去掉了属性和命名空间):
public partial class VerticalDataValue {
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public VerticalUnitEnum unit;
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool unitSpecified;
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public double Value;
}
我创建了另一个文件,包含所有 MetadataType classes,定义如下:
[MetadataType(typeof(VerticalDataValueMetaClass))]
public partial class VerticalDataValue { }
public class VerticalDataValueMetaClass
{
[JsonProperty("@unit")]
public VerticalUnitEnum unit;
[JsonIgnore]
public bool unitSpecified
[JsonProperty("text")]
public double value;
}
请注意,这只有在您的基础 class 是部分的情况下才有可能。
当然,这是高维护代码,但至少这不会与自动生成的代码混淆 class。
在处理 XSD.
中的 simpleContent 标签时,我的 WebService 无法正确生成 XML/JSON首先,我只有一个 XSD 文件(没有 WSDL),其内容(已简化):
<xs:complexType name="VerticalDataValue">
<xs:simpleContent>
<xs:extension base="NCADevicePublication:Double">
<xs:attribute name="unit" type="NCADevicePublication:VerticalUnitEnum" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="Double">
<xs:restriction base="xs:double" />
</xs:simpleType>
<xs:simpleType name="VerticalUnitEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="ft"></xs:enumeration>
<xs:enumeration value="m"></xs:enumeration>
</xs:restriction>
</xs:simpleType>
然后我使用 Xsd.exe 生成我的 class。
我对这个结构的期望,在 XML 输出上:
<altitudeCoordinate unit="ft">2.1</altitudeCoordinate>
我得到的:
<altitudeCoordinate>
<Value>2.1</Value>
<unit>ft</unit>
<unitSpecified>true</unitSpecified>
</altitudeCoordinate>
JSON 也一样,我预计:
"altitudeCoordinate": {
"@unit": "ft",
"text": "2.1"
}
但我得到:
"altitudeCoordinate":{
"unit": "ft",
"unitSpecified": "true,
"Value": 2.1
我在 MSDN 上看到 Xsd.Exe 无法识别 simpleContent 限制。
有什么方法可以得到这种 "standard" 输出,或者 .Net 做不到?
谢谢
更新
我能够让它为我的 WCF 服务工作。解决方案非常简单......只需将 [XmlSerializerFormat] 放在界面的顶部,然后就可以了。 原因是默认序列化器(DataContractSerializer)无法正确处理xml属性。 另外,请注意 WCFStorm 也使用 DataContractSerializer:我发现即使在使用 XmlSerializer 时,WCFStorm 中的 XML 也很糟糕。然后我检查了 SoapUI,它工作正常! (仍然损失了几个小时)。
那么现在,让我们在我的 Web API 项目上完成这项工作,JSON...
终于想到了解决办法。提醒一下:我的目标是不要触及生成的 class.
对于SOAP/XML 如我的更新所述,解决方案非常简单,我只是将以下属性放在 WCF 接口上:
[XmlSerializerFormat]
对于REST/JSON 解决方案是为未很好转换的 "bothering" classes 定义 MetadataType classes。
例如,这里是 VerticalDataValue class 在自动生成的文件中的定义方式(我去掉了属性和命名空间):
public partial class VerticalDataValue {
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public VerticalUnitEnum unit;
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool unitSpecified;
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public double Value;
}
我创建了另一个文件,包含所有 MetadataType classes,定义如下:
[MetadataType(typeof(VerticalDataValueMetaClass))]
public partial class VerticalDataValue { }
public class VerticalDataValueMetaClass
{
[JsonProperty("@unit")]
public VerticalUnitEnum unit;
[JsonIgnore]
public bool unitSpecified
[JsonProperty("text")]
public double value;
}
请注意,这只有在您的基础 class 是部分的情况下才有可能。
当然,这是高维护代码,但至少这不会与自动生成的代码混淆 class。