问题描述
任务考虑两种形式:
- 操作注册
- 操作确认
因此,第一个表单允许根据数据注释输入具有相应字段验证的数据。同时第二个表单设计为以只读模式显示相同的数据以供最终确认。
还有一个想法是对第一个表单使用模型验证。 假设数据注释用于简单的验证,如字段值长度和字段值内容。同时模型验证将用于更复杂的数据验证。例如,某些操作类型只需要一些额外的数据。否则不需要额外的数据。这个额外的数据可以有自己的验证要求等等。因此验证逻辑可能非常复杂,并且需要有关整个模型的信息。这就是为什么有使用模型验证的想法。
在之前的 question 中提出了如何启用模型验证的建议。
但我注意到了一些意想不到的行为。通过按下第一个表单上的提交按钮来触发验证。运行两种类型的验证(表单字段数据注释和表单验证)。 没事。但验证消息仅基于字段数据注释显示。未显示基于模型验证的验证错误。它们仅在下一个表格中可用。第二种形式(确认)ModelState 包含这些错误。但是我们说已经太晚了。这个想法是在第一个表单上显示这些错误(来自模型验证)。更重要的是,我希望在模型验证错误的情况下不应该发生 post 操作(确认页面调用)。
让我分享没有所有字段的源代码。因为视图和相应的视图模型包含大约 20 个字段。
请在下面找到视图模型的部分
public class DealRegistrationviewmodel : Baseviewmodel
{
[display(Name = "Код (для получения котировок с биржи)")]
[StringLength(10,MinimumLength = 0)]
[RegularExpression(@"^[a-zA-Z]+$",ErrorMessage = "Неверное значение")]
public string Code { get; set; }
[required]
public int SelectedSecuritiesTypeId { get; set; }
[display(Name = "Вид")]
public List<SecuritiesType> SecuritiesTypes { get; set; }
}
请在下方找到相应的部分
<div class="row">
<div class="col-md-4">
<form asp-action="Confirmation">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="SecuritiesTypes" class="control-label"></label>
<br>
<select asp-for="SelectedSecuritiesTypeId" asp-items="@(new SelectList(Model.SecuritiesTypes,"Id","Description"))"></select>
<br>
<span asp-validation-for="SelectedSecuritiesTypeId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Code" class="control-label"></label>
<input asp-for="Code" class="form-control"/>
<span asp-validation-for="Code" class="text-danger"></span>
</div>
请在下面找到 IModelValidator.Validate 方法的实现
public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context)
{
var model = context.Container as WAVM.DealRegistrationviewmodel;
if (model == null)
{
throw new ArgumentNullException("Container is null");
}
if (context.ModelMetadata.Name.Equals(nameof(model.Code)) == false
&& context.ModelMetadata.Name.Equals(nameof(model.SelectedSecuritiesTypeId)) == false)
{
return Enumerable.Empty<ModelValidationResult>();
}
BLI.SecuritiesType type = _securitiesService.GetItemAsync(model.SelectedSecuritiesTypeId).GetAwaiter().GetResult();
if (type == null)
{
return new List<ModelValidationResult>
{
new ModelValidationResult("",$"Не найден тип ценной бумаги по коду ({model.SelectedSecuritiesTypeId})")
};
}
if (type.IsRateRequestAllowed == true && string.IsNullOrEmpty(model.Code) == true)
{
if (context.ModelMetadata.Name == nameof(model.Code))
{
return new List<ModelValidationResult>
{
new ModelValidationResult("","Пустое значение поля Код не допустимо")
};
}
if (context.ModelMetadata.Name == nameof(model.SelectedSecuritiesTypeId))
{
return new List<ModelValidationResult>
{
new ModelValidationResult("","Выбранный тип ценной бумаги требует значения для поля Код")
};
}
}
if (type.IsRateRequestAllowed == false && string.IsNullOrEmpty(model.Code) == false)
{
if (context.ModelMetadata.Name == nameof(model.Code))
{
return new List<ModelValidationResult>
{
new ModelValidationResult("","Значение поля Код должно быть пустым")
};
}
if (context.ModelMetadata.Name == nameof(model.SelectedSecuritiesTypeId))
{
return new List<ModelValidationResult>
{
new ModelValidationResult("","Выбранный тип ценной бумаги не допускает значения для поля Код")
};
}
}
return Enumerable.Empty<ModelValidationResult>();
}
执行正确地在每个“返回新列表”的断点处停止
请在下面找到 IModelValidatorProvider.CreateValidators 方法的实现
public void CreateValidators(ModelValidatorProviderContext context)
{
if (context.Results.Any(v => v.Validator.GetType() == typeof(DealRegistrationviewmodelValidator)) == true)
{
return;
}
if (context.ModelMetadata.ContainerType == typeof(DealRegistrationviewmodel)
&& ( context.ModelMetadata.Name == nameof(DealRegistrationviewmodel.Code)
|| context.ModelMetadata.Name == nameof(DealRegistrationviewmodel.SelectedSecuritiesTypeId)) )
{
context.Results.Add(new ValidatorItem
{
Validator = new DealRegistrationviewmodelValidator(_securitiesService),IsReusable = true
});
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)