简体   繁体   English

如何实现异步 ValidationAttribute.IsValid()

[英]How can I implement an async ValidationAttribute.IsValid()

I have a use case where, when the user enters an email in a form, I need to verify it's unique.我有一个用例,当用户在表单中输入 email 时,我需要验证它是唯一的。 This is for registering as a new user and every user email in our app must be unique.这是为了注册为新用户,我们应用程序中的每个用户 email 都必须是唯一的。

The call to do this takes time as it's hitting a database.执行此操作的调用需要时间,因为它正在访问数据库。 Therefore I'd like it to be async.因此我希望它是异步的。 So would the following work and how do I accomplish the below problematic steps.以下工作也是如此,我如何完成以下有问题的步骤。

What if I use CustomValidation instead of ValidationAttribute.如果我使用CustomValidation而不是 ValidationAttribute 会怎样? This works great for synchronous complex validation.这对于同步复杂验证非常有效。 But making it async...但是让它异步......

<EditForm EditContext="_editContext" OnValidSubmit="HandleValidSubmitAsync" OnInvalidSubmit="HandleInvalidSubmitAsync" Context="EditFormContext">
    <DataAnnotationsValidator />
    <CustomValidation @ref="_customValidation" />

When it is called for validation it kicks off a background Task and returns an error of "checking email..."当调用它进行验证时,它会启动后台任务并返回错误“正在检查 email...”

Now here's where I don't know exactly what to do.现在我不知道该怎么做。 When the task completes:任务完成时:

  1. How do I update the CustomValidation object, either saying the email is valid or updating the message to now say the email is a duplicate?我如何更新 CustomValidation object,要么说 email 有效,要么将消息更新为现在说 email 是重复的?
  2. If I can simply update _customValidation.ClearErrors()/DisplayErrors(), can I call it in the thread the task completes in?如果我可以简单地更新 _customValidation.ClearErrors()/DisplayErrors(),我可以在任务完成的线程中调用它吗? Or do I need to do something similar to WinForms where I invoke a method that will be called in the main/UI thread?或者我是否需要执行类似于 WinForms 的操作,在其中调用将在主/UI 线程中调用的方法?
  3. How do I then tell the form that the CustomValidation object has changed, possibly now allowing a submit?然后我如何告诉表单 CustomValidation object 已经更改,现在可能允许提交?

If all I can do when the task completes is update an object and then force the form to re-validate the email, I can make that work.如果任务完成后我所能做的就是更新 object,然后强制表单重新验证 email,我可以完成这项工作。 But in that case I still have #3 above, how do I make that happen?但在那种情况下,我仍然有上面的#3,我该如何实现呢?

You can implement custom validation like this:您可以像这样实现自定义验证:


EditContext editContext;
ValidationMessageStore messageStore;

protected override void OnInitialized()
{
    editContext = new(yourModel);
    messageStore = new(editContext);

    editContext.OnValidationRequested += Validate;
}

void Validate(object sender, ValidationRequestedEventArgs args)
{
    messageStore.Clear();

    if (yourModel.RequiredObject == null)
        messageStore.Add(() => yourModel.RequiredObject, "This object is required!");

    editContext.NotifyValidationStateChanged();
}

Then in your method used for data submission you can call editContext.Validate() , which returns a bool based on whether validation succeeded or not, or use the editContext object in your EditForm component.然后在您用于数据提交的方法中,您可以调用editContext.Validate() ,它会根据验证是否成功返回一个bool ,或者在您的EditForm组件中使用editContext object 。

There are of course ways, but you need to ditch EditContext for validation.当然有很多方法,但是您需要放弃EditContext进行验证。

The Validation process is synchronous.验证过程是同步的。 It's based on standard events.它基于标准事件。

"Submitting" the form calls Validate on the EditContext which looks like this: “提交”表单调用EditContext上的Validate ,如下所示:

    public bool Validate()
    {
        OnValidationRequested?.Invoke(this, ValidationRequestedEventArgs.Empty);
        return !GetValidationMessages().Any();
    }

This invokes OnValidationRequested and then checks for validation messages.这会调用OnValidationRequested ,然后检查验证消息。 This is the standard "fire and forget" event process.这是标准的“即发即弃”事件流程。 It doesn't await any of the handlers, so will always complete before any yielding handler completes, and potentially provide the wrong result.它不等待任何处理程序,因此总是会在任何让步处理程序完成之前完成,并可能提供错误的结果。

You need to write your own validation if you want async behaviour.如果您想要异步行为,则需要编写自己的验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Blazor webassembly:如何将自定义类型参数传递给自定义 ValidationAttribute - Blazor webassembly: How to pass a custom type parameter to a custom ValidationAttribute 在 Blazor 服务器端应用程序中调用 StateHasChanged() 异步会影响所有打开的浏览器,我该如何阻止它? - calling StateHasChanged() async in Blazor Server-Side application effects all open browsers, how can I stop this? 如何在 xaf blazor .net 6 应用程序中实现 state 转换的状态栏 - How can I implement status bar for state transition in xaf blazor .net 6 application 如何停止异步调用之前的Syncronous方法 - How do I stop a Syncronous method racing ahead of an async Call 链接标签在 Blazor 页面中不起作用,如何在 blazor 中实现 asp 调用? - Link tag not working in Blazor page, how do I implement asp call in blazor? 如何在 Blazor 中实现路由器动画? - How to implement router animation in Blazor? 如何在 Blazor 中正确创建异步方法? - How to correctly create an async method in Blazor? 如何在 Blazor 中访问浏览器 localStorage? - How can I access the browsers localStorage in Blazor? "如何在 Blazor 中有新行" - How can I have New Line in Blazor 如何更新 Blazor 视图? - How can I update the Blazor View?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM