You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Razor ASP.NET Core中实现条件必填属性的客户端验证

解决方案

一、修复下拉框提交后丢失选中值问题

下拉框值丢失的核心原因是OnPostAsync方法中重新生成SelectList时没有指定选中值,ASP.NET Core渲染下拉框时会默认选中空选项。

修复步骤:

  1. 修改OnPostAsync中所有SelectList的初始化逻辑,增加第四个参数传入当前提交的选中值:
if (!ModelState.IsValid)
{
    // 所有SelectList构造方法末尾增加选中值参数
    ViewData["EntityID"] = new SelectList(_context.Entity.Where(a => a.Active == "Y").OrderBy(a => a.Name), "ID", "Name", SecurityLog.EntityID);
    ViewData["ShiftRangeID"] = new SelectList(_context.ShiftRange.Where(a => a.Active == "Y").OrderBy(a => a.Name), "ID", "Name", SecurityLog.ShiftRangeID);
    ViewData["LocationID"] = new SelectList(_context.Location.Where(a => a.Active == "Y" && a.EntityID == SecurityLog.EntityID).OrderBy(a => a.Name), "ID", "Name", SecurityLog.LocationID);
    ViewData["EventTypeID"] = new SelectList(_context.EventType.Where(a => a.Active == "Y").OrderBy(a => a.Name), "ID", "Name", SecurityLog.EventTypeID);  
    return Page();
}
  1. 级联下拉框(Location)补充回发后自动选中逻辑,在页面底部加如下JS:
$(function(){
    // 页面加载时如果Entity已经有值,自动加载对应Location并选中
    var entityId = $('#entity').val();
    if(entityId){
        $.getJSON('?handler=Locations&entity=' + entityId, function(data){
            var locationSelect = $('#location');
            locationSelect.empty();
            locationSelect.append('<option value="">--Select Location--</option>');
            $.each(data, function(index, item){
                locationSelect.append($('<option></option>').attr('value', item.value).text(item.text));
            });
            // 设置之前选中的Location值
            locationSelect.val('@Model.SecurityLog.LocationID');
        });
    }
});

二、实现RequiredIf属性的客户端验证

第一步:修改自定义验证属性,实现客户端验证适配

让RequiredIfAttribute继承IClientModelValidator接口,生成客户端验证需要的data-*属性:

public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
    public string PropertyName { get; set; }
    public object Value { get; set; }

    public RequiredIfAttribute(string propertyName, object value, string errorMessage = "")
    {
        PropertyName = propertyName;
        ErrorMessage = errorMessage;
        Value = value;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var instance = validationContext.ObjectInstance;
        var type = instance.GetType();
        var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
        if (proprtyvalue?.ToString() == Value.ToString() && value == null)
        {
            return new ValidationResult(ErrorMessage);
        }
        return ValidationResult.Success;
    }

    // 新增客户端验证适配方法
    public void AddValidation(ClientModelValidationContext context)
    {
        MergeAttribute(context.Attributes, "data-val", "true");
        MergeAttribute(context.Attributes, "data-val-requiredif", ErrorMessage);
        MergeAttribute(context.Attributes, "data-val-requiredif-property", PropertyName);
        MergeAttribute(context.Attributes, "data-val-requiredif-value", Value.ToString());
    }

    private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
    {
        if (attributes.ContainsKey(key))
        {
            return false;
        }
        attributes.Add(key, value);
        return true;
    }
}

第二步:页面增加AppType隐藏域

在Security Log创建页的表单内增加隐藏域,让客户端能获取到AppType的值:

<input type="hidden" asp-for="SecurityLog.AppType" value="Security Log" />

第三步:添加客户端验证逻辑

确保页面已经引用了jquery.validate.js和jquery.validate.unobtrusive.js,然后添加如下JS代码:

// 新增requiredif验证规则
$.validator.addMethod("requiredif", function (value, element, parameters) {
    var targetProperty = $('[name="' + parameters.dependentProperty + '"]');
    var targetValue = parameters.targetValue;
    // 如果依赖属性的值等于目标值,则当前字段必填
    if (targetProperty.val() == targetValue) {
        return $.trim(value) != '';
    }
    return true;
});

// 适配unobtrusive验证
$.validator.unobtrusive.adapters.add("requiredif", ["property", "value"], function (options) {
    options.rules["requiredif"] = {
        dependentProperty: options.params.property,
        targetValue: options.params.value
    };
    options.messages["requiredif"] = options.message;
});

内容的提问来源于stack exchange,提问作者Rob C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 16:15:02