在 ASP.NET 核心 MVC 中一次验证两个属性
Validating two attributes at once in ASP.NET Core MVC
我有以下 ViewModel;
public class MyViewModel {
[Required(ErrorMessage = "Location is required")]
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Latitude { get; set; }
[Required(ErrorMessage = "Location is required")]
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Longitude { get; set; }
}
我使用 OpenStreetMap 作为这些纬度和经度值的输入,我想使用 ViewModel 中的属性添加客户端和服务器端验证。我正在创建两个 html 输入字段(均隐藏)。提交表单(而不是设置位置)时,我自然会得到两次“需要位置”。如何将这两个属性组合在一起进行验证?
查看;
<form asp-area="" asp-controller="Report" asp-action="Create" method="post" enctype="multipart/form-data">
<h4>@ViewData["Title"]</h4>
<hr />
<div class="form-group">
<input id="latitude" type="hidden" asp-for="@Model.Latitude" class="form-control" />
<span asp-validation-for="@Model.Latitude" class="text-danger"></span>
</div>
<div class="form-group">
<input id="longitude" type="hidden" asp-for="@Model.Longitude" class="form-control" />
<span asp-validation-for="@Model.Longitude" class="text-danger"></span>
</div>
</form>
您可以尝试使用自定义属性来验证坐标对。
在您的模型中,我将删除 [Required] 属性并将其替换为自定义验证属性。这些值可以设置为模型中的默认值,以便初始视图最初不会抛出错误。然后,您的控制器可以在呈现视图后将坐标覆盖到您想要的任何位置。
public class MyCoordinateModel {
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
[CustomCoordinate("Longitude", ErrorMessage = "{0} field has not been set.")]
public double? Latitude { get; set; }
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
[CustomCoordinate("Latitude", ErrorMessage = "{0} field has not been set.")]
public double? Longitude { get; set; }
MyCoordinateModel()
{
Longitude = 0;
Latitude = 0;
}
}
自定义属性将是这样的,错误消息有条件地显示并自定义到无效的 属性:
[AttributeUsage(AttributeTargets.Property |
AttributeTargets.Field, AllowMultiple = false)]
public class CustomCoordinateAttribute : ValidationAttribute
{
private readonly string _requiredProperty;
public CustomCoordinateAttribute(public double? requiredValue)
{
_requiredProperty = requiredValue;
}
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
var currentValue = (double)value;
var property =
validationContext.ObjectType.GetProperty(_requiredProperty);
if (property == null)
throw new ArgumentException("Specified property name not found");
var otherValue =
(DateTime)property.GetValue(validationContext.ObjectInstance);
if ((currentValue == null) || (otherValue == null))
{
return new ValidationResult("None of the coordinates are defined");
}
if ((currentValue == null) && (otherValue != null))
{
return new ValidationResult(String.Format(
ErrorMessageString, currentValue));
}
if ((currentValue != null) && (otherValue == null))
{
return new ValidationResult(String.Format(
ErrorMessageString, otherValue);
}
if ((currentValue < 0) || (otherValue < 0))
{
return new ValidationResult("Coordinates cannot be negative");
}
return ValidationResult.Success;
}
}
您可以使用ajax在表单提交前进行验证,这里是一个演示:
操作:
public IActionResult Verify(double? Latitude,double? Longitude)
{
if (Latitude==null||Longitude==null)
{
return Json("Location is required");
}
return Json(true);
}
我的视图模型:
public class MyViewModel {
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Latitude { get; set; }
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Longitude { get; set; }
}
查看:
<form asp-area="" asp-controller="Report" asp-action="Create" method="post" enctype="multipart/form-data">
<h4>@ViewData["Title"]</h4>
<hr />
<div class="form-group">
<input id="latitude" hidden asp-for="Latitude" class="form-control" value="1"/>
<span asp-validation-for="Latitude" class="text-danger"></span>
</div>
<div class="form-group">
<input id="longitude" hidden asp-for="Longitude" class="form-control"/>
<span asp-validation-for="Longitude" class="text-danger"></span>
</div>
<div>
<span class="text-danger field-validation-error" id="error"></span>
</div>
<button>submit</button>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
<script>
$("form").submit(function (e) {
$.ajax({
type: "GET",
url: 'Verify?Latitude=' + $("#latitude").val() + '&Longitude=' + $("#longitude").val(),
success: function (data) {
if (data != "valid") {
$("#error").html(data);
} else {
$('form').unbind().submit();
}
}
})
return false;
})
</script>
}
结果:
我有以下 ViewModel;
public class MyViewModel {
[Required(ErrorMessage = "Location is required")]
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Latitude { get; set; }
[Required(ErrorMessage = "Location is required")]
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Longitude { get; set; }
}
我使用 OpenStreetMap 作为这些纬度和经度值的输入,我想使用 ViewModel 中的属性添加客户端和服务器端验证。我正在创建两个 html 输入字段(均隐藏)。提交表单(而不是设置位置)时,我自然会得到两次“需要位置”。如何将这两个属性组合在一起进行验证?
查看;
<form asp-area="" asp-controller="Report" asp-action="Create" method="post" enctype="multipart/form-data">
<h4>@ViewData["Title"]</h4>
<hr />
<div class="form-group">
<input id="latitude" type="hidden" asp-for="@Model.Latitude" class="form-control" />
<span asp-validation-for="@Model.Latitude" class="text-danger"></span>
</div>
<div class="form-group">
<input id="longitude" type="hidden" asp-for="@Model.Longitude" class="form-control" />
<span asp-validation-for="@Model.Longitude" class="text-danger"></span>
</div>
</form>
您可以尝试使用自定义属性来验证坐标对。
在您的模型中,我将删除 [Required] 属性并将其替换为自定义验证属性。这些值可以设置为模型中的默认值,以便初始视图最初不会抛出错误。然后,您的控制器可以在呈现视图后将坐标覆盖到您想要的任何位置。
public class MyCoordinateModel {
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
[CustomCoordinate("Longitude", ErrorMessage = "{0} field has not been set.")]
public double? Latitude { get; set; }
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
[CustomCoordinate("Latitude", ErrorMessage = "{0} field has not been set.")]
public double? Longitude { get; set; }
MyCoordinateModel()
{
Longitude = 0;
Latitude = 0;
}
}
自定义属性将是这样的,错误消息有条件地显示并自定义到无效的 属性:
[AttributeUsage(AttributeTargets.Property |
AttributeTargets.Field, AllowMultiple = false)]
public class CustomCoordinateAttribute : ValidationAttribute
{
private readonly string _requiredProperty;
public CustomCoordinateAttribute(public double? requiredValue)
{
_requiredProperty = requiredValue;
}
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
var currentValue = (double)value;
var property =
validationContext.ObjectType.GetProperty(_requiredProperty);
if (property == null)
throw new ArgumentException("Specified property name not found");
var otherValue =
(DateTime)property.GetValue(validationContext.ObjectInstance);
if ((currentValue == null) || (otherValue == null))
{
return new ValidationResult("None of the coordinates are defined");
}
if ((currentValue == null) && (otherValue != null))
{
return new ValidationResult(String.Format(
ErrorMessageString, currentValue));
}
if ((currentValue != null) && (otherValue == null))
{
return new ValidationResult(String.Format(
ErrorMessageString, otherValue);
}
if ((currentValue < 0) || (otherValue < 0))
{
return new ValidationResult("Coordinates cannot be negative");
}
return ValidationResult.Success;
}
}
您可以使用ajax在表单提交前进行验证,这里是一个演示:
操作:
public IActionResult Verify(double? Latitude,double? Longitude)
{
if (Latitude==null||Longitude==null)
{
return Json("Location is required");
}
return Json(true);
}
我的视图模型:
public class MyViewModel {
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Latitude { get; set; }
[Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")]
public double? Longitude { get; set; }
}
查看:
<form asp-area="" asp-controller="Report" asp-action="Create" method="post" enctype="multipart/form-data">
<h4>@ViewData["Title"]</h4>
<hr />
<div class="form-group">
<input id="latitude" hidden asp-for="Latitude" class="form-control" value="1"/>
<span asp-validation-for="Latitude" class="text-danger"></span>
</div>
<div class="form-group">
<input id="longitude" hidden asp-for="Longitude" class="form-control"/>
<span asp-validation-for="Longitude" class="text-danger"></span>
</div>
<div>
<span class="text-danger field-validation-error" id="error"></span>
</div>
<button>submit</button>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
<script>
$("form").submit(function (e) {
$.ajax({
type: "GET",
url: 'Verify?Latitude=' + $("#latitude").val() + '&Longitude=' + $("#longitude").val(),
success: function (data) {
if (data != "valid") {
$("#error").html(data);
} else {
$('form').unbind().submit();
}
}
})
return false;
})
</script>
}
结果: