首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EditContext :如何检查嵌套对象的验证消息

EditContext :如何检查嵌套对象的验证消息
EN

Stack Overflow用户
提问于 2022-05-30 07:31:09
回答 2查看 549关注 0票数 0

我有一个扩展方法来检查特定字段是否有效。

代码语言:javascript
运行
复制
        public static bool IsValid(this EditContext editContext, string fieldName)
        {
            var fieldIdentifier = editContext.Field(fieldName);

            editContext.NotifyFieldChanged(fieldIdentifier);

            var result = !editContext.GetValidationMessages(fieldIdentifier).Any();

            Console.WriteLine($"{fieldName}  : {result}");

            return result;
        }

它对非复杂领域很好,但对复杂领域却不起作用。e.g

我的模型是

代码语言:javascript
运行
复制
    public class RegisterCompanyRequest
    {
        [Required(ErrorMessage = "Company Name is required")]
        [MaxLength(200, ErrorMessage = "Maximum allowed length for company name is 200 characters")]
        public string NameEn { get; set; }

        [ValidateComplexType]
        public List<CompanyLocation> CompanyLocations { get; set; }

        [ValidateComplexType]
        public CompanyAdminInfo CompanyAdminInfo { get; set; } = new CompanyAdminInfo();
    }

    public class CompanyAdminInfo
    {
        [Required(ErrorMessage = "Full name is required")]
        [MaxLength(200, ErrorMessage = "Maximum allowed length for full name is 200 characters")]
        public string FullName { get; set; }
    }

    public class CompanyLocation
    {
        public int Id { get; set; }

        [Required]
        [MaxLength(200, ErrorMessage = "Maximum allowed length for location name is 200 characters")]
        public string Name { get; set; }
    }

如果我通过那个方法NameEn,如果验证失败,它返回false,否则返回true,但是如果我传递它CompanyLocations[0].NameCompanyAdminInfo.FullName,它总是返回true。

如何对模型中的嵌套对象实现相同的功能?

复制:将下面的代码复制到新的blazor项目中。还安装以下包以验证复杂类型( install Microsoft.AspNetCore.Components.DataAnnotations.Validation -Version 3.2.0-rc1.20223.4)

代码语言:javascript
运行
复制
@page "/"
@using System.ComponentModel.DataAnnotations

<p>"Name" : @company.Name <span>@nameValid</span> </p> 
<p>"Admin Name" : @company.Admin.Name <span>@adminNameValid</span> </p>

<EditForm EditContext="editContext">
    <ObjectGraphDataAnnotationsValidator />

    <input type="text" @bind-value="@company.Name"/>

    <input type="text" @bind-value="@company.Admin.Name"/>

    <button @onclick="Validate" type="submit">Validate</button>
</EditForm>


@code
{
    private bool nameValid, adminNameValid;
    private Company company = new Company();

    EditContext editContext { get; set; }

    protected override async Task OnInitializedAsync()
    {
        editContext = new(company);
    }

    private async Task Validate()
    {
        var isValid = IsValid(editContext, "Name");

        nameValid = isValid;

        isValid = IsValid(editContext, "Admin.Name");

        adminNameValid = isValid;
    }

    public bool IsValid(EditContext editContext, string fieldName)
    {
        var fieldIdentifier = editContext.Field(fieldName);

        editContext.NotifyFieldChanged(fieldIdentifier);

        return !editContext.GetValidationMessages(fieldIdentifier).Any();
    }

    public class Company
    {
        [Required]
        public string Name { get; set; }

        [ValidateComplexType] /*(Install-Package Microsoft.AspNetCore.Components.DataAnnotations.Validation -Version 3.2.0-rc1.20223.4)*/
        public Admin Admin { get; set; } = new Admin();
    }

    public class Admin
    {
        [Required]
        public string Name { get; set; }
    }

}
EN

回答 2

Stack Overflow用户

发布于 2022-05-30 20:59:26

我猜你的代码中有两个反模式。

第一个是用手打电话给editContext.NotifyFieldChanged(fieldIdentifier);。让Blazor处理通知。

第二个是提交,在我看来,您应该避免调用submit按钮上的函数。相反,可以在OnValidSubmitOnInvalidSubmit组件级别使用EditForm,或者将函数绑定到editContext.OnValidationStateChanged,如我正在运行的示例中所示。

代码语言:javascript
运行
复制
@page "/"
@using System.ComponentModel.DataAnnotations
@implements IDisposable

<EditForm EditContext="editContext" OnValidSubmit="ValidSubmit">
    
    <ObjectGraphDataAnnotationsValidator />
    
    <InputText type="text" @bind-Value="@company.Name" />
    <ValidationMessage For="@(() => company.Name)" />

    <InputText type="text" @bind-Value="@company.Admin.Name" />
    <ValidationMessage For="@(() => company.Admin.Name)" />
    
    <button type="submit">Validate</button>
    
</EditForm>

<p>"Name" : @company.Name <span>@nameValid</span> </p> 
<p>"Admin Name" : @company.Admin.Name <span>@adminNameValid</span> </p>

@code
{
    private bool? nameValid, adminNameValid;
    private Company company = new Company();

    EditContext editContext { get; set; } = default!;

    protected override void OnInitialized()
    {
        editContext = new(company);
        editContext.OnValidationStateChanged += HandleValidationStateChanged;
    }

    private void HandleValidationStateChanged(object? o, ValidationStateChangedEventArgs args) 
    {
        var name_field = FieldIdentifier.Create( () => company.Name  );
        nameValid = IsValid(editContext, name_field);

        var admin_name_field = FieldIdentifier.Create( () => company.Admin.Name  );
        adminNameValid = IsValid(editContext, admin_name_field);

    }

    private void ValidSubmit()
    {
        nameValid = true;
        adminNameValid = true;
    }

    public bool IsValid(EditContext editContext, FieldIdentifier fieldIdentifier)
        =>
        !editContext.GetValidationMessages(fieldIdentifier).Any();

    public class Company
    {
        [Required]
        [StringLength(3, ErrorMessage = "Identifier too long (3 character limit).")]
        public string Name { get; set; } = default!;

        [ValidateComplexType] /*(Install-Package Microsoft.AspNetCore.Components.DataAnnotations.Validation -Version 3.2.0-rc1.20223.4)*/
        public Admin Admin { get; set; } = new Admin();
    }

    public class Admin
    {
        [Required]
        [StringLength(3, ErrorMessage = "Identifier too long (3 character limit).")]
        public string Name { get; set; } = default!;
    }

    public void Dispose()
    {
        if (editContext is not null)
        {
            editContext.OnValidationStateChanged -= HandleValidationStateChanged;
        }
    }

}
票数 1
EN

Stack Overflow用户

发布于 2022-05-31 05:56:39

创建了一个扩展方法。

代码语言:javascript
运行
复制
    public static class EditContextHelper
    {
        public static bool IsValid(this EditContext editContext, Expression<Func<Object>> field)
        {
            var fieldIdentifier = FieldIdentifier.Create(field);

            editContext.NotifyFieldChanged(fieldIdentifier);

            return !editContext.GetValidationMessages(fieldIdentifier).Any();
        }
    }

用它就像,

代码语言:javascript
运行
复制
var field = model.CompanyLocations[0].Name
var result = EditContext.IsValid(field);

在我的例子中,我使用数组遍历像这样的指定字段。

代码语言:javascript
运行
复制
var isValid = false;
var fieldsToValidate = new Expression<Func<Object>>[]
       {
           () => model.NameEn, () => (model.Address), () => model.Lattitude,
           () => model.Longitude , () => (model.Tel1), () => (model.Tel2), () => (model.Mobile), () => (model.Whatsapp),
           () => (model.Email), () => (model.Url), () => (model.TaxNumber) 
         };

foreach (var field in fieldsToValidate)
   {
       var result = EditContext.IsValid(field);

       if (!result)
       {
          isValid = false;
       }
    //doing something if any of the fields is wrong.
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72430616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档