英文:
Unique ID being changed when deserializing JSON - it should stay the same
问题
在构造函数触发时生成一个新的唯一ID。然而,当我对其进行序列化然后反序列化时,我的ID再次生成,因为它似乎又创建了一个新对象。停止此行为的最简单方法是什么?(如果可能的话,我想保留构造函数中的唯一guid生成)
<Serializable>
Public Class YubikeyPool
Public ReadOnly Property ID As Guid
Public Property Name As String
Public Sub New()
' 在反序列化时不要重新生成ID
If Not System.Runtime.Serialization.FormatterServices.IsConstructorInvocation Then
ID = Guid.NewGuid()
End If
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
这里是我的序列化/反序列化函数:
Function Serialize(ByVal objData As Object) As Byte()
If objData Is Nothing Then Return Nothing
Return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(objData, GetJsonSerializerOptions()))
End Function
Function Deserialize(Of T)(ByVal byteArray As Byte()) As T
If byteArray Is Nothing OrElse Not byteArray.Any() Then Return Nothing
Return JsonSerializer.Deserialize(Of T)(byteArray, GetJsonSerializerOptions())
End Function
Private Function GetJsonSerializerOptions() As JsonSerializerOptions
Dim options = New JsonSerializerOptions
With options
.PropertyNamingPolicy = Nothing
.WriteIndented = True
.AllowTrailingCommas = True
.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
End With
Return options
End Function
请注意,我在构造函数中添加了一个条件,以确保只有在反序列化时才会生成新的ID。这样,当您进行序列化和反序列化时,ID将保持不变。
英文:
I have a small class in which when the constructor is fired it generates a new unique ID. However, when I serialize it and then deserialize it my ID is being generated again because it seems to be creating a new object again. What is the easiest way to stop this behavior? (I would like to keep the unique guid generation in the constructor if possible)
<Serializable>
Public Class YubikeyPool
Public ReadOnly Property ID As Guid
Public Property Name As String
Public Sub New()
ID = Guid.NewGuid()
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
Here is my Serialize/Deserialize functions
Function Serialize(ByVal objData As Object) As Byte()
If objData Is Nothing Then Return Nothing
Return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(objData, GetJsonSerializerOptions()))
End Function
Function Deserialize(Of T)(ByVal byteArray As Byte()) As T
If byteArray Is Nothing OrElse Not byteArray.Any() Then Return Nothing
Return JsonSerializer.Deserialize(Of T)(byteArray, GetJsonSerializerOptions())
End Function
Private Function GetJsonSerializerOptions() As JsonSerializerOptions
Dim options = New JsonSerializerOptions
With options
.PropertyNamingPolicy = Nothing
.WriteIndented = True
.AllowTrailingCommas = True
.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
End With
Return options
End Function
答案1
得分: 3
构造函数将会运行。保留先前值的唯一方法是覆盖构造函数的工作,并在反序列化时设置该值以及其他属性...但目前无法进行此操作,因为该属性标记为ReadOnly
。首先移除该修饰符。
英文:
The constructor WILL run. The only way to keep a prior value is to overwrite the constructor's work and the set the value along with other properties when you deserialize... which can't happen right now because the property is marked ReadOnly
. Start by removing that modifier.
答案2
得分: 0
You can probably make a little change to your class definition, using an overloaded Constructor and decorating the default Constructor with [JsonConstructorAttribute]
你可以对你的类定义进行一些小的更改,使用一个重载的构造函数,并在默认构造函数上添加 [JsonConstructorAttribute]
。
The read-only property (here, the property has a private
setter) can be decorated with a [JsonIncludeAttribute]
. In this case, the non-public setter is used. For example:
只读属性(这里属性具有private
setter)可以使用[JsonIncludeAttribute]
进行修饰。在这种情况下,将使用非公共的setter。例如:
(in C#, since you have tagged this language)
(在C#中,因为您标记了这种语言)
[Serializable]
public class YubikeyPool {
[System.Text.Json.Serialization.JsonInclude]
public Guid ID { get; private set; }
public string Name { get; set; }
[System.Text.Json.Serialization.JsonConstructor]
public YubikeyPool() : this(string.Empty) { }
public YubikeyPool(string name) => ID = Guid.NewGuid();
public override string ToString() => Name;
}
You can initialize a class object as you were probably doing.
您可以像之前一样初始化一个类对象。
var yp = new YubikeyPool() { Name = "Some Name" };
The previously auto-generated GUID is preserved when deserializing
在反序列化时,之前自动生成的GUID将被保留
I think the method used for serialization should be changed in:
我认为用于序列化的方法应该进行更改:
public byte[] Serialize<T>(T objData) where T : class {
if (objData is null) return null;
return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(objData, GetJsonSerializerOptions()));
}
VB.NET version:
VB.NET版本:
<Serializable>
Public Class YubikeyPool
Private m_ID As Guid
<JsonInclude>
Public Property ID As Guid
Get
Return m_ID
End Get
Private Set()
m_ID = Value
End Set
End Property
Public Property Name As String
<JsonConstructor>
Public Sub New()
Me.New(String.Empty)
End Sub
Public Sub New(name As String)
Me.Name = name
ID = Guid.NewGuid()
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
Public Function Serialize(Of T As Class)(objData As T) As Byte()
If objData Is Nothing Then Return Nothing
Return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(objData, GetJsonSerializerOptions()))
End Function
以上是您提供的代码部分的翻译。
英文:
You can probably make a little change to your class definition, using an overloaded Constructor and decorating the default Constructor with [JsonConstructorAttribute]
The read-only property (here, the property has a private
setter) can be decorated with a [JsonIncludeAttribute]
. In this case, the non-public setter is used. For example:
(in C#, since you have tagged this language)
Assuming System.Text.Json 7.0.0.3
[Serializable]
public class YubikeyPool {
[System.Text.Json.Serialization.JsonInclude]
public Guid ID { get; private set; }
public string Name { get; set; }
[System.Text.Json.Serialization.JsonConstructor]
public YubikeyPool() : this(string.Empty) { }
public YubikeyPool(string name) => ID = Guid.NewGuid();
public override string ToString() => Name;
}
You can initialize a class object as you were probably doing.
var yp = new YubikeyPool() { Name = "Some Name" };
The previously auto-generated GUID is preserved when deserializing
I think the method used for serialization should be changed in:
public byte[] Serialize<T>(T objData) where T : class {
if (objData is null) return null;
return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(objData, GetJsonSerializerOptions()));
}
VB.NET version:
<Serializable>
Public Class YubikeyPool
Private m_ID As Guid
<JsonInclude>
Public Property ID As Guid
Get
Return m_ID
End Get
Private Set()
m_ID = Value
End Set
End Property
Public Property Name As String
<JsonConstructor>
Public Sub New()
Me.New(String.Empty)
End Sub
Public Sub New(name As String)
Me.Name = name
ID = Guid.NewGuid()
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
Public Function Serialize(Of T As Class)(objData As T) As Byte()
If objData Is Nothing Then Return Nothing
Return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(objData, GetJsonSerializerOptions()))
End Function
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论