2017-01-18 10 views
1

Скажут, например, у меня есть контракт данных C# написанного как этогоПочему WCF десериализация пустых строк в качестве действительных перечислений

[DataContract] 
public class GiftCard 
{ 
    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    public PaymentMethod MethodOfPayment; 
} 

[DataContract] 
[Flags] 
public enum PaymentMethod 
{ 
    [EnumMember] 
    Mastercard = 0, 
    [EnumMember] 
    Visa = 1 
} 

Затем проверить его с помощью SoapUI, намеренно не указывая значение.

<soapenv:Body> 
    <GiftCardTest> 
    <GiftCard> 
     <MethodOfPayment></MethodOfPayment> 
    </GiftCard> 
    </GiftCardTest> 
</soapenv:Body> 

Он прибывает в мой метод обслуживания как действительный Visual Studio Watch

Какие атрибуты мне не хватает? Как это подтвердить?

ответ

2

Удаление флаги атрибутов сделал трюк.

[DataContract] 
public enum PaymentMethod 
{ 
    [EnumMember] 
    Mastercard = 0, 
    [EnumMember] 
    Visa = 1 
} 

Теперь он бросает исключение:

недопустимое значение перечисления '' не может быть десериализации в тип 'PAYMENTMETHOD' ...

+0

Когда вы установили 'Flags', значение' String.Empty' будет интерпретироваться как «no flags set», которое равно 0. Если вы используете флаги, ваш первый флаг должен начинаться с 1. Однако просто удаление 'Flags' имеет наибольший смысл в этом случае, потому что не имеет смысла иметь «MethodOfPayment», одновременно являющуюся как Visa, так и Mastercard. –

+0

Спасибо Скотту. Флаги были реликвией из другого перечисления с непересекающимися индексами. –

0

Когда оно десериализует значение, оно должно установить значение по умолчанию, если оно не может найти допустимое значение для использования во время десериализации. Поэтому он использует default(PaymentMethod), что и у (PaymentMethod)default(int).

Значение default(int) является 0, вы должны либо сделать 0 недействительное значение перечисления или сделать MethodOfPayment Nullable поэтому значение по умолчанию будет null вместо 0.

+0

Я предположил бы, что если бы он имел 'EmitDefaultValue = false', тогда он не будет интерпретировать пустые строки как значения по умолчанию. –

+0

@AndrewShepherd все еще нужно присвоить значение свойству или выбросить исключение. Поскольку OP использовал атрибут flags, не передающий значение, это то же самое, что сказать «Не устанавливать никаких флагов», и установите для перечисления значение 0. Поскольку значение 0 было допустимым значением, оно использовало MasterCard. –