Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在ASP.NET核心MVC中同时验证两个属性_C#_Asp.net Core_Asp.net Core Mvc_Viewmodel_Latitude Longitude - Fatal编程技术网

C# 在ASP.NET核心MVC中同时验证两个属性

C# 在ASP.NET核心MVC中同时验证两个属性,c#,asp.net-core,asp.net-core-mvc,viewmodel,latitude-longitude,C#,Asp.net Core,Asp.net Core Mvc,Viewmodel,Latitude Longitude,我有以下的视图模型 public class MyViewModel { [Required(ErrorMessage = "Location is required")] [Range(SOME_RANDOM_COORDINATE, SOME_RANDOM_COORDINATE, ErrorMessage = "Keep location within map bounds")] public double? Latitude {

我有以下的视图模型

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输入字段(都是隐藏的)。当提交表单时(而不是设置位置),我自然会得到两次“位置是必需的”。如何将这两个要验证的属性组合在一起

观点


@ViewData[“标题”]


您可以尝试使用自定义属性验证坐标对

在您的模型中,我将删除[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;
    }
}
[AttributeUsage(AttributeTargets.Property |
AttributeTargets.Field,AllowMultiple=false)]
公共类CustomCoordinateAttribute:ValidationAttribute
{
私有只读字符串_requiredProperty;
公共CustomCoordinateAttribute(公共双精度?必需值)
{
_requiredProperty=requiredValue;
}
受保护的覆盖验证结果有效(对象值,
ValidationContext(验证上下文)
{
var currentValue=(双)值;
var属性=
validationContext.ObjectType.GetProperty(_requiredProperty);
if(属性==null)
抛出新ArgumentException(“未找到指定的属性名称”);
var otherValue=
(DateTime)属性.GetValue(validationContext.ObjectInstance);
if((currentValue==null)| |(otherValue==null))
{
返回新的ValidationResult(“未定义任何坐标”);
}
如果((currentValue==null)&&(otherValue!=null))
{
返回新的ValidationResult(String.Format(
ErrorMessageString,currentValue));
}
如果((currentValue!=null)&&(otherValue==null))
{
返回新的ValidationResult(String.Format(
ErrorMessageString,其他值);
}
如果((当前值<0)| |(其他值<0))
{
返回新的ValidationResult(“坐标不能为负”);
}
返回ValidationResult.Success;
}
}

您可以在提交表单之前使用ajax进行验证,下面是一个演示:

行动:

public IActionResult Verify(double? Latitude,double? Longitude)
        {
            if (Latitude==null||Longitude==null)
            {
                return Json("Location is required");
            }

            return Json(true);
        }
MyViewModel:

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; }
}
视图:


@ViewData[“标题”]

提交 @节脚本{ @{wait Html.RenderPartialAsync(“_validationScript”);} $(“表格”)。提交(功能(e){ $.ajax({ 键入:“获取”, url:“验证?纬度=”+$(“#纬度”).val()+”&经度=”+$(“#经度”).val(), 成功:功能(数据){ 如果(数据!=“有效”){ $(“#错误”).html(数据); }否则{ $('form').unbind().submit(); } } }) 返回false; }) }
结果:

我是否也应该删除range属性并将其添加到custom属性中?我认为range属性也会限制类的默认值,因此最好将其移动到自定义验证中。
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>
}