Serialize ASCIIEncoding

196
20 декабря 2017, 19:10

Работаю сейчас с AR (Active Reports), есть у них классы HTMLExport, PdfExport, TextExport. Так вот в текст экспорт есть public свойство Encoding Encoding, которое содержит кодировки. При сериализации этого объекта падает exception который описал выше.

Решил немного поэкспериментировать и попробовать сериализовать, например, объект типа ASCIIEncoding и снова получаю ошибку

The type System.Text.EncoderReplacementFallback was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

Хотя класс с атрибутом Serializable. Код примера ниже:

class Program
{
    static readonly XmlSerializer serializer = new XmlSerializer(typeof (ASCIIEncoding));
    static void Main(string[] args)
    {
        // СЕРИАЛИЗАЦИЯ.
        using (var stream = new FileStream("Serialization.xml", FileMode.Create, FileAccess.Write, FileShare.Read))
        {
            // Сохраняем объект в XML-файле на диске(СЕРИАЛИЗАЦИЯ).
            try
            {
                serializer.Serialize(stream, new ASCIIEncoding());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}
Answer 1

Как уже сказано в комментариях, атрибут Serializable не имеет отношения к xml-сериализации, он нужен для BinaryFormatterа.

Класс Encoding напрямую нельзя сериализовать в xml. Поэтому, как предложил VladD, нужно вместо него сериализовать собственный объект. Например, так:

public class Test
{
    [XmlIgnore]
    public Encoding Encoding { get; set; }
    [XmlElement("Encoding")]
    public string EncodingValue
    {
        get => Encoding.EncodingName;
        set => Encoding = Encoding.GetEncoding(value);
    }
}

Свойство Encoding помечаем атрибутом XmlIgnore - в результате сериализатор не будет обращать на него внимания. А вместо него в будет (де)сериализоваться его строковое значение.

Недостаток этого способа в том, что теперь в нашем классе присутствует лишнее свойство EncodingValue.

Answer 2

Идею уловил. Буду думать. Хотя ситуация у меня немного сложнее. Есть класс TextExport. Он от стороннего разработчика и sealed. Этот класс содержит свойство Encoded которое не хотело сериализоваться, когда использовал XmlSerializer. Пока ищу решение временно отключил сериализацию этого свойства.

public static string Serialize(object exportObject)
    {
        if (exportObject == null)
            throw new ArgumentNullException("exportObject cannot be null.");
        try
        {
            var overrides = new XmlAttributeOverrides();
            var attrs = new XmlAttributes { XmlIgnore = true };
            overrides.Add(typeof(Component), "Site", attrs);
            attrs = new XmlAttributes { XmlIgnore = true };
            overrides.Add(typeof(TextExport), "Encoding", attrs);
            var temp = new XmlSerializer(typeof(T), overrides);
            var stringWriter = new StringWriter();
            temp.Serialize(stringWriter, exportObject);
            string serializedXml = stringWriter.ToString();
            stringWriter.Dispose();
            return serializedXml;
        }
        catch (Exception ex)
        {
            throw new Exception("Could not serialize the object.", ex);
        }
    }
READ ALSO
Не вызывается callback потока в C#

Не вызывается callback потока в C#

Имеется приложение на C# ASPNET MVC

209
Как передать state в this.props.children. React

Как передать state в this.props.children. React

ПриветНе знаю как при загрузке с помощью react-router какогото layaut-а передать state в this

261
Две разные строки попадают под одну регулярку

Две разные строки попадают под одну регулярку

Есть строка две строки, которые мне нужно распознавать регулярками, как разные строки /tickets/moscow/tokyo/ и /tickets/moscow/Я написал сначала регулярку...

292
Как отформатировать число в JS и вывести в pug?

Как отформатировать число в JS и вывести в pug?

Всем доброго времени сутокПередаю в вид объект

289