2015-09-28 74 views
0

我有這個類:參數爲空取決於XML格式

[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); 
    } 
} 

本地和張貼這個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到達控制器的方法無效。

我可能在xml或類的「映射」中做錯了什麼,但我看不到它是什麼。

+0

我可以看到你沒有發送關閉在xml.where是datetime的值? –

回答

0

您已將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包含一個standard representation for a null 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); 
     } 
    } 
} 
+0

謝謝您的好評!問題是我沒有權限改變這個XML。它將採用這種格式(多一點節點)。我能在這種情況下做什麼? – gabsferreira

+0

@gabsferreira - 你能分享那些額外節點的樣子嗎?是否提供了[XSD架構](http://www.w3schools.com/schema/default.asp)? – dbc

+0

@gabsferreira - 答案已更新。 – dbc