如何有效地序列化DataContract属性类中“类型”类型的属性?我假设Type是一个不可序列化的类型(哇,这听起来有点傻)。我确信有一种方法可以满足我的需求。基本上,我需要序列化工厂方法的类型名称才能有效地构造,但我不想将其公开为字符串,我想要一个类型。
我知道有许多方法可以做到这一点,我很好奇目前还知道哪些其他方法。
编辑:我刚刚意识到可能是其他原因造成的,但这里是错误,下面我有类定义。
数据协定名称为'RuntimeType:http://schemas.datacontract.org/2004/07/System‘的类型'System.RuntimeType’不应为空。考虑使用DataContractResolver或将任何未知类型静态添加到已知类型列表中-例如,通过使用KnownTypeAttribute属性或通过将它们添加到传递给DataContractSerializer的已知类型列表中。
[DataContract]
public class PlottingDeviceInfo : ObservableObject
{
private string _deviceName;
[DataMember]
public string DeviceName
{
get
{
return _deviceName;
}
set
{
Set(() => DeviceName, ref _deviceName, value);
}
}
private Type _deviceType;
[DataMember]
public Type DeviceType
{
get
{
return _deviceType;
}
set
{
Set(() => DeviceType, ref _deviceType, value);
}
}
private DeviceSettingsInfo _settings;
[DataMember]
public DeviceSettingsInfo Settings
{
get
{
return _settings;
}
set
{
Set(() => Settings, ref _settings, value);
}
}
private DeviceChannelInfo _channel;
[DataMember]
public DeviceChannelInfo Channel
{
get
{
return _channel;
}
set
{
Set(() => Channel, ref _channel, value);
}
}
private DeviceCategory _deviceCategory;
[IgnoreDataMember]
public DeviceCategory DeviceCategory
{
get
{
return _deviceCategory;
}
set
{
Set(() => DeviceCategory, ref _deviceCategory, value);
}
}
}
下面是基类,用于添加视图模型消耗的可观察性。
[DataContract]
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[IgnoreDataMember]
protected PropertyChangedEventHandler PropertyChangedHandler
{
get
{
return PropertyChanged;
}
}
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
var myType = this.GetType();
if (!string.IsNullOrEmpty(propertyName)
&& myType.GetProperty(propertyName) == null)
{
throw new ArgumentException("Property not found", propertyName);
}
}
protected virtual void RaisePropertyChanged(string propertyName)
{
VerifyPropertyName(propertyName);
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
if (propertyExpression == null)
{
return;
}
var handler = PropertyChanged;
if (handler != null)
{
var body = propertyExpression.Body as MemberExpression;
handler(this, new PropertyChangedEventArgs(body.Member.Name));
}
}
protected void Set<T>(
Expression<Func<T>> propertyExpression,
ref T field,
T newValue)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
{
return;
}
field = newValue;
RaisePropertyChanged(propertyExpression);
}
protected void Set<T>(
string propertyName,
ref T field,
T newValue)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
{
return;
}
field = newValue;
RaisePropertyChanged(propertyName);
}
}
发布于 2011-09-20 17:04:35
Type
不能以跨平台的方式表示,因此它没有内置的表示形式。最好的办法是将其表示为一个字符串,即
public Type DeviceType { get; set; }
[DataMember(Name="DeviceType")]
private string DeviceTypeName {
get { return DeviceType == null ? null : DeviceType.AssemblyQualifiedName; }
set { DeviceType = value == null ? null : Type.GetType(value); }
}
发布于 2011-09-20 16:36:16
将带有作为类型传入的System.RuntimeType
的KnownType
属性添加到根类。
在C#中,
[KnownType(typeof(System.RuntimeType))]
发布于 2013-04-11 15:05:21
您还可以做的是在DataContractSerializer
的构造函数中传递一个IDataContractSurrogate
,特别是在不想更改PlottingDeviceInfo
的情况下。我所做的(不知道是否有更简单的方法)是定义
public class TypeWrapper
{
public string TypeName;
}
然后像这样使用它:
public class TypeReplacementSurrogate : IDataContractSurrogate
{
public object GetCustomDataToExport(Type clrType, Type dataContractType)
{
return null;
}
public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
{
return null;
}
public Type GetDataContractType(Type type)
{
if(type == typeof(Type))
{
return typeof (TypeWrapper);
}
return type;
}
public object GetDeserializedObject(object obj, Type targetType)
{
var objAsTypeWrapper = obj as TypeWrapper;
if (objAsTypeWrapper != null)
{
return Assembly.GetExecutingAssembly().GetType(objAsTypeWrapper.TypeName);
}
return obj;
}
public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes)
{
}
public object GetObjectToSerialize(object obj, Type targetType)
{
var objAsType = obj as Type;
if (objAsType != null)
{
return new TypeWrapper() {TypeName = objAsType.FullName};
}
return obj;
}
public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
{
return null;
}
public System.CodeDom.CodeTypeDeclaration ProcessImportedType(
System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
{
return null;
}
}
https://stackoverflow.com/questions/7488488
复制相似问题