WCF Datacontract, некоторые поля не десериализуются
Проблема:
У меня есть настройка службы WCF как конечная точка для вызова из внешней системы. Вызов посылает простой xml. Я тестирую систему, отправляя вызовы в службу от Fiddler с помощью RequestBuilder.
Проблема заключается в том, что все мои поля десериализуются, за исключением двух полей. price_retail и price_wholesale.
Что мне не хватает? Все остальные поля десериализуются без проблем - служба отвечает. Это только эти поля.
XML-сообщение:
<widget_conclusion>
<list_criteria_id>123</list_criteria_id>
<list_type>consumer</list_type>
<qty>500</qty>
<price_retail>50.00</price_retail>
<price_wholesale>40.00</price_wholesale>
<session_id>123456789</session_id>
</widget_conclusion>
Сервисный метод:
public string WidgetConclusion(ConclusionMessage message)
{
var priceRetail = message.PriceRetail;
}
Класс сообщения:
[DataContract(Name = "widget_conclusion", Namespace = "")]
public class ConclusionMessage
{
[DataMember(Name = "list_criteria_id")]
public int CriteriaId { get; set;}
[DataMember(Name = "list_type")]
public string ListType { get; set; }
[DataMember(Name = "qty")]
public int ListQuantity { get; set; }
[DataMember(Name = "price_retail")]
public decimal PriceRetail { get; set; }
[DataMember(Name = "price_wholesale")]
public decimal PriceWholesale { get; set; }
[DataMember(Name = "session_id")]
public string SessionId { get; set; }
}
Ответы
Ответ 1
Поля для вашего сообщения неверны. DataContracts по умолчанию - Алфавитный порядок, а не порядок объявления; и ожидает, что элементы XML поступят в этом порядке; Элементы из порядка обычно отбрасываются.
Либо исправьте контракт, чтобы указать правильный порядок явно (используя свойство Order для DataMemberAttribute), либо убедитесь, что ваш клиент отправляет их в нужное место.
Ответ 2
Вы можете попробовать использовать XmlSerializer вместо DataContractSerializer.
В моем случае мне нужно изменить двигатель по умолчанию в файле global.asax:
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = true;
Сделайте это осторожно, потому что некоторые XML могут стать недействительными, например - пространства имен, с XmlSerializer должны быть определены следующим образом:
[XmlNamespaceDeclarations]
private XmlSerializerNamespaces xmlns
{
get {
var xns = new XmlSerializerNamespaces();
xns.Add("i", "http://www.w3.org/2001/XMLSchema-instance");
return xns;
}
set { }
}
Или вы можете установить XmlSerializerFormatArribute для вас класс (не работает для меня).
Посмотрите в url head "Вручную переключение на XmlSerializer"