WCF сериализация десятичной строки в строку с точностью до 2 десятичных знаков - PullRequest
1 голос
/ 08 октября 2019

Мы подключаемся к внешней системе, которая предоставляет WSDL, который ожидает, что десятичные дроби будут предоставлены с двумя десятичными знаками, то есть:

<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 таким образом?

Ответы [ 2 ]

1 голос
/ 09 октября 2019

Итак, мы исправили это, слегка взломав систему типов.

Оказывается, что десятичные числа, преобразованные из строк и обратно в десятичные, имеют разную точность. Следовательно, мы сделали:

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

Делая это, когда сериализатор XML видит десятичное число, он сохраняет точность, которую Convert.ToDecimal использует от ToString.

1 голос
/ 09 октября 2019

Используйте следующее:

    public partial class amountSetRequest
    {
        private decimal _collectionAmount { get; set; }

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