Десериализация пустого атрибута XML оценивает в nullable международное использование свойства XmlSerializer

Необходимо "снять" недженерик IEnumerable к IEnumerable<string>. Было предложено использовать OfType, но это - метод фильтрации. То, что Вы делаете, является эквивалентом броска, для которого существует Cast оператор:

var fields = RequestFields().Cast<string>();

, Поскольку Frans указал, это только обеспечивает доступ к ключам. Необходимо было бы все еще индексировать в набор для значений. Вот дополнительный метод для извлечения KeyValuePair с из NameValueCollection:

public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return collection.Cast<string>().Select(key => new KeyValuePair<string, string>(key, collection[key]));
}

Редактирование: В ответ на запрос @Ruben Bartelink, вот то, как получить доступ к полному набору значений для каждого ключа с помощью [1 110]:

public static ILookup<string, string> ToLookup(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    var pairs =
        from key in collection.Cast<String>()
        from value in collection.GetValues(key)
        select new { key, value };

    return pairs.ToLookup(pair => pair.key, pair => pair.value);
}

, С другой стороны, кортежи C# 7.0 использования:

public static IEnumerable<(String name, String value)> ToTuples(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return
        from key in collection.Cast<string>()
        from value in collection.GetValues(key)
        select (key, value);
}
73
задан Community 23 May 2017 в 12:10
поделиться

3 ответа

Я решил эту проблему, реализовав интерфейс IXmlSerializable. Я не нашел более простого способа.

Вот пример тестового кода:

[XmlRoot("root")]
public class DeserializeMe {
    [XmlArray("elements"), XmlArrayItem("element")]
    public List<Element> Element { get; set; }
}

public class Element : IXmlSerializable {
    public int? Value1 { get; private set; }
    public float? Value2 { get; private set; }

    public void ReadXml(XmlReader reader) {
        string attr1 = reader.GetAttribute("attr");
        string attr2 = reader.GetAttribute("attr2");
        reader.Read();

        Value1 = ConvertToNullable<int>(attr1);
        Value2 = ConvertToNullable<float>(attr2);
    }

    private static T? ConvertToNullable<T>(string inputValue) where T : struct {
        if ( string.IsNullOrEmpty(inputValue) || inputValue.Trim().Length == 0 ) {
            return null;
        }

        try {
            TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
            return (T)conv.ConvertFrom(inputValue);
        }
        catch ( NotSupportedException ) {
            // The conversion cannot be performed
            return null;
        }
    }

    public XmlSchema GetSchema() { return null; }
    public void WriteXml(XmlWriter writer) { throw new NotImplementedException(); }
}

class TestProgram {
    public static void Main(string[] args) {
        string xml = @"<root><elements><element attr='11' attr2='11.3'/><element attr='' attr2=''/></elements></root>";
        XmlSerializer deserializer = new XmlSerializer(typeof(DeserializeMe));
        Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
        var result = (DeserializeMe)deserializer.Deserialize(xmlStream);
    }
}
20
ответ дан 24 November 2019 в 12:24
поделиться

В последнее время я сам много возился с сериализацией и нашел следующие статьи и сообщения полезными, когда работа с нулевыми данными для типов значений.

Ответ на Как сделать тип значения допускающим значение NULL с помощью XmlSerializer в C # - сериализация описывает довольно изящный трюк XmlSerializer. В частности, XmlSerialier ищет логическое свойство XXXSpecified, чтобы определить, должно ли оно быть включено, что позволяет игнорировать значения NULL.

Алекс Скорделлис задал вопрос StackOverflow, на который был хороший ответ . Алекс также сделал хорошую запись в своем блоге о проблеме, которую он пытался решить Использование XmlSerializer для десериализации в Nullable .

Документация MSDN по Поддержка привязки атрибутов Xsi: nil тоже полезен. Как и документация по IXmlSerializable Interface , хотя написание собственной реализации должно быть вашим последним средством.

XmlSerialier ищет логическое свойство XXXSpecified, чтобы определить, следует ли его включать, что позволяет игнорировать значения NULL.

Алекс Скорделлис задал вопрос StackOverflow, на который получил хороший ответ . Алекс также сделал хорошую запись в своем блоге о проблеме, которую он пытался решить Использование XmlSerializer для десериализации в Nullable .

Документация MSDN по Поддержка привязки атрибутов Xsi: nil тоже полезен. Как и документация по IXmlSerializable Interface , хотя написание собственной реализации должно быть вашим последним средством.

XmlSerialier ищет логическое свойство XXXSpecified, чтобы определить, следует ли его включать, что позволяет игнорировать значения NULL.

Алекс Скорделлис задал вопрос StackOverflow, на который получил хороший ответ . Алекс также сделал хорошую запись в своем блоге о проблеме, которую он пытался решить Использование XmlSerializer для десериализации в Nullable .

Документация MSDN по Поддержка привязки атрибутов Xsi: nil тоже полезен. Как и документация по IXmlSerializable Interface , хотя написание собственной реализации должно быть вашим последним средством.

Алекс также сделал хорошую запись в своем блоге о проблеме, которую он пытался решить Использование XmlSerializer для десериализации в Nullable .

Документация MSDN по Поддержка привязки атрибутов Xsi: nil тоже полезен. Как и документация по IXmlSerializable Interface , хотя написание собственной реализации должно быть вашим последним средством.

Алекс также сделал хорошую запись в своем блоге о проблеме, которую он пытался решить Использование XmlSerializer для десериализации в Nullable .

Документация MSDN по Поддержка привязки атрибутов Xsi: nil тоже полезен. Как и документация по IXmlSerializable Interface , хотя написание собственной реализации должно быть вашим последним средством.

10
ответ дан 24 November 2019 в 12:24
поделиться

Это должно работать:

[XmlIgnore]
public int? Age { get; set; }

[XmlElement("Age")]
public string AgeAsText
{
  get { return (Age.HasValue) ? Age.ToString() : null; } 
  set { Age = !string.IsNullOrEmpty(value) ? int.Parse(value) : default(int?); }
}
57
ответ дан 24 November 2019 в 12:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: