Marc
Marc

Reputation: 993

Don't serialize Caliburn.Micro IsNotifying property

I'm implementing INotifyPropertyChanged in my ModelBase class so that all of my derived classes have access to the INotifyPropertyChanged methods and events.

I'm using Caliburn.Micro in my project so I was doing this by implementing INotifyPropertyChangedEx in my IModelBase interface and then extending PropertyChangedBase in my ModelBase class.

This all works great, except that the IsNotifying property from PropertyChangedBase is getting serialized with my models. I tried a few things but haven't been able to get it to stop serializing.

I tried overriding IsNotifying in ModelBase and added [XmlIgnore] to the property. I also tried hiding IsNotifying by using the new keyword in my ModelBase class. Neither of these worked.

I copied the PropertyChangedBase code from github, put it into my own PropertyChangedBase class, and then added [XmlIgnore] to the IsNotifying property. This worked, but isn't ideal.

Any ideas? Can this be done? Should I just scrap using the Caliburn.Micro PropertyChangedBase and implement my own? It isn't difficult to implement INotifyPropertyChanged. I was just trying to use the one in Caliburn.Micro since I'm already using the library.

This is a simple example that writes the XML to the console

using System;
using System.IO;
using System.Xml.Serialization;
using Caliburn.Micro;

namespace CaliburnPropertyChangedBase
{
    internal class Program
    {
        private static void Main()
        {
            var myModel = new MyModel {SomeProperty = "Test"};

            Console.WriteLine(myModel.SerializeObject());
            Console.ReadKey();
        }
    }

    public static class XmlHelper
    {
        public static string SerializeObject<T>(this T toSerialize)
        {
            var xmlSerializer = new XmlSerializer(toSerialize.GetType());

            using (var textWriter = new StringWriter())
            {
                xmlSerializer.Serialize(textWriter, toSerialize);
                return textWriter.ToString();
            }
        }
    }

    public interface IModelBase : INotifyPropertyChangedEx
    {
    }

    public class ModelBase : PropertyChangedBase, IModelBase
    {
    }

    public interface IMyModel : IModelBase
    {
        string SomeProperty { get; set; }
    }

    public class MyModel : ModelBase, IMyModel
    {
        public string SomeProperty { get; set; }
    }
}

This is the output

<?xml version="1.0" encoding="utf-16"?>
<MyModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <IsNotifying>true</IsNotifying>
  <SomeProperty>Test</SomeProperty>
</MyModel>

Upvotes: 0

Views: 247

Answers (1)

Frank
Frank

Reputation: 4481

In your SerializeObject<T> method, try this:

var overrides = new XmlAttributeOverrides();
overrides.Add(typeof(PropertyChangedBase), "IsNotifying", new XmlAttributes
{
    XmlIgnore = true,
});
var xmlSerializer = new XmlSerializer(toSerialize.GetType(), overrides);

The XmlAttributeOverrides type lets you customize everything that can be done using xml serializer attributes - but at runtime. I was amazed when I found out.

Further reading: .NET Framework Documentation

Upvotes: 1

Related Questions