FluentEditForm 说没有数据,尽管输入的数据在那里

问题描述 投票:0回答:1

我的代码如下,是一个流畅的编辑表单。我提交后,它说即使我填写了这些字段仍然需要填写。我的代码有什么问题吗?

@page "/movieform" 
@using Assignment10.Entities
@using System.ComponentModel.DataAnnotations

<h3>MovieForm</h3>

<FluentCard>
    <FluentEditForm FormName="MovieForm" Model="@movie">
        <DataAnnotationsValidator />
        <FluentValidationSummary />
        <FluentGrid>
            <FluentGridItem xs="12">
                <FluentTextField Name="MovieNameField" Id="movieNameField" @bind-Value="movie.MovieName" Label="Name: " Required/>
                <ValidationMessage For="@(() => movie.MovieName)" />
            </FluentGridItem>
            <FluentGridItem xs="12">
                <FluentTextField Name="MoviePublisherField" Id="moviePublisherField" @bind-Value="movie.Publisher" Label="Publisher: " Required/>
                <ValidationMessage For="@(() => movie.Publisher)" />

            </FluentGridItem>
            <FluentGridItem xs="12" >
                <FluentTextField Name="MovieDescriptionField" Id="movieDescriptionField" @bind-Value="movie.MovieDescription" Label="Description: " Required/>
                <ValidationMessage For="@(() => movie.MovieDescription)" />
            </FluentGridItem>
            <FluentGridItem xs="12" >
                <FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent">Submit</FluentButton>
            </FluentGridItem>
        </FluentGrid>
    </FluentEditForm>
</FluentCard>

@code {
    private Movie movie = new Movie(); 

}
razor-pages fluentvalidation
1个回答
0
投票

您使用

<DataAnnotationsValidator />
- 这就是您的验证器未收到数据的原因 - 它尝试将数据传递到 DataAnnotations 基础设施。

在我的项目中我不使用库。相反,我使用

FluentValidationValidator
组件的自定义实现,代码如下所示:

<EditForm Model="Model" OnValidSubmit="OnValidSubmit">
    <FluentValidationValidator TValidator="MyModelValidator" />
    <ValidationSummary />

    // your inputs, with validation messages, like below:
    <ValidationMessage For="@(() => Model.Thought)" />
</EditForm>

@code{
    private EditContext editContext;
    private ValidationMessageStore messageStore;

    protected override void OnInitialized()
    {
        Model = new MyModel();

        editContext = new EditContext(Model);
        messageStore = new(editContext);

        base.OnInitialized();
    }

    private async Task OnValidSubmit()
    {
        // your save logic here
    }
}

以及组件本身(在 stackoverflow 上找到的代码):

public class FluentValidationValidator<TValidator> : ComponentBase where TValidator : IValidator, new()
{
    private readonly static char[] separators = new[] { '.', '[' };
    private TValidator validator;

    [CascadingParameter]
    private EditContext EditContext { get; set; }

    protected override void OnInitialized()
    {
        validator = new TValidator();
        var messages = new ValidationMessageStore(EditContext);

        /* Re-validate when any field changes or when the entire form   requests validation.*/
        EditContext.OnFieldChanged += (sender, eventArgs)
            => ValidateModel((EditContext)sender!, messages, false);

        EditContext.OnValidationRequested += (sender, eventArgs)
            => ValidateModel((EditContext)sender!, messages, true);
    }

    private void ValidateModel(EditContext editContext, ValidationMessageStore messages, bool submit)
    {
        if (submit)
            editContext.Properties["submitted"] = true;

        if (!editContext.Properties.TryGetValue("submitted", out _))
            return;

        var context = new ValidationContext<object>(editContext.Model);
        var validationResult = validator.Validate(context);
        messages.Clear();
        foreach (var error in validationResult.Errors)
        {
            var fieldIdentifier = ToFieldIdentifier(editContext, error.PropertyName);
            messages.Add(fieldIdentifier, error.ErrorMessage);
        }
        editContext.NotifyValidationStateChanged();
    }

    private static FieldIdentifier ToFieldIdentifier(EditContext editContext, string propertyPath)
    {
        var obj = editContext.Model;

        while (true)
        {
            var nextTokenEnd = propertyPath.IndexOfAny(separators);
            if (nextTokenEnd < 0)
            {
                return new FieldIdentifier(obj, propertyPath);
            }

            var nextToken = propertyPath.Substring(0, nextTokenEnd);
            propertyPath = propertyPath.Substring(nextTokenEnd + 1);

            object? newObj;
            if (nextToken.EndsWith("]"))
            {
                nextToken = nextToken.Substring(0, nextToken.Length - 1);
                var prop = obj.GetType().GetProperty("Item");
                var indexerType = prop!.GetIndexParameters()[0].ParameterType;
                var indexerValue = Convert.ChangeType(nextToken, indexerType);
                newObj = prop.GetValue(obj, [indexerValue]);
            }
            else
            {
                var prop = obj.GetType().GetProperty(nextToken);
                if (prop == null)
                {
                    throw new InvalidOperationException($"Could not find property named {nextToken} in object of type {obj.GetType().FullName}.");
                }
                newObj = prop.GetValue(obj);
            }

            if (newObj == null)
            {
                return new FieldIdentifier(obj, nextToken);
            }

            obj = newObj;
        }
    }
}

它对我的几个项目都有效。优点是您可以扩展组件并添加一些自定义逻辑(如果需要)。缺点是你需要在你的项目中支持它。因此,如果您决定不支持,您可以尝试使用此链接中的内容。

希望对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.