2

I have the following custom DataContract serializer:

public string Serialize(JobInfo info)
{
    var stringBuilder = new StringBuilder();

    using (var stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture))
    {
        var writer = new XmlTextWriter(stringWriter);
        new DataContractSerializer(typeof(JobInfo)).WriteObject(writer, info);
    }

    return stringBuilder.ToString();
}

But I don't want to serialize everything. I would like to create a custom attribure "DoNotSerializeAttribute".

If some property in DataContract contain that attribute then ignore it and do not serialize and if some property contains "password" in the name and do not contain this attribute then generate exception. How can I do this?

  • 3
    There is already an Attribute for this http://stackoverflow.com/questions/1791946/how-can-i-ignore-a-property-when-serializing-using-the-datacontractserializer Your question should be How do I ignore a property with the DataContractSerializer. For info on how to write an attribute see here https://msdn.microsoft.com/en-us/library/aa288454%28v=vs.71%29.aspx?f=255&MSPPError=-2147217396 –  Mar 01 '16 at 12:14
  • 1
    Is this not what you're after? https://msdn.microsoft.com/en-us/library/system.runtime.serialization.ignoredatamemberattribute.aspx – Simon Hardy Mar 01 '16 at 12:23
  • @ojf Update question –  Mar 01 '16 at 12:51
  • @SimonHardy No, I cannot use it –  Mar 01 '16 at 12:55
  • 1
    Good question. I have the same problem. – Anatoly Mar 01 '16 at 12:57

1 Answers1

3

You can remove the DataMember attribute and keep your property like this :

public string Password { get; set; }

If your classe is decored with [DataContract] the DataContractSerializer will serialize all public properties decorated with DataMember attribute, and if your class is not decorated you can use [IgnoreDataMember] attribute.

EDIT

Maybe you can try with a custom surrogate I dont know if its the good way for doing this.

class Program
{
    static void Main(string[] args)
    {
        var s = Serialize(new BackgroundJobInfo() { Password = "toto", Text = "text" });
        var myJob = Deserialize(s);
    }

    public static string Serialize(BackgroundJobInfo info)
    {
        MySurrogate mySurrogate = new MySurrogate();
        DataContractSerializer dataContractSerializer =
            new DataContractSerializer(
            typeof(BackgroundJobInfo),
            null,
            64 * 1024,
            true,
            true,
            mySurrogate);

        var stringBuilder = new StringBuilder();

        using (var stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture))
        {
            var writer = new XmlTextWriter(stringWriter);
            dataContractSerializer.WriteObject(writer, info);
        }

        return stringBuilder.ToString();
    }

    public static BackgroundJobInfo Deserialize(string info)
    {
        var dataContractSerializer = new DataContractSerializer(typeof(BackgroundJobInfo));
        using (var xmlTextReader = new XmlTextReader(info, XmlNodeType.Document, new XmlParserContext(null, null, null, XmlSpace.None)))
        {
            try
            {
                var result = (BackgroundJobInfo)dataContractSerializer.ReadObject(xmlTextReader);
                return result;
            }
            catch (Exception e)
            {
                return null;
            }
        }
    }
}

internal class MySurrogate : IDataContractSurrogate
{
    public Type GetDataContractType(Type type)
    {
        return typeof (BackgroundJobInfo);
    }

    public object GetObjectToSerialize(object obj, Type targetType)
    {
        var maskedMembers = obj.GetType().GetProperties().Where(
            m => m.GetCustomAttributes(typeof(DataMemberAttribute), true).Any()
            && m.GetCustomAttributes(typeof(DoNotSerializeAttribute), true).Any());
        foreach (var member in maskedMembers)
        {
            member.SetValue(obj, null, null);
        }
        return obj;
    }

    public object GetDeserializedObject(object obj, Type targetType)
    {
        throw new NotImplementedException();
    }

    public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
    {
        throw new NotImplementedException();
    }

    public object GetCustomDataToExport(Type clrType, Type dataContractType)
    {
        throw new NotImplementedException();
    }

    public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
    {
        throw new NotImplementedException();
    }

    public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
    {
        throw new NotImplementedException();
    }

    public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
    {
        throw new NotImplementedException();
    }
}

internal class DoNotSerializeAttribute : Attribute
{
}

[DataContract]
public class BackgroundJobInfo
{
    [DataMember(Name = "password")]
    [DoNotSerializeAttribute]
    public string Password { get; set; }

    [DataMember(Name = "text")]
    public string Text { get; set; }
}

enter image description here

Quentin Roger
  • 6,410
  • 2
  • 23
  • 36
  • Why do we need to create `MySurrogate` ? Maybe we can just `var propeties = info.GetType().GetProperties().Where(m => m.GetCustomAttributes(typeof(EncryptedConfigurationItemAttribute), true).Any()); ` ?? –  Mar 01 '16 at 14:58
  • `MySurrogate` is used as a parameter for the `DataContractSerializer` constructor, what do you mean exactly ? – Quentin Roger Mar 01 '16 at 15:11