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

使用AdditionalFields远程验证时,创建商品无法触发Controller问题求助

问题分析

你遇到的问题核心在于:当给Remote验证添加AdditionalFields="Id"后,ASP.NET MVC的Unobtrusive Remote验证默认会同时监听指定字段(Code和Id)的变化,只有当其中任意一个字段的值改变时才会触发验证请求。

在创建商品场景中,Id是隐藏字段,初始值为0且不会被用户修改,所以当你输入Code时,验证框架认为只有Code变化了,但因为依赖了Id字段且Id没有变化,导致验证请求根本没被触发。而编辑场景下,Id是已有商品的非0值,页面加载时Id值已存在,修改Code时框架会同时发送Code和Id的值,所以验证能正常工作。

解决方案

这里提供几种实用的解决方法,你可以根据自己的项目场景选择:

方法1:手动配置前端Remote验证规则

绕过框架的默认行为,手动为Code字段添加验证规则,确保每次输入Code时都主动获取Id值并发送请求。

在视图页面的末尾添加以下脚本:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script>
        $(document).ready(function () {
            // 重新配置Code字段的Remote验证规则
            $('#Code').rules('add', {
                remote: {
                    url: '@Url.Action("IsCodeAvailable", "Product")',
                    type: 'GET',
                    data: {
                        // 每次验证时主动获取Id字段的当前值
                        Id: function () {
                            return $('#Id').val();
                        }
                    }
                },
                messages: {
                    remote: 'Product Code already taken'
                }
            });
        });
    </script>
}

这样无论Id字段的值是否变化,只要Code内容修改,就会触发验证请求并携带当前Id值。

方法2:修改后端方法参数为可空类型

把后端验证方法的Id参数改为int?(可空整数),这样即使前端没传递Id值也能正常进入方法,再调整判断逻辑:

[HttpGet]
public JsonResult IsCodeAvailable(string code, int? Id)
{
    try
    {
        var flag = true;
        // 判断是否为创建操作:Id为null或0
        if (!Id.HasValue || Id.Value == 0) 
        {
            flag = !db.Product.Any(x => x.Code == code);
        }
        else 
        {
            flag = !db.Product.Any(x => x.Code == code && x.Id != Id.Value);
        }
        return Json(flag, JsonRequestBehavior.AllowGet);
    }
    catch (Exception ex)
    {
        return Json(false, JsonRequestBehavior.AllowGet);
    }
}

同时修改模型的Remote属性,去掉AdditionalFields:

[Remote("IsCodeAvailable", "Product", HttpMethod = "GET", ErrorMessage = "Product Code already taken")]
public string Code { get; set; }

这种方法让后端自行判断场景,无需依赖前端传递额外字段的变化触发验证。

方法3:拆分ViewModel分离场景

为创建和编辑操作分别定义ViewModel,避免在同一个模型中混合两种场景的验证规则:

创建用ViewModel

public class CreateProductViewModel
{
    [Remote("IsCodeAvailableForCreate", "Product", HttpMethod = "GET", ErrorMessage = "Product Code already taken")]
    public string Code { get; set; }
    public string Name { get; set; }
}

编辑用ViewModel

public class EditProductViewModel
{
    public int Id { get; set; }
    [Remote("IsCodeAvailableForEdit", "Product", AdditionalFields = "Id", HttpMethod = "GET", ErrorMessage = "Product Code already taken")]
    public string Code { get; set; }
    public string Name { get; set; }
}

然后在控制器中实现两个独立的验证方法:

[HttpGet]
public JsonResult IsCodeAvailableForCreate(string code)
{
    try
    {
        var flag = !db.Product.Any(x => x.Code == code);
        return Json(flag, JsonRequestBehavior.AllowGet);
    }
    catch (Exception ex)
    {
        return Json(false, JsonRequestBehavior.AllowGet);
    }
}

[HttpGet]
public JsonResult IsCodeAvailableForEdit(string code, int Id)
{
    try
    {
        var flag = !db.Product.Any(x => x.Code == code && x.Id != Id);
        return Json(flag, JsonRequestBehavior.AllowGet);
    }
    catch (Exception ex)
    {
        return Json(false, JsonRequestBehavior.AllowGet);
    }
}

这种方法的优势是职责分离,每个ViewModel只处理对应场景,避免验证规则冲突。

验证测试

无论选择哪种方法,测试时都可以打开浏览器开发者工具(F12),切换到Network标签页,输入Code后观察是否有向IsCodeAvailable的GET请求发送,以此确认验证是否正常触发。

内容的提问来源于stack exchange,提问作者Iftekhar Rasul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:02:00