顽固对象不会使用 protobuf-net 进行序列化
我正在将 protobuf-net 集成到我们基于 WCF 服务的解决方案中,但遇到了我无法解决的问题。 以下类将正常序列化,除了 ObjectId 属性之外。
/// <summary>
/// A service data object that represents a user of the system.
/// </summary>
[DataContract(Namespace = "http://LINKS.Service.Security.Administration", Name = "User")]
public sealed class UserMessagePart : IMessagePart
{
private ObjectId objectId;
private string userName;
private string firstName;
private string lastName;
private string middleName;
private string gender;
private string emailAddress;
private bool isAccountDisabled;
private string disabledMeaning;
private DateTime createDtTm;
private DateTime disabledDtTm;
private VersionMessagePart version;
/// <summary>
/// Main constructor.
/// </summary>
public UserMessagePart(ObjectId objectId, string userName, string firstName, string lastName, string middleName,
string gender, string emailAddress, bool isAccountDisabled, string disabledMeaning, DateTime createDtTm,
DateTime disabledDtTm, VersionMessagePart version)
{
this.objectId = objectId;
this.userName = userName;
this.firstName = firstName;
this.lastName = lastName;
this.middleName = middleName;
this.gender = gender;
this.emailAddress = emailAddress;
this.isAccountDisabled = isAccountDisabled;
this.disabledMeaning = disabledMeaning;
this.createDtTm = createDtTm;
this.disabledDtTm = disabledDtTm;
this.version = version;
}
/// <summary>
/// Parameterless constructor.
/// </summary>
public UserMessagePart(){}
/// <summary>
/// The unique identifier for this user.
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "ObjectId", Order = 0)]
public ObjectId ObjectId
{
get { return objectId; }
set { objectId = value; }
}
/// <summary>
/// The user's login identity.
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "UserName", Order = 1)]
public string UserName
{
get { return userName; }
set { userName = value; }
}
// ...abbreviated code for readability...
/// <summary>
/// Version information for this user
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "Version", Order = 11)]
public VersionMessagePart Version
{
get { return version; }
set { version = value; }
}
}
这是在玩弄我的班级:
/// <summary>
/// Uniquely identifies any <see cref="IMessagePart"/> implementation in the system.
/// </summary>
[DataContract(Namespace = "http://LINKS.Service.Core", Name = "ObjectIdentifier")]
public class ObjectId
{
private string id;
private string domain;
private string modelName;
private long instanceId;
private int versionNumber;
/// <summary>
/// Default constructor. (required for Protobuf-net)
/// </summary>
public ObjectId()
{
}
/// <summary>
/// Main constructor.
/// </summary>
public ObjectId(string domain, string modelName, long instanceId, int versionNumber)
{
id = string.Format("{0}#{1}#{2}#{3}", domain, modelName, instanceId, versionNumber);
this.domain = domain;
this.modelName = modelName;
this.instanceId = instanceId;
this.versionNumber = versionNumber;
}
/// <summary>
/// The unique identifier for the <see cref="ObjectId"/>. The format of this string is not
/// guaranteed and should only be treated as a unique key. No attempts to parse it should be
/// made by client applications.
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "Id", Order = 0)]
public string Id
{
get { return id; }
set
{
id = value;
string[] parts = id.Split('#');
domain = parts[0];
modelName = parts[1];
instanceId = long.Parse(parts[2]);
versionNumber = int.Parse(parts[3]);
}
}
/// <summary>
/// The system domain that the <see cref="ObjectId"/> originated from.
/// </summary>
public string Domain
{
get { return domain; }
}
/// <summary>
/// The type of object that this <see cref="ObjectId"/> refers to.
/// </summary>
public string ModelName
{
get { return modelName; }
}
/// <summary>
/// The object instance identifier for the object that this <see cref="ObjectId"/>
/// refers to. Typically, this is a database key.
/// </summary>
public long InstanceId
{
get { return instanceId; }
}
/// <summary>
/// The version instance of the object referred to by this <see cref="ObjectId"/>
/// </summary>
public int VersionNumber
{
get { return versionNumber; }
}
/// <summary>
/// Returns a string representation of the object identifier.
/// </summary>
new public string ToString()
{
return id;
}
}
我尝试了多种方法,但没有运气。 任何想法将不胜感激!
I'm integrating protobuf-net into our WCF services based solution but have ran into a snag that I can't figure out. The following class will serialize fine, all except for the ObjectId property.
/// <summary>
/// A service data object that represents a user of the system.
/// </summary>
[DataContract(Namespace = "http://LINKS.Service.Security.Administration", Name = "User")]
public sealed class UserMessagePart : IMessagePart
{
private ObjectId objectId;
private string userName;
private string firstName;
private string lastName;
private string middleName;
private string gender;
private string emailAddress;
private bool isAccountDisabled;
private string disabledMeaning;
private DateTime createDtTm;
private DateTime disabledDtTm;
private VersionMessagePart version;
/// <summary>
/// Main constructor.
/// </summary>
public UserMessagePart(ObjectId objectId, string userName, string firstName, string lastName, string middleName,
string gender, string emailAddress, bool isAccountDisabled, string disabledMeaning, DateTime createDtTm,
DateTime disabledDtTm, VersionMessagePart version)
{
this.objectId = objectId;
this.userName = userName;
this.firstName = firstName;
this.lastName = lastName;
this.middleName = middleName;
this.gender = gender;
this.emailAddress = emailAddress;
this.isAccountDisabled = isAccountDisabled;
this.disabledMeaning = disabledMeaning;
this.createDtTm = createDtTm;
this.disabledDtTm = disabledDtTm;
this.version = version;
}
/// <summary>
/// Parameterless constructor.
/// </summary>
public UserMessagePart(){}
/// <summary>
/// The unique identifier for this user.
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "ObjectId", Order = 0)]
public ObjectId ObjectId
{
get { return objectId; }
set { objectId = value; }
}
/// <summary>
/// The user's login identity.
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "UserName", Order = 1)]
public string UserName
{
get { return userName; }
set { userName = value; }
}
// ...abbreviated code for readability...
/// <summary>
/// Version information for this user
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "Version", Order = 11)]
public VersionMessagePart Version
{
get { return version; }
set { version = value; }
}
}
Here's the class that's toying with me:
/// <summary>
/// Uniquely identifies any <see cref="IMessagePart"/> implementation in the system.
/// </summary>
[DataContract(Namespace = "http://LINKS.Service.Core", Name = "ObjectIdentifier")]
public class ObjectId
{
private string id;
private string domain;
private string modelName;
private long instanceId;
private int versionNumber;
/// <summary>
/// Default constructor. (required for Protobuf-net)
/// </summary>
public ObjectId()
{
}
/// <summary>
/// Main constructor.
/// </summary>
public ObjectId(string domain, string modelName, long instanceId, int versionNumber)
{
id = string.Format("{0}#{1}#{2}#{3}", domain, modelName, instanceId, versionNumber);
this.domain = domain;
this.modelName = modelName;
this.instanceId = instanceId;
this.versionNumber = versionNumber;
}
/// <summary>
/// The unique identifier for the <see cref="ObjectId"/>. The format of this string is not
/// guaranteed and should only be treated as a unique key. No attempts to parse it should be
/// made by client applications.
/// </summary>
[DataMemberAttribute(IsRequired = true, Name = "Id", Order = 0)]
public string Id
{
get { return id; }
set
{
id = value;
string[] parts = id.Split('#');
domain = parts[0];
modelName = parts[1];
instanceId = long.Parse(parts[2]);
versionNumber = int.Parse(parts[3]);
}
}
/// <summary>
/// The system domain that the <see cref="ObjectId"/> originated from.
/// </summary>
public string Domain
{
get { return domain; }
}
/// <summary>
/// The type of object that this <see cref="ObjectId"/> refers to.
/// </summary>
public string ModelName
{
get { return modelName; }
}
/// <summary>
/// The object instance identifier for the object that this <see cref="ObjectId"/>
/// refers to. Typically, this is a database key.
/// </summary>
public long InstanceId
{
get { return instanceId; }
}
/// <summary>
/// The version instance of the object referred to by this <see cref="ObjectId"/>
/// </summary>
public int VersionNumber
{
get { return versionNumber; }
}
/// <summary>
/// Returns a string representation of the object identifier.
/// </summary>
new public string ToString()
{
return id;
}
}
I've tried multiple things with no luck. Any thoughts would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
(我是 protobuf-net 的作者)
我即将离开,所以我无法验证“现在”,但初步猜测,我会说
Order = 0
看起来可能是罪魁祸首。 尝试使用Order = 1
或其他数字(“协议缓冲区”标识符必须为正数)。请注意,您需要在
ObjectId
和Id
上进行调整。我已经复制了上面的内容,我将在火车上检查...
另请注意,如果您使用程序集共享,则 WCF 挂钩效果最佳 - 即您在客户端和服务器上具有相同的类。 如果您使用 svcutl(或“添加服务引用”),它有时会重新映射数字; 有一个技巧可以解决这个问题 - 让我知道这是否是一个问题(基本上,请仔细检查工具生成的属性上的
Order
)(I'm the author of protobuf-net)
I'm about to leave, so I can't verify "right now", but at a first guess, I'd say that the
Order = 0
looks a likely culprit. TryOrder = 1
or some other number ("protocol buffers" identifiers must be positive).Note that you'll need to tweak this both on
ObjectId
and onId
.I've taken a copy of the above, and I'll check on the train...
Note also that the WCF hooks work best if you are using assembly sharing - i.e. you have the same class at the client and server. If you are using
svcutl
(or "Add Service Reference"), it sometimes remaps the numbers; there is a trick to fix this - let me know if this is an issue (basically, double check theOrder
on the properties generated by the tooling)