【问题标题】:Web API How to Handle Dashes and DateTime FormatingWeb API 如何处理破折号和日期时间格式
【发布时间】:2012-10-01 15:40:39
【问题描述】:

使用 .Net Web API 我必须编写一个服务来使用第三方对我们服务器的一些安静的调用。我无法控制我们发送的 XML,也无法更改它。我们只会收到 HTTP POST 调用,它们都是 XML 格式的。

以下是我们将收到的 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>12345678901234567</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 对象始终为空。有人可以帮忙吗?

谢谢!

【问题讨论】:

  • 我不太了解将 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)

标签: c# rest asp.net-web-api


【解决方案1】:

来自How WebAPI does Parameter Binding Work

绑定参数有两种技术:模型绑定和 格式化程序。在实践中,WebAPI 使用模型绑定从 从正文中读取的查询字符串和格式化程序。

如果您从第三方接收的 XML 在 POST 操作的主体中,那么您应该编写一个自定义 XML 媒体格式化程序来执行模型绑定,该绑定将采用 XML 并返回一个表示数据的 .NET 对象正在接收。

有关如何编写自定义媒体类型格式化程序的示例,请参阅Media Formatters。您需要将默认的 XML 媒体类型格式化程序替换为您的自定义 XML 格式化程序。

【讨论】:

  • 这不是我担心的反应。我正在尝试让请求(POST)正确转换为我创建的对象。我在我的 Application_Start() 中设置了 UseXmlSerializer = true 并且我还尝试添加 [XmlElement("account-id")] 装饰和 [DataMember(Name = "account-id")] 装饰但无法获得请求正确转换为我的对象。调试时对象始终为 NULL。
  • 啊,我明白了。这意味着模型绑定不起作用。这意味着您很可能需要自定义格式化程序。
  • 它说“要更改类名在 XML 中的显示方式,请在 DataContract 属性中设置 Name 参数。”然后它还说“要更改成员名称在 XML 中的显示方式,请在 DataMember 属性中设置 Name 参数。”因此,我关闭了 UseXMLSerializer,然后添加了 [DataContract(Name="listing-confirmation")] 公共类 Listing_confirmation 并且我还添加了 [DataMember(Name="account-id")] 到具有适当名称的每个属性,但是它仍然没有正确绑定。当我去调试它的对象为空。为什么它不能识别专有名称?
【解决方案2】:

我终于知道问题出在哪里了。

1 - 在我的 Application_Start() 方法中,我添加了以下代码行来指定使用 XmlSerializer 而不是 DataContract Serializer:

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

2 - 我使用 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 属性,因为它无法将传递的值转换为有效的 DateTime。我仍在努力使其正常工作。

【讨论】:

  • 您可以创建一个自定义日期时间类来实现 IXmlSerializable 并处理您看到的字符串格式;或者您可以只对日期时间元素使用字符串属性并将实用程序 getter 属性添加到 Listing_confirmation。例如。绑定属性是 start_timestamp_value 并且您有一个 start_timestamp 属性来解析值并返回 DateTime
【解决方案3】:

我终于也能弄清楚 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;
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2022-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多