我在 Web API 中有一个 POST 方法,该方法具有
RequestAppointment
参数。例如:
// POST: api/RequestAppointment
public HttpResponseMessage Post([FromBody]RequestAppointment httpRequest)
{
var response = Appointment.CreateAppointment(httpRequest);
return Request.CreateResponse<ResponseRequest>(System.Net.HttpStatusCode.Created, response);
}
RequestAppoint
类具有以下结构:
public partial class RequestAppointment
{
public RequestAppointmentAppointmentInformation appointmentInformation { get; set; }
}
public partial class RequestAppointmentAppointmentInformation
{
public string AppointmentCcEmail { get; set; }
public string ClaimType { get; set; }
public RequestAppointmentAppointmentInformationClaimant Claimant { get; set; }
}
public partial class RequestAppointmentAppointmentInformationClaimant
{
public System.DateTime DateOfBirth { get; set; }
}
可以提出两个请求:
第一个是:
<RequestAppointment>
<appointmentInformation>
<AppointmentCcEmail>x.x.com</AppointmentCcEmail>
<ClaimType>A</ClaimType>
<Claimant>
<DateOfBirth>1961-12-25</DateOfBirth>
</Claimant>
</appointmentInformation>
</RequestAppointment>
第二个请求是:
<RequestAppointment>
<appointmentInformation>
<AppointmentCcEmail>x.x.com</AppointmentCcEmail>
<ClaimType>A</ClaimType>
</appointmentInformation>
</RequestAppointment>
两个请求 XML 的区别在于 #1 有 Claimant 标签,而 #2 没有。
第二个请求没有,因为当用户从数据接口调用Web服务时,没有提供索赔人。当提供索赔人时,第一个总是会出现。
在我使用 Fiddler 进行测试时,我的 #1 请求返回数据。也就是说,它能够反序列化为对象 RequestAppointment,而 #2 请求返回 null 值。
我可以做什么来解决这个问题?请求将始终采用这两种格式,并且它们将始终使用相同的模型结构。
我可以做什么来解决这个问题?我在 Fiddler 中测试了该场景。
首先,第1步。如果您有
RequestAppointment
XSD文件,最好的解决方案是使用xsd.exe生成类参见如何使用它,如果没有,您可以自己创建XSD并执行第1步,或者最后您应该进行更改并指向显式属性,使您的类 XML 可序列化。有很多关于它的文章。
这个类是用 xsd.exe 生成的,我从 XML 创建示例架构,仅在标记
<Claimant>
中进行更改,使其成为可选,并且类看起来像这样。注意工具如何生成可选字段Claimant
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Xml.Serialization;
//
// This source code was auto-generated by xsd, Version=4.6.1055.0.
//
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class RequestAppointment {
private RequestAppointmentAppointmentInformation appointmentInformationField;
/// <remarks/>
public RequestAppointmentAppointmentInformation appointmentInformation {
get {
return this.appointmentInformationField;
}
set {
this.appointmentInformationField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class RequestAppointmentAppointmentInformation {
private string appointmentCcEmailField;
private string claimTypeField;
private RequestAppointmentAppointmentInformationClaimant claimantField;
/// <remarks/>
public string AppointmentCcEmail {
get {
return this.appointmentCcEmailField;
}
set {
this.appointmentCcEmailField = value;
}
}
/// <remarks/>
public string ClaimType {
get {
return this.claimTypeField;
}
set {
this.claimTypeField = value;
}
}
/// <remarks/>
public RequestAppointmentAppointmentInformationClaimant Claimant {
get {
return this.claimantField;
}
set {
this.claimantField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class RequestAppointmentAppointmentInformationClaimant {
private System.DateTime dateOfBirthField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType="date")]
public System.DateTime DateOfBirth {
get {
return this.dateOfBirthField;
}
set {
this.dateOfBirthField = value;
}
}
}
XSD 示例
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="RequestAppointment">
<xs:complexType>
<xs:sequence>
<xs:element name="appointmentInformation">
<xs:complexType>
<xs:sequence>
<xs:element name="AppointmentCcEmail" type="xs:string" />
<xs:element name="ClaimType" type="xs:string" />
<xs:element name="Claimant" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="DateOfBirth" type="xs:date" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
感谢您的所有建议。他们都是伟大的! Seyran 的回答确实很棒。但就我的问题而言,我通过对所有元素进行 nil="true" (nullable=true) 来解决它。我使用 xsd 为我的请求 xml 生成类。
谢谢