根据xml格式的不同,参数为空
本文关键字:参数 xml 格式 根据 | 更新日期: 2023-09-27 18:15:08
我有这样一个类:
[XmlRoot(ElementName = "order")]
public class Order
{
[XmlElement(ElementName= "buyer-accepts-marketing")]
public bool BuyerAcceptsMarketing { get; set; }
[XmlElement(ElementName= "closed-at")]
public DateTime? ClosedAt { get; set; }
}
这个简单的控制器和我用来测试请求的方法:
public class OrdersController : ApiController
{
[HttpPost]
public HttpResponseMessage Post([FromBody]Order order)
{
return Request.CreateResponse(HttpStatusCode.OK);
}
}
当我在本地运行服务并使用Fiddler将此xml发送到服务时:
<?xml version="1.0" encoding="UTF-8"?>
<order>
<buyer-accepts-marketing type="boolean">false</buyer-accepts-marketing>
</order>
我在控制器的Post方法中接收参数,一切正常。但是,如果我发布带有第二个属性的xml:
<?xml version="1.0" encoding="UTF-8"?>
<order>
<buyer-accepts-marketing type="boolean">false</buyer-accepts-marketing>
<closed-at type="datetime" nil="true"></closed-at>
</order>
参数order
在Controller的方法中到达null
我可能在xml或类的"映射"中做错了什么,但我看不出它是什么。
您已经将nil
属性放置在默认名称空间中。您需要将其放在"http://www.w3.org/2001/XMLSchema-instance"
名称空间中。传统的方法是将其放在根元素中,并使用xsi
前缀:
<?xml version="1.0" encoding="UTF-8"?>
<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<buyer-accepts-marketing type="boolean">false</buyer-accepts-marketing>
<closed-at type="datetime" xsi:nil="true"></closed-at>
</order>
但是将它放在"closed-at"
元素本身在语义上是相同的:
<?xml version="1.0" encoding="UTF-8"?>
<order >
<buyer-accepts-marketing type="boolean">false</buyer-accepts-marketing>
<closed-at xmlns:i="http://www.w3.org/2001/XMLSchema-instance" type="datetime" i:nil="true"></closed-at>
</order>
由于DateTime? ClosedAt
不是空的(因为它没有适当的xsi:nil="true"
属性),但也不能被反序列化为DateTime
(因为值为空),XmlSerializer
会混淆并抛出异常。
如果不能更改XML以包含空DateTime
的标准表示,则需要实现代理属性来手动进行转换。由于您没有在问题中指定是否需要序列化和反序列化,因此以下代码既需要序列化又需要反序列化:
[XmlRoot(ElementName = "order")]
public class Order
{
[XmlElement(ElementName = "buyer-accepts-marketing")]
public bool BuyerAcceptsMarketing { get; set; }
[XmlIgnore]
public DateTime? ClosedAt { get; set; }
[XmlElement("closed-at")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public XmlDateTimeWrapper XmlDateTime
{
get
{
return ClosedAt;
}
set
{
ClosedAt = value;
}
}
}
public class XmlDateTimeWrapper
{
public static implicit operator DateTime?(XmlDateTimeWrapper wrapper) { return wrapper == null ? null : wrapper.DateTime; }
public static implicit operator XmlDateTimeWrapper(DateTime? dateTime) { return new XmlDateTimeWrapper { DateTime = dateTime }; }
[XmlIgnore]
public DateTime? DateTime { get; set; }
[XmlText]
public string DateTimeString
{
get
{
if (DateTime == null)
return string.Empty;
return XmlConvert.ToString(DateTime.Value, XmlDateTimeSerializationMode.Utc);
}
set
{
if (String.IsNullOrWhiteSpace(value))
DateTime = null;
else
DateTime = XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.Utc);
}
}
[XmlAttribute("type")]
public string Type { get { return "datetime"; } set { /* Do nothing */ } }
[XmlAttribute("nil")]
public bool Nil { get { return DateTime == null; } set { /* Do nothing */ } }
}
如果不需要序列化,可以使用字符串值的代理属性:
[XmlRoot(ElementName = "order")]
public class Order
{
[XmlElement(ElementName = "buyer-accepts-marketing")]
public bool BuyerAcceptsMarketing { get; set; }
[XmlIgnore]
public DateTime? ClosedAt { get; set; }
[XmlElement("closed-at")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public string XmlDateTime
{
get
{
return ClosedAt == null ? null : XmlConvert.ToString(ClosedAt.Value, XmlDateTimeSerializationMode.Utc);
}
set
{
if (String.IsNullOrWhiteSpace(value))
ClosedAt = null;
else
ClosedAt = XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.Utc);
}
}
}