我有一个使用 ASP.Net 构建的 Web 服务,到目前为止它仅使用 XML 作为输入和输出。现在它还需要能够使用 JSON。
我们使用 xsd2code++ 从 XSD 生成模型,并可以选择创建“指定”属性 https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/zds0b35c(v=vs.100)启用(即,如果在 XML 中指定了属性,则其各自的“指定”属性将是true
).
从像这样的 XSD...
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="Details" type="PersonalDetails"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="PersonalDetails">
<xs:sequence>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
... xsd2code++ 创建一个类,其属性如下:
public partial class Person
{
#region Private fields
private string _id;
private PersonalDetails _details;
private Address _address;
private bool _iDSpecified;
private bool _detailsSpecified;
private bool _addressSpecified;
#endregion
public Person()
{
this._address = new Address();
this._details = new PersonalDetails();
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ID
{
get
{
return this._id;
}
set
{
this._id = value;
}
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public PersonalDetails Details
{
get
{
return this._details;
}
set
{
this._details = value;
}
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public Address Address
{
get
{
return this._address;
}
set
{
this._address = value;
}
}
[XmlIgnore()]
public bool IDSpecified
{
get
{
return this._iDSpecified;
}
set
{
this._iDSpecified = value;
}
}
[XmlIgnore()]
public bool DetailsSpecified
{
get
{
return this._detailsSpecified;
}
set
{
this._detailsSpecified = value;
}
}
[XmlIgnore()]
public bool AddressSpecified
{
get
{
return this._addressSpecified;
}
set
{
this._addressSpecified = value;
}
}
}
这对于 XML 非常有用。
例如,如果输入 XML 中未指定 ID,则属性 IDSpecified 将为false
。我们可以在业务逻辑层使用这些“指定”属性,这样我们就知道哪些数据必须插入/更新,以及哪些数据可以忽略/跳过。
然后,我们尝试添加 JSON 序列化。
我们向 WebApiConfig 类添加了一个 Json 格式化程序:
config.Formatters.Add(new JsonMediaTypeFormatter());
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
API 现在将识别 JSON 输入,但“指定”属性无法像 XML 那样适用于复杂对象,并且始终会说它们是false
.
{
"ID": "abc123", // IDSpecified comes through as "true"
"Details": { // DetailsSpecified always comes through as "false"
"FirstName": "John", // FirstNameSpecified = true
"LastName": "Doe", // LastNameSpecified = true
"BirthDate": "1990-06-20" // BirthDateSpecified = true
}
}
Newtonsoft 的 DefaultContractResolver 是否与这些“指定”字段不完全兼容,就像 XML 一样?我是否需要明确说明每个属性的“指定”值是否为 true?
或者我错过了什么?
EDIT:
我已经将一些示例代码上传到 GitHub:https://github.com/AndreNobrega/XML-JSON-Serialization-POC https://github.com/AndreNobrega/XML-JSON-Serialization-POC
我尝试发送的请求正文可以在项目的 Examples 文件夹中找到。 POST 请求可以发送到 .../api/Person。
发送 XML 示例时,我设置了Content-Type
标头至application/xml
。发送 JSON 示例时,我将其设置为application/json
.
如果在 PersonController 类的 Post() 方法中设置断点,您将看到xxxSpecified
XML 请求的成员设置正确,但 JSON 请求的成员设置不正确。
也许它与由 xsd2code++ 自动生成的 Person.Designer 类有关?该属性是否有等效的 JSON[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
?