【问题标题】:WCF serialization of decimal to string with 2 decimal precisionWCF将十进制序列化为具有2个十进制精度的字符串
【发布时间】:2020-02-05 21:38:26
【问题描述】:

我们正在连接到一个提供 WSDL 的外部系统,该系统期望将小数提供到小数点后 2 位 - 即:

<collectionAmount>1000.00</collectionAmount>

但是,当我们的客户端序列化 SOAP 请求时,小数点以单精度显示:

<collectionAmount>1000.0</collectionAmount>

我们已尝试使用元数据扩展:

    [MetadataType(typeof(amountSetRequestMetadata))]
    public partial class amountSetRequest
    {
        internal sealed class amountSetRequestMetadata
        {
            [XmlIgnore]
            public decimal collectionAmount { get; set; }

            [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 14, ElementName = "collectionAmount")]
            public string collectionAmountString => "yay!";
        }
    }

amountSetRequest 是 WSDL 服务自动生成器生成的部分类。输出 XML 没有什么不同,因此这似乎对请求没有任何影响。

我们认为这是相当普遍的,但无法找到解决方法。我们已经看到了扩展基本 XML 序列化程序的解决方案。

以这种方式序列化 SOAP 请求的最简洁的方法是什么?

【问题讨论】:

  • 显然,对于 XML 本身,有一种方法可以在 XML 配置文件中指定它。见this。但是,很难在谷歌上搜索相关信息,因为谷歌总是认为你在谈论一个常规的配置文件,存储为 XML,而不是 XML 格式本身的配置。所以我无法弄清楚这是否/如何应用于 SOAP 消息。祝你好运!
  • 你需要像 ToString("F2") 这样的数字格式
  • @jdweng 是的,那将是理想的 - 但是 - 合同接受 decimal 而不是 string 所以内部 XML 序列化没有正确转换它。问题是如何让它按照预期进行序列化?

标签: c# wcf soap code-generation partial-classes


【解决方案1】:

所以我们通过稍微修改类型系统来修复它。

事实证明,从字符串转换为小数的小数具有不同的精度。因此我们做到了:

public void RequestAmount(decimal amount) {
   var request = new amountSetRequest()
   request.collectionAmount = Convert.ToDecimal(amount.ToString("F2"));
   // ...
}

这样做时,当 XML 序列化程序看到小数点时,它会保持 Convert.ToDecimal 使用的来自 ToString 的精度。

【讨论】:

    【解决方案2】:

    使用以下:

        public partial class amountSetRequest
        {
            private decimal _collectionAmount { get; set; }
    
            public string collectionAmount {
                get {return _collectionAmount.ToString("F2");}
                set {_collectionAmount = decimal.Parse(value);}
            }
        }
    

    【讨论】:

    • 编译器失败,collectionAmount 已经定义。初始部分类是从 wsdl 自动生成的,因此 collectionAmount 已经是该类的一部分,因此无法将其合同更改为 string
    • 它不需要是部分类(也不需要元数据扩展)。将代码放在类的主要部分。
    • 如果wsdl文件发生变化,我们会生成一个新文件。另一个团队在自动生成后必须支持手工更改会导致问题。因此,我们正在寻找在不更改自动生成代码的情况下实现序列化的方法。
    • 我认为你做不到。您需要继承(然后覆盖)该类,然后 xml 需要一个类型属性。我可以建议的最好方法是使用条件编译语句,这样手动更改的内容就很明显了。
    猜你喜欢
    • 1970-01-01
    • 2019-10-25
    • 2015-06-14
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    相关资源
    最近更新 更多