我想序列化datacontract 这是代码datacontract
webpages
当我序列化到这段代码时
[Serializable]
//[DataContract(Name = "Shared", Namespace = "PJ")]
[DataContract]
[KnownType(typeof(System.Windows.Media.MatrixTransform))]
[System.Runtime.Serialization.KnownType(typeof(TPropHatchBrush))]
[System.Runtime.Serialization.KnownType(typeof(System.Windows.Input.Cursor))]
public class TPropHatchBrush : TPropBrush, ICloneable
{
[DataMember]
public UInt32 uColor = 0xFFFE0606;
[DataMember]
public double Opacity = 1;
[DataMember]
public VisualBrush theBrush = new VisualBrush();
[DataMember]
public Grid grd = new Grid();
[DataMember]
public Path path = new Path();
[DataMember]
public SolidColorBrush blackBrush = new SolidColorBrush();
//[DataMember]
//public BitmapSource bmp = null;
public Color Color
{
get
{
return TUtility.ColorFromUInt32(uColor);
}
set
{
uColor = TUtility.ColorToUInt32(value);
}
}
//
public TPropHatchBrush()
{
BrushType = BrushType.Hatch;
path.Data = Geometry.Parse("M 0 0 L 15 15");
blackBrush.Color = Colors.Black;
path.Stroke = blackBrush;
//path.StrokeThickness = 3;
path.Fill = blackBrush;
grd.Children.Add(path);
theBrush.Viewport = new Rect(0, 0, 0.15, 0.15);
theBrush.TileMode = TileMode.Tile;
// Set Visual of VisualBrush
//theBrush.Visual = grd;
}
override public Brush getBrush()
{
SolidColorBrush br = new SolidColorBrush(Color);
br.Opacity = Opacity;
return br;
}
/*override public bool FromArrayByte(byte[] val)
{
TPropHatchBrush tbrush = (TPropHatchBrush)CSerialization.dataContractDeserializer(val, typeof(TPropHatchBrush));
return false;
}*/
public override bool FromArrayByte(byte[] val)
{
TPropHatchBrush tbrush = (TPropHatchBrush)CSerialization.dataContractDeserializer(val, typeof(TPropHatchBrush));
return false;
}
public byte[] ToArrayByte()
{
//return CSerialization.saveSerializableObject(this);
//CSerialization.dataContractSerializer(@"e:\test.xml", this);
return CSerialization.dataContractSerializer(this);
}
override public void CopyFrom(TPropBrush to, TPropBrush from)
{
((TPropHatchBrush)to).BrushType = ((TPropHatchBrush)from).BrushType;
((TPropHatchBrush)to).uColor = ((TPropHatchBrush)from).uColor;
((TPropHatchBrush)to).Opacity = ((TPropHatchBrush)from).Opacity;
}
public object Clone()
{
TPropHatchBrush to = new TPropHatchBrush();
CopyFrom(to, this);
return to;
}
override public bool FromBrush(Brush br)
{
SolidColorBrush sbr;
try
{
sbr = (SolidColorBrush)br;
Color = sbr.Color;
Opacity = sbr.Opacity;
}
catch
{
return false;
}
return false;
}
}
我有错误,错误警告是
public static byte[] dataContractSerializer(object obj)
{
MemoryStream ms = new MemoryStream();
DataContractSerializer ser = new DataContractSerializer(obj.GetType());
XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms);
ser.WriteObject(binaryDictionaryWriter, obj);
binaryDictionaryWriter.Flush();
byte[] data = ms.ToArray();
return data;
}
如何解决这个问题? 首先我得到一个错误MatrixTransform,所以我在Input.Cursor中使用了knowntype MatrixTransform和错误,所以我使用了knowntype Input.Cursor并且仍然出错。
修改
这是序列化之前的结果datacontract对象
感谢
答案 0 :(得分:0)
您无法序列化游标。如果它是使用ToString()方法的标准类型之一,则可以序列化游标的名称,并使用CursorConverter类对其进行反序列化。
String cursorName = System.IO.File.ReadAllText("I:\\cursor.txt");
CursorConverter cnv = new CursorConverter();
Cursor c = (Cursor) cnv.ConvertFromString(cursorName);
如果光标存在于文件中,则可以从该文件中获取byte []并对其进行序列化。然后在反序列化时,使用它的构造函数从byte []创建一个MemoryStream,并使用Cursor的构造函数从该内存流加载Cursor。
byte[] cursorBytes = ...
MemoryStream ms = new MemoryStream(cursorBytes);
Cursor c1 = new Cursor(ms);
答案 1 :(得分:0)
我能够使用以下minimal, complete, and verifiable测试用例重现您的问题:
[DataContract]
public class TPropHatchBrush : IDisposable
{
System.Windows.Input.Cursor cursor;
[DataMember]
public System.Windows.Input.Cursor Cursor { get { return cursor; } set { cursor = value; } }
#region IDisposable Members
public void Dispose()
{
var oldCursor = Interlocked.Exchange(ref this.cursor, null);
if (oldCursor != null)
oldCursor.Dispose();
}
#endregion
}
问题是Cursor
类根本不可序列化 - 加载后没有API可以保存。但是,可以使用standard set of cursors将游标转换为其名称,该名称可以是CursorConverter
中的名称,也可以是加载游标的文件名。您可以利用这一事实在序列化期间用data contract surrogate替换Cursor
,SO link存储游标的名称,而不是游标本身。反序列化时,代理将尝试从名称中重新加载游标:
public class CursorDataSurrogate : IDataContractSurrogate
{
[DataContract(Namespace = "")]
class CursorName
{
[DataMember]
public string Name { get; set; }
}
#region IDataContractSurrogate Members
public object GetCustomDataToExport(Type clrType, Type dataContractType)
{
throw new NotImplementedException();
}
public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
{
throw new NotImplementedException();
}
public Type GetDataContractType(Type type)
{
if (type == typeof(System.Windows.Input.Cursor))
return typeof(CursorName);
return type;
}
public object GetDeserializedObject(object obj, Type targetType)
{
if (obj is CursorName)
{
try
{
return (System.Windows.Input.Cursor)TypeDescriptor.GetConverter(typeof(System.Windows.Input.Cursor)).ConvertFromInvariantString(((CursorName)obj).Name);
}
catch (Exception ex)
{
// ArgumentException or Win32Exception could be generated if file is missing or name is invalid. Handle here, or pass on?
throw;
}
}
return obj;
}
public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
{
throw new NotImplementedException();
}
public object GetObjectToSerialize(object obj, Type targetType)
{
if (obj is System.Windows.Input.Cursor)
{
return new CursorName { Name = TypeDescriptor.GetConverter(typeof(System.Windows.Input.Cursor)).ConvertToInvariantString(obj) };
}
return obj;
}
public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
{
throw new NotImplementedException();
}
public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
{
throw new NotImplementedException();
}
#endregion
}
然后,在您的方法dataContractSerializer
中,使用它:
var ser = new DataContractSerializer(obj.GetType(), new Type[] { }, Int32.MaxValue, false, false, new CursorDataSurrogate());
由此产生的XML看起来像:
<TPropHatchBrush xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Question32622276"> <Cursor xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Windows.Input"> <Name xmlns="">IBeam</Name> </Cursor> </TPropHatchBrush>
请注意,如果光标不存在,按名称加载游标的方法可能会引发异常 - 例如因为加载它的文件不再存在。您可能需要修改代理来处理此问题,而不仅仅是重新抛出异常。