Комментарии 12
Double, int, bool — это типы значений (Value Types), и они не могут принимать значение null; в результате int свойства сериализуются значением по умолчанию (читай, если int свойству не присвоили значение, сериализуется 0).
Хм, а вы правда не знаете про
minOccurs="0"
и паттерн *Specified
, или просто в статье не упомянули?0
Знаю.
Но в данном случае они будут усложнять код DTO-класса.
Сравните:
и
При наличии одного-двух полей — можно и IsSpecified использовать; плюс, этот способ приходится использовать с атрибутами.
При наличии же большого числа Value Type полей мне кажется более удобным использовать оберточные типы, особенно, если они уже есть в готовом виде.
Но в данном случае они будут усложнять код DTO-класса.
Сравните:
[XmlElement]
public XmlDecimalWrapper NullableDecimal{get;set;}
и
[XmlElement]
public decimal NullableDecimal{get;set;}
[XmlIgnore]
public bool NullableDecimalSpecified{get{ AnyAdditionalLogicHere;}}
При наличии одного-двух полей — можно и IsSpecified использовать; плюс, этот способ приходится использовать с атрибутами.
При наличии же большого числа Value Type полей мне кажется более удобным использовать оберточные типы, особенно, если они уже есть в готовом виде.
+1
Почему нельзя использовать nullable-тип из коробки, для которого даже есть красивый синтаксис (int? etc)?
+1
Потому что XmlSerializer его не поддерживает.
0
Какой именно случай?
Сейчас запустил это
Вывод:
true
false
Сейчас запустил это
class Program
{
static void Main(string[] args)
{
var xml1 = XDocument.Parse("<Test><Prop>5</Prop></Test>");
var test1 = new XmlSerializer(typeof(Test)).Deserialize(xml1.CreateReader()) as Test;
var xml2 = XDocument.Parse("<Test></Test>");
var test2 = new XmlSerializer(typeof(Test)).Deserialize(xml2.CreateReader()) as Test;
Console.WriteLine(test1.Prop.HasValue);
Console.WriteLine(test2.Prop.HasValue);
}
}
public class Test
{
public int? Prop { get; set; }
}
Вывод:
true
false
0
А на запись?
0
Это у вас игра такая? Я же реально ответа не знал, потому и спросил…
Это сериализуется нормально
Это сериализуется нормально
var test1 = new Test() { Prop = 5 };
var test2 = new Test();
var writer1 = new StringWriter();
var writer2 = new StringWriter();
new XmlSerializer(typeof(Test)).Serialize(writer1, test1);
new XmlSerializer(typeof(Test)).Serialize(writer2, test2);
Console.WriteLine(writer1.ToString());
Console.WriteLine(writer2.ToString());
+1
Нормально — это как, с пропущенным тегом, или с
xsi:nil
? У меня просто сейчас нет возможности проверить.0
witer1:
writer2:
<?xml version="1.0" encoding="utf-16"?>
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Prop>5</Prop>
</Test>
writer2:
<?xml version="1.0" encoding="utf-16"?>
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Prop xsi:nil="true" />
</Test>
0
К сожалению все эти Wrapper'ы не помогут сохранять примитивы в аттрибуты…
+1
Да, с атрибутами приходится использовать *Specified, и красивого способа решить эту проблему я пока не вижу. Разве что, сниппет написать, или над когогенерирующей утилитой задуматься.
С перечислениями тоже неудобно работать. Писать обертку на каждый enum — раздувать проект, а удобную обобщенную оболочку вроде
написать не получится.
С перечислениями тоже неудобно работать. Писать обертку на каждый enum — раздувать проект, а удобную обобщенную оболочку вроде
public class EnumWrapper<T> where T : Enum
написать не получится.
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Как приготовить DTO?