我有一个包含Password
字段的部分,我希望在数据库中对其进行加密。我使用Orchard.Email作为灵感来做到这一点,但我使用ComputedField
遇到了问题。
编辑部件时,ComputedField
应该负责加密。我编写了一个处理程序,它应该为Getter
设置Setter
和ComputedField
委托,但是当到达驱动程序更新模型时,这些委托是NULL,所以我得到一个NullReferenceException。但是,当我检索部件时,代理设置正确。
我的代码:
public class TaskServerPart : ContentPart<TaskServerPartRecord>
{
private readonly ComputedField<string> _password = new ComputedField<string>();
public ComputedField<string> PasswordField
{
get { return _password; }
}
public string Name
{
get { return Record.Name; }
set { Record.Name = value; }
}
public string Domain
{
get { return Record.Domain; }
set { Record.Domain = value; }
}
public string Username
{
get { return Record.Username; }
set { Record.Username = value; }
}
public string Password
{
get { return _password.Value; }
set { _password.Value = value; }
}
}
public class TaskServerPartRecord : ContentPartRecord
{
public virtual string Name { get; set; }
public virtual string Domain { get; set; }
public virtual string Username { get; set; }
public virtual string Password { get; set; }
}
public class TaskServerPartHandler : ContentHandler
{
private readonly IEncryptionService _encryptionService;
public TaskServerPartHandler(IRepository<TaskServerPartRecord> repository, IEncryptionService encryptionService)
{
_encryptionService = encryptionService;
Logger = NullLogger.Instance;
Filters.Add(new ActivatingFilter<TaskServerPart>("Site"));
Filters.Add(StorageFilter.For(repository));
OnLoaded<TaskServerPart>(LoadHandlers);
}
void LoadHandlers(LoadContentContext context, TaskServerPart part)
{
part.PasswordField.Getter(() =>
{
try
{
return String.IsNullOrWhiteSpace(part.Record.Password) ? String.Empty : Encoding.UTF8.GetString(_encryptionService.Decode(Convert.FromBase64String(part.Record.Password)));
}
catch
{
Logger.Error("The task server password could not be decrypted. It might be corrupted, try to reset it.");
return null;
}
});
part.PasswordField.Setter(value => part.Record.Password = String.IsNullOrWhiteSpace(value) ? String.Empty : Convert.ToBase64String(_encryptionService.Encode(Encoding.UTF8.GetBytes(value))));
}
}
public class TaskServerDriver : ContentPartDriver<TaskServerPart>
{
protected override string Prefix { get { return "TaskServer"; } }
//GET
protected override DriverResult Editor(
TaskServerPart part, dynamic shapeHelper)
{
return ContentShape("Parts_TaskServer_Edit",
() => shapeHelper.EditorTemplate(
TemplateName: "Parts/TaskServer",
Model: part,
Prefix: Prefix))
;
}
//POST
protected override DriverResult Editor(
TaskServerPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape("Parts_TaskServer_Edit", () => {
var previousPassword = part.Password; // This fails, because the ComputedField has no Getter or Setter delegates
updater.TryUpdateModel(part, Prefix, null, null);
// restore password if the input is empty, meaning it has not been changed
if (String.IsNullOrEmpty(part.Password)) {
part.Password = previousPassword;
}
return shapeHelper.EditorTemplate(TemplateName: "Parts/TaskServer", Model: part, Prefix: Prefix);
});
}
}
我在处理程序上设置了一个断点,以查看它何时被调用。
我为我的部分添加了额外的属性(但不是部分记录)。如果我在断点到达处理程序时设置了这个属性的值,那么当我到达驱动程序时,该值就不存在了,所以我处理的是与我设置ComputedField&#39的部分对象不同的部分对象。 ; s委托,虽然底层记录对象是相同的。使用&#34;创建对象ID&#34;,我发现基本相同的事情:我正在处理三个TaskServerPart实例。第二个实例是我的驱动程序要处理的实例,它是处理程序未执行的唯一实例。
对于最终在驱动程序中的对象,Initialized
和Activated
事件是,如果我使用其中一个而不是{{1}事件?
答案 0 :(得分:0)
未针对发送给驱动程序的对象触发Loaded
事件。 Initialized
事件发生了,因此我使用该事件来设置Getter
的{{1}}和Setter
代表。