簡體   English   中英

在 ASP.NET Core MVC 中一次驗證兩個屬性

[英]Validating two attributes at once in ASP.NET Core MVC

我有以下視圖模型;

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>

您可以嘗試使用自定義屬性來驗證坐標對。

在您的 model 中,我將刪除 [Required] 屬性並將其替換為自定義驗證屬性。 這些值可以在 model 中設置為默認值,以便初始視圖最初不會引發錯誤。 然后,您的 controller 可以在渲染視圖后將坐標覆蓋到您想要的任何位置。

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>
}

結果: 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM