Protobuf net 没有为类型定义序列化程序:System.Drawing.Color
为了减少网络流量,我想使用protobuf net来代替BinaryFormatter,但发生了以下错误:Protobuf net 没有为类型定义序列化程序:System.Drawing.Color,protobuf-net,Protobuf Net,为了减少网络流量,我想使用protobuf net来代替BinaryFormatter,但发生了以下错误: No serializer defined for type: System.Drawing.Color WBMessage: [ProtoContract] [Serializable] public abstract class WBMessage { [ProtoMember(1)] public Color setColor1; [ProtoMember
No serializer defined for type: System.Drawing.Color
WBMessage:
[ProtoContract]
[Serializable]
public abstract class WBMessage
{
[ProtoMember(1)]
public Color setColor1;
[ProtoMember(2)]
public UInt16 userNo;
public abstract WHITEBOARD_MESSAGE_TYPE MessageType
{
get;
}
[ProtoMember(3)]
public string age;
public enum WHITEBOARD_MESSAGE_TYPE
{
enWBBegin,
enWBLine,
enWBRectangle,
enWBRectangleF,
enWBEllipse,
enWBEllipseF,
enWBClearScreen,
enWBText,
enWBEnd
};
}
[ProtoContract]
[ProtoInclude(1, typeof(WBMessage))]
public class WBMsgDrawBegin : WBMessage
{
private const WHITEBOARD_MESSAGE_TYPE m_enMsgType = WHITEBOARD_MESSAGE_TYPE.enWBBegin;
public override WHITEBOARD_MESSAGE_TYPE MessageType
{
get
{
return m_enMsgType;
}
}
[ProtoMember(4)]
public int x;
[ProtoMember(5)]
public int y;
[ProtoMember(6)]
public bool m_bMouseDown;
[ProtoMember(7)]
public string name;
}
WBMsgDrawBegin item1 = new WBMsgDrawBegin();
item1.setColor1 = Color.AliceBlue;
item1.name = "test";
item1.age = "31";
item1.x = 10998;
item1.y = 10089;
Stream stream = new MemoryStream();
MemoryStream ms = new MemoryStream();
Serializer.SerializeWithLengthPrefix<WBMsgDrawBegin>(ms, item1, PrefixStyle.Base128, 0);
WBMsgDrawBegin:
[ProtoContract]
[Serializable]
public abstract class WBMessage
{
[ProtoMember(1)]
public Color setColor1;
[ProtoMember(2)]
public UInt16 userNo;
public abstract WHITEBOARD_MESSAGE_TYPE MessageType
{
get;
}
[ProtoMember(3)]
public string age;
public enum WHITEBOARD_MESSAGE_TYPE
{
enWBBegin,
enWBLine,
enWBRectangle,
enWBRectangleF,
enWBEllipse,
enWBEllipseF,
enWBClearScreen,
enWBText,
enWBEnd
};
}
[ProtoContract]
[ProtoInclude(1, typeof(WBMessage))]
public class WBMsgDrawBegin : WBMessage
{
private const WHITEBOARD_MESSAGE_TYPE m_enMsgType = WHITEBOARD_MESSAGE_TYPE.enWBBegin;
public override WHITEBOARD_MESSAGE_TYPE MessageType
{
get
{
return m_enMsgType;
}
}
[ProtoMember(4)]
public int x;
[ProtoMember(5)]
public int y;
[ProtoMember(6)]
public bool m_bMouseDown;
[ProtoMember(7)]
public string name;
}
WBMsgDrawBegin item1 = new WBMsgDrawBegin();
item1.setColor1 = Color.AliceBlue;
item1.name = "test";
item1.age = "31";
item1.x = 10998;
item1.y = 10089;
Stream stream = new MemoryStream();
MemoryStream ms = new MemoryStream();
Serializer.SerializeWithLengthPrefix<WBMsgDrawBegin>(ms, item1, PrefixStyle.Base128, 0);
用法:
[ProtoContract]
[Serializable]
public abstract class WBMessage
{
[ProtoMember(1)]
public Color setColor1;
[ProtoMember(2)]
public UInt16 userNo;
public abstract WHITEBOARD_MESSAGE_TYPE MessageType
{
get;
}
[ProtoMember(3)]
public string age;
public enum WHITEBOARD_MESSAGE_TYPE
{
enWBBegin,
enWBLine,
enWBRectangle,
enWBRectangleF,
enWBEllipse,
enWBEllipseF,
enWBClearScreen,
enWBText,
enWBEnd
};
}
[ProtoContract]
[ProtoInclude(1, typeof(WBMessage))]
public class WBMsgDrawBegin : WBMessage
{
private const WHITEBOARD_MESSAGE_TYPE m_enMsgType = WHITEBOARD_MESSAGE_TYPE.enWBBegin;
public override WHITEBOARD_MESSAGE_TYPE MessageType
{
get
{
return m_enMsgType;
}
}
[ProtoMember(4)]
public int x;
[ProtoMember(5)]
public int y;
[ProtoMember(6)]
public bool m_bMouseDown;
[ProtoMember(7)]
public string name;
}
WBMsgDrawBegin item1 = new WBMsgDrawBegin();
item1.setColor1 = Color.AliceBlue;
item1.name = "test";
item1.age = "31";
item1.x = 10998;
item1.y = 10089;
Stream stream = new MemoryStream();
MemoryStream ms = new MemoryStream();
Serializer.SerializeWithLengthPrefix<WBMsgDrawBegin>(ms, item1, PrefixStyle.Base128, 0);
WBMsgDrawBegin item1=新的WBMsgDrawBegin();
item1.setColor1=Color.AliceBlue;
item1.name=“测试”;
项目1.age=“31”;
项目1.x=10998;
第1项y=10089;
Stream=新的MemoryStream();
MemoryStream ms=新的MemoryStream();
Serializer.SerializeWithLengthPrefix(ms,item1,PrefixStyle.Base128,0);
那么问题是什么
内置颜色类没有序列化程序
如果您想通过有线传输颜色,则必须使用其他表示方式,例如为ARGB发送32位整数,这是颜色的常见做法
有许多传达颜色的标准方式。不过,我建议你坚持一种标准的方式,而不是试图定义自己的方式。只需使用32位整数或4字节ARGB即可。它不能保证处理所有已知的BCL类型,特别是图形库之类的类型,这些类型在所有平台上都不受支持。我建议:
public Color Foo {get;set;}
[ProtoMember(n, DataFormat=DataFormat.Fixed)]
private int FooSerialized {
get { return Foo.ToArgb(); }
set { Foo = Color.FromArgb(value); }
}
将其序列化为固定的4字节块。如果你有很多颜色属性,你也可以使用一个“代理”来做一些非常类似的事情(代码更少,但每个项目多2个字节)。因为我整个上午都在努力做类似的事情,我要补充的是,另一种存储点、大小、矩形和颜色等的方法是使用NET的内置转换器。代码是用VB编写的,但您应该充分了解漂移:
Imports System.Drawing
Imports System.ComponentModel
Private Function GetInvariantString(ByVal v As Object) As String
Dim conv As TypeConverter = TypeDescriptor.GetConverter(v.GetType)
Dim t As System.Type = v.GetType
' at least in VB '=' and 'Is' are not defined for Boolean
' and System.Type so I cant find a way to word the Case
' test so, it's inverted...only one Case can be true anyway
Select Case True
...
Case t Is GetType(Drawing.Point)
Return conv.ConvertToInvariantString(v)
Case t Is GetType(Drawing.Size)
Return conv.ConvertToInvariantString(v)
Case t Is GetType(Drawing.Color)
Return conv.ConvertToInvariantString(v)
Case Else
Throw New ArgumentException("Unknown Type " & v.type.ToString)
End Select
End Function
myPoint.ToString
的简单方法将返回类似于{X=11 Y=156}
的内容,但是对于这里处理的类型,并不总是有一个互补的FromString
方法ConvertToInvariantString
返回11156
,可用于重建点(以及其他点):
矩形、SizeF等(甚至字体)都可以用相同的方式处理。就个人而言,对于Color
而言,我更喜欢存储/传递表示ARGB值的Int,但是不变字符串方法也可以很好地工作,如果颜色是一种命名颜色,比如“Red”,那么Red
就是返回/序列化的全部内容。用法:
' serializer version
<ProtoMember(6)> _
Private Property PBNImgPoint() As String
Get
Return GetInvariantString(_ImgPoint)
End Get
Set(ByVal value As String)
_ImgPoint = TypeFromInvariantString(value, GetType(Point))
End Set
End Property
' method used in code/program....
Friend Property ImgPoint() As Point
Set(ByVal value As Point)
_ImgPoint = value
End Set
Get
Return _ImgPoint
End Get
End Property
序列化程序版本
_
私有属性PBNImgPoint()作为字符串
得到
返回GetInvariantString(_ImgPoint)
结束
设置(ByVal值作为字符串)
_ImgPoint=TypeFromInvariantString(值,GetType(点))
端集
端属性
'代码/程序中使用的方法。。。。
友元属性ImgPoint()作为点
设置(ByVal值作为点)
_ImgPoint=值
端集
得到
返回点
结束
端属性
显然,转换可以在每个Getter/Setter中进行,而不是在一个被调用的过程中进行,但是我的试验/测试用例有多个点、矩形和大小,我想确保它们都得到了相同的处理
HTH你能把WBMessage类定义的其余部分包括进来吗?马克,谢谢你的回答,我的问题已经解决了。还有一个问题,你能告诉我如何序列化点的数据类型。@Hudson点的确切类型是什么?有几个,来自不同的框架现在我正在用visual c开发一个项目,框架的版本是V3.5。这个解决方案要求每个要序列化的
颜色值都有一个单独的属性。“代理”似乎是一个更好的解决方案,尽管我不认为这允许您将颜色存储为原始整数(即代理具有更高的开销,并且与上述解决方案不兼容):谢谢您的回答。我是.Net开发的新手,所以始终使用默认数据类型,例如颜色,我使用System.drawing.color类,point我使用System.drawing.point类。现在根据你的建议,颜色问题已经解决了。