2012-10-01 61 views
1

使用.Net Web API我必須編寫一個服務以消耗第三方對我們的服務器進行的一些平穩的調用。我無法控制我們發送的XML,無論如何不能改變它。我們只會接收HTTP POST調用,並且它們都將採用XML格式。Web API如何處理短劃線和日期時間格式化

下面是一個XML消息的例子,我們將得到:

<listing-confirmation> 
<account-id>123456</account-id> 
<allow-bid>true</allow-bid> 
<allow-both>true</allow-both> 
<allow-buy>true</allow-buy> 
<allow-offers>false</allow-offers> 
<auction-work-order>1234</auction-work-order> 
<bid-count>1</bid-count> 
<bid-increment>50</bid-increment> 
<buyer-group-name>og_name bg_name</buyer-group-name> 
<buyer-group-type>GlobalOpen</buyer-group-type> 
<buy-now-price>1000</buy-now-price> 
<condition-report-url>some_url</condition-report-url> 
<current-bid>700</current-bid> 
<end-timestamp>Wed May 25 21:48:09 +0000 2011</end-timestamp> 
<event-sale-id>1234</event-sale-id> 
<event-sale-name>event_sale_name</event-sale-name> 
<facilitated-auction-code>abc</facilitated-auction-code> 
<floor-price>700</floor-price> 
<listing-activated-timestamp>Tue May 24 21:38:09 +0000 2011</listing-activated-timestamp> 
<manheim-group-code>mgc</manheim-group-code> 
<physical-location>at_auction</physical-location> 
<seller-id>5000000</seller-id> 
<starting-bid-price>300</starting-bid-price> 
<start-timestamp>Tue May 24 21:38:09 +0000 2011</start-timestamp> 
<stock-number>3BBBDOC</stock-number> 
<unique-bidder-count>1</unique-bidder-count> 
<vehicle-detail-url>http://localhost/vdp/show/169</vehicle-detail-url> 
<view-count>0</view-count> 
<vin>123456789</vin> 
</listing-confirmation> 

我有幾個問題:

1 - 如何處理根XML消息中的幾許?它會是這樣嗎?

[XmlRoot("listing-confirmation")] 
public class Listing_confirmation 

2 - 如何處理XML元素中的破折號?我會用這個嗎?

[XmlElement("account-id")] 
public int account_id { get; set; } 

3 - 如何處理日期時間格式化?它會自動理解並將其轉換爲DateTime還是我需要做一些處理?如果是這樣,我該怎麼做?

謝謝! 傑里米

編輯爲2012年10月1日的@ 4:56 EST

這裏是我的Listing_confirmation模型我的新的類文件

[DataContract(Name="listing-confirmation")] 
public class Listing_confirmation 
{ 
    [DataMember(Name="account-id")] 
    public int account_id { get; set; } 
    [DataMember(Name="allow-bid")] 
    public bool allow_bid { get; set; } 
    [DataMember(Name="allow-both")] 
    public bool allow_both { get; set; } 
    [DataMember(Name="allow-buy")] 
    public bool allow_buy { get; set; } 
    [DataMember(Name="allow-offers")] 
    public bool allow_offers { get; set; } 
    [DataMember(Name="auction-work-order")] 
    public int? auction_work_order { get; set; } 
    [DataMember(Name="bid-count")] 
    public int? bid_count { get; set; } 
    [DataMember(Name="bid-increment")] 
    public int? bid_increment { get; set; } 
    [DataMember(Name="buyer-group-name")] 
    public string buyer_group_name { get; set; } 
    [DataMember(Name="buyer-group-type")] 
    public string buyer_group_type { get; set; } 
    [DataMember(Name="buy-now-price")] 
    public int buy_now_price { get; set; } 
    [DataMember(Name="condition-report-url")] 
    public string condition_report_url { get; set; } 
    [DataMember(Name="current-bid")] 
    public int? current_bid { get; set; } 
    //[DataMember(Name="end-timestamp")] 
    //public DateTime end_timestamp { get; set; } 
    [DataMember(Name="event-sale-id")] 
    public int? event_sale_id { get; set; } 
    [DataMember(Name="event-sale-name")] 
    public string event_sale_name { get; set; } 
    [DataMember(Name="facilitated-auction-code")] 
    public string facilitated_auction_code { get; set; } 
    [DataMember(Name="floor-price")] 
    public int floor_price { get; set; } 
    //[DataMember(Name="listing-activated-timestamp")] 
    //public DateTime listing_activated_timestamp { get; set; } 
    [DataMember(Name="manheim-group-code")] 
    public string manheim_group_code { get; set; } 
    //[DataMember(Name="message-triggered")] 
    //public DateTime message_triggered { get; set; } 
    [DataMember(Name="physical-location")] 
    public string physical_location { get; set; } 
    [DataMember(Name="seller-id")] 
    public int seller_id { get; set; } 
    [DataMember(Name="starting-bid-price")] 
    public int? starting_bid_price { get; set; } 
    //[DataMember(Name="start-timestamp")] 
    //public DateTime start_timestamp { get; set; } 
    [DataMember(Name="stock-number")] 
    public string stock_number { get; set; } 
    [DataMember(Name="unique-bidder-count")] 
    public int? unique_bidder_count { get; set; } 
    [DataMember(Name="vehicle-detail-url")] 
    public string vehicle_detail_url { get; set; } 
    [DataMember(Name="view-count")] 
    public int? view_count { get; set; } 
    [DataMember(Name="vin")] 
    public string vin { get; set; } 
} 

但是,它仍然不綁定數據正確。當我調試控制器時,它始終具有ModelState.IsValid = false,並且Listing_Confirmation對象始終爲空。有人可以幫忙嗎?

謝謝!

+1

我不太瞭解將XML序列化爲對象,但我可以幫助使用格式字符串。你用來解析日期的格式字符串就是這個......「ddd MMM dd HH:mm:ss zzz yyyy」,例如。 DateTime.ParseExact(「Tue May 24 21:38:09 +0000 2011」,「ddd MMM dd HH:mm:ss zzz yyyy」,System.Globalization.CultureInfo.InvariantCulture) –

回答

1

How WebAPI does Parameter Binding Work

有2個技術結合參數:模型綁定和 格式化程序。實際上,WebAPI使用模型綁定來從 中讀取查詢字符串和格式化程序以從正文讀取。

如果從第三方收到的XML是POST操作的身體,那麼你應該寫一個自定義XML格式媒體進行模型結合,將採取XML並返回一個.NET對象代表正在接收的數據。

有關如何編寫自定義媒體類型格式化程序的示例,請參見Media Formatters。您將需要用您的自定義XML格式化程序替換默認的XML媒體類型格式化程序。

+0

這不是我擔心的迴應。我試圖讓請求(POST)正確地轉換成我創建的對象。我在我的Application_Start()中設置了UseXmlSerializer = true,我也嘗試添加[XmlElement(「account-id」)]裝飾和[DataMember(Name =「account-id」)]裝飾,但一直無法獲取請求正確地轉換爲我的對象。我調試時該對象始終爲NULL。 – jkruer01

+0

啊,我明白了。這意味着模型綁定不起作用。這意味着你最需要一個自定義的格式化程序。 – Oppositional

+0

使用此鏈接:http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter – jkruer01

0

我終於明白了問題所在。

1 - 在我的Application_Start()方法我添加以下代碼行指定要使用XmlSerializer代替DataContract串行:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; 
xml.UseXmlSerializer = true; 

2 - I中使用的XmlRoot和的XmlElement屬性來裝飾類名稱和每個屬性。這是我的新的類文件 -

[XmlRoot("listing-confirmation")] 
public class Listing_confirmation 
{ 
    [XmlElement("account-id")] 
    public int account_id { get; set; } 
    [XmlElement("allow-bid")] 
    public bool allow_bid { get; set; } 
    [XmlElement("allow-both")] 
    public bool allow_both { get; set; } 
    [XmlElement("allow-buy")] 
    public bool allow_buy { get; set; } 
    [XmlElement("allow-offers")] 
    public bool allow_offers { get; set; } 
    [XmlElement("auction-work-order")] 
    public int auction_work_order { get; set; } 
    [XmlElement("bid-count")] 
    public int bid_count { get; set; } 
    [XmlElement("bid-increment")] 
    public int bid_increment { get; set; } 
    [XmlElement("buyer-group-name")] 
    public string buyer_group_name { get; set; } 
    [XmlElement("buyer-group-type")] 
    public string buyer_group_type { get; set; } 
    [XmlElement("buy-now-price")] 
    public int buy_now_price { get; set; } 
    [XmlElement("condition-report-url")] 
    public string condition_report_url { get; set; } 
    [XmlElement("current-bid")] 
    public int current_bid { get; set; } 
    //[XmlElement("end-timestamp")] 
    //public DateTime end_timestamp { get; set; } 
    [XmlElement("event-sale-id")] 
    public int event_sale_id { get; set; } 
    [XmlElement("event-sale-name")] 
    public string event_sale_name { get; set; } 
    [XmlElement("facilitated-auction-code")] 
    public string facilitated_auction_code { get; set; } 
    [XmlElement("floor-price")] 
    public int floor_price { get; set; } 
    //[XmlElement("listing-activated-timestamp")] 
    //public DateTime listing_activated_timestamp { get; set; } 
    [XmlElement("manheim-group-code")] 
    public string manheim_group_code { get; set; } 
    //[XmlElement("message-triggered")] 
    //public DateTime message_triggered { get; set; } 
    [XmlElement("physical-location")] 
    public string physical_location { get; set; } 
    [XmlElement("seller-id")] 
    public int seller_id { get; set; } 
    [XmlElement("starting-bid-price")] 
    public int starting_bid_price { get; set; } 
    //[XmlElement("start-timestamp")] 
    //public DateTime start_timestamp { get; set; } 
    [XmlElement("stock-number")] 
    public string stock_number { get; set; } 
    [XmlElement("unique-bidder-count")] 
    public int unique_bidder_count { get; set; } 
    [XmlElement("vehicle-detail-url")] 
    public string vehicle_detail_url { get; set; } 
    [XmlElement("view-count")] 
    public int view_count { get; set; } 
    [XmlElement("vin")] 
    public string vin { get; set; } 
} 

3 - 我不得不註釋掉我所有的日期時間屬性,因爲它是不能夠被傳遞到有效的DateTime的值轉換。我仍在努力讓這些工作正常進行。

+0

您可以創建一個實現IXmlSerializable並處理您所看到的字符串格式的自定義日期 - 時間類;或者你可以爲日期時間元素使用一個字符串屬性,並將實用的getter屬性添加到Listing_confirmation中。例如。綁定屬性是start_timestamp_value,並且您有一個start_timestamp屬性,用於分析該值並返回DateTime – Oppositional

0

我終於能夠找出DateTime格式問題了。這是我如何處理一個DateTime的例子。我同樣對待其他人。

[XmlIgnore] 
    public DateTime? start_timestamp { get; set; } 
    [XmlElement("start-timestamp")] 
    public string start_timestampstring 
    { 
     get 
     { 
      return start_timestamp.HasValue ? start_timestamp.Value.ToString("ddd MMM dd HH:mm:ss zzz yyyy") : string.Empty; 
     } 
     set 
     { 
      if (!string.IsNullOrEmpty(value)) 
      { 
       try 
       { 
        start_timestamp = DateTime.ParseExact(value, "ddd MMM dd HH:mm:ss zzz yyyy", System.Globalization.CultureInfo.InvariantCulture); 
       } 
       catch 
       { 
        start_timestamp = null; 
       } 

      } 
      else 
      { 
       start_timestamp = null; 
      } 
     } 
    }