将 CodeFirst 的 属性 保存到 EFCore 中的 Base64 字符串,但从 EFCore 读回 X509Certificate2?
Save CodeFirst's property to Base64 string in EFCore but read back X509Certificate2 from EFCore?
ThirdParty
模型包含 属性 Certificate
。它是供源代码使用的 X509Certificate2
数据类型,但 EFCore 不支持它,这意味着我必须将其转换为 Base64 string
以便 EFCore 数据库存储。然后在从 EFCore 数据库读取时将其转换回 X509Certificate2
。
我们如何指示 EFCore 使用任何 属性 映射器自动执行此操作?
public class ThirdParty
{
public Guid ThirdPartyId { get; set; }
public X509Certificate2 Certificate { get; set; }
public string RawData { get; set; }
public DateTime CreatedDate { get; set; }
}
var certificate1 = new X509Certificate();
var thirdParty = new ThirdParty() { Certificate = certificate }
var certificate2 = thirdParty.Certificate;
一种方法是添加一个额外的未映射属性,它将return X509Certificate2
对象创建从数据库中读取的 Base64
string
。
因此 CertificateString
属性 仅用于保存和读取数据上下文,而 Certificate
属性 用于您的其他逻辑。
public class ThirdParty
{
private X509Certificate2 _certificate;
public Guid ThirdPartyId { get; set; }
// to write in data context only - only set it in production code
public string CertificateString
{
get
{
// return the Base64 string - is just pseudo code
return _certificate?.ToString();
}
set
{
_certificate = new X509Certificate2(value);
}
}
// not mapped for data context - to read from data context only - only read fro
public X509Certificate2 Certificate
{
get
{
if (string.IsNullOrWhiteSpace(CertificateString))
{
return default(X509Certificate2);
}
return new X509Certificate2(CertificateString);
}
private set
{
// will be set by CertificateString
}
}
public string RawData { get; set; }
public DateTime CreatedDate { get; set; }
}
要不映射 属性,您可以在 Fluent API.
中使用 [NotMapped]
作为数据注释或 .Ignore(p => p.PropertyName)
我会做这样的事情,如果您在序列化证书时遇到问题,可以查看 Why does Json.NET fail to serialize a X509Certificate2?。
public class Configuration : IEntityTypeConfiguration<ThirdParty>
{
public void Configure(EntityTypeBuilder<ThirdParty> builder)
{
// This Converter will perform the conversion to and from Json to the desired type
builder.Property(e => e.Certificate).HasConversion(
v => JsonConvert.SerializeObject(v, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }),
v => JsonConvert.DeserializeObject<X509Certificate2>(v, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
}
}
ThirdParty
模型包含 属性 Certificate
。它是供源代码使用的 X509Certificate2
数据类型,但 EFCore 不支持它,这意味着我必须将其转换为 Base64 string
以便 EFCore 数据库存储。然后在从 EFCore 数据库读取时将其转换回 X509Certificate2
。
我们如何指示 EFCore 使用任何 属性 映射器自动执行此操作?
public class ThirdParty
{
public Guid ThirdPartyId { get; set; }
public X509Certificate2 Certificate { get; set; }
public string RawData { get; set; }
public DateTime CreatedDate { get; set; }
}
var certificate1 = new X509Certificate();
var thirdParty = new ThirdParty() { Certificate = certificate }
var certificate2 = thirdParty.Certificate;
一种方法是添加一个额外的未映射属性,它将return X509Certificate2
对象创建从数据库中读取的 Base64
string
。
因此 CertificateString
属性 仅用于保存和读取数据上下文,而 Certificate
属性 用于您的其他逻辑。
public class ThirdParty
{
private X509Certificate2 _certificate;
public Guid ThirdPartyId { get; set; }
// to write in data context only - only set it in production code
public string CertificateString
{
get
{
// return the Base64 string - is just pseudo code
return _certificate?.ToString();
}
set
{
_certificate = new X509Certificate2(value);
}
}
// not mapped for data context - to read from data context only - only read fro
public X509Certificate2 Certificate
{
get
{
if (string.IsNullOrWhiteSpace(CertificateString))
{
return default(X509Certificate2);
}
return new X509Certificate2(CertificateString);
}
private set
{
// will be set by CertificateString
}
}
public string RawData { get; set; }
public DateTime CreatedDate { get; set; }
}
要不映射 属性,您可以在 Fluent API.
中使用[NotMapped]
作为数据注释或 .Ignore(p => p.PropertyName)
我会做这样的事情,如果您在序列化证书时遇到问题,可以查看 Why does Json.NET fail to serialize a X509Certificate2?。
public class Configuration : IEntityTypeConfiguration<ThirdParty>
{
public void Configure(EntityTypeBuilder<ThirdParty> builder)
{
// This Converter will perform the conversion to and from Json to the desired type
builder.Property(e => e.Certificate).HasConversion(
v => JsonConvert.SerializeObject(v, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }),
v => JsonConvert.DeserializeObject<X509Certificate2>(v, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
}
}