如何使用 DataContractSerializer 忽略属性(无法删除 DataMember)?

Posted

技术标签:

【中文标题】如何使用 DataContractSerializer 忽略属性(无法删除 DataMember)?【英文标题】:How can I ignore a property with the DataContractSerializer (can't delete DataMember)? 【发布时间】:2016-06-13 20:26:06 【问题描述】:

我有以下自定义 DataContract 序列化程序:

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();

但我不想序列化所有内容。我想创建一个自定义属性“DoNotSerializeAttribute”。

如果DataContract 中的某些属性包含该属性,则忽略它并且不序列化,如果某些属性的名称中包含“密码”且不包含该属性,则生成异常。我怎样才能做到这一点?

【问题讨论】:

已经有这个***.com/questions/1791946/… 的属性你的问题应该是如何忽略DataContractSerializer 的属性。有关如何编写属性的信息,请参见此处msdn.microsoft.com/en-us/library/… 这不是你想要的吗? msdn.microsoft.com/en-us/library/… @ojf 更新问题 @SimonHardy 不,我不能使用它 好问题。我也有同样的问题。 【参考方案1】:

您可以删除 DataMember 属性并像这样保留您的属性:

public string Password  get; set; 

如果你的类用[DataContract] 装饰,DataContractSerializer 将序列化所有用DataMember 属性装饰的公共属性,如果你的类没有装饰你可以使用[IgnoreDataMember] 属性。

编辑

也许您可以尝试使用自定义代理,我不知道这是否是这样做的好方法。

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; 

【讨论】:

为什么我们需要创建MySurrogate ?也许我们可以var propeties = info.GetType().GetProperties().Where(m =&gt; m.GetCustomAttributes(typeof(EncryptedConfigurationItemAttribute), true).Any()); ?? MySurrogate 被用作DataContractSerializer 构造函数的参数,你到底是什么意思?

以上是关于如何使用 DataContractSerializer 忽略属性(无法删除 DataMember)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?