我的代码如下,是一个流畅的编辑表单。我提交后,它说即使我填写了这些字段仍然需要填写。我的代码有什么问题吗?
@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();
}
您使用
<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;
}
}
}
它对我的几个项目都有效。优点是您可以扩展组件并添加一些自定义逻辑(如果需要)。缺点是你需要在你的项目中支持它。因此,如果您决定不支持,您可以尝试使用此链接中的内容。
希望对您有帮助。