如何使用 MVC 验证来显示警告消息而不需要填写字段?

How do I use MVC Validation to display a warning message without making the field required?

我有一个 asp.net MVC 网站,用户可以在其中输入社会保险号 (SSN)。如果 SSN 已被使用,客户希望显示一条警告消息,但不想强制他们更改 SSN(在某些情况下,多个记录可以具有相同的 SSN)。

我继承的 MVC 代码有一个验证来检查 SSN 是否已经被使用。该代码效果很好。如果用户输入的 SSN 已被使用,则会显示一条消息 "SSN already exists" 并阻止提交表单。我怎样才能更改此设置以显示消息,但不会阻止提交表单?

ModelApplication.cs

    [StringLength(9, MinimumLength = 9, ErrorMessage = "Please Enter 9 Digit SSN No")]
    [Remote("IsSSNExist", "Admin", HttpMethod = "GET")]
    public string ApplicantSSN { get; set; }

AdminController.cs

    [HttpGet]
    public JsonResult IsSSNExist(string ApplicantSSN)
    {
        if (Session["viewapp"] == null)
        {
            if (obj_BllApp.IsSSNExist(ApplicantSSN))
                return Json("SSN already exists.", JsonRequestBehavior.AllowGet);
            else
                return Json(true, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json(true, JsonRequestBehavior.AllowGet);
        }
    }

Application.cshtml

<label>
SSN
</label>
@Html.TextBoxFor(m => m.ApplicantSSN, new { @class = "input-small", @maxlength = "9", @onkeypress = "return ValidateNumberKeyPress(this, event);" })<br />
@Html.HiddenFor(m => m.ApplicantSSNID, new { id = "hdnApplicantSSN" })
span id="spAppSSn" class="SSNmsg">@Html.ValidationMessageFor(m => m.ApplicantSSN)</span>

更新

我也试过使用响应 header 就像另一位发帖人建议的那样,但我无法让它工作。

这段代码没有 return 任何东西并且破坏了其他 javascript 我有:

    $(function () {
    $("#txtApplicantSSN").change(function (xhr) {
        alert("Hello");
        var req = new XMLHttpRequest();
        req.open('GET', document.location, false);
        req.send(null);
        var headers = req.getResponseHeader("SSN-DUPLICATED").toLowerCase();
        alert(headers);
        alert("Goodbye");
    });
});

使用相同的概念,我尝试了另一种获取请求的方法 header,但我从未得到值。看起来设置 header 值的验证是在 javascript.

之后调用的
    $(function () {
    $("#txtApplicantSSN").change(function () {
        var req = new XMLHttpRequest();
        req.open('GET', document.location, false);
        req.send(null);
        var headers = req.getResponseHeader('SSN-DUPLICATED');
        $("#remoteMessage").text(headers);
    });
});

我尝试使用 session 变量进行类似的操作,但 session 变量似乎在 javascript 代码之后设置。

    $(function () {
    $("#txtApplicantSSN").change(function () {
        var someSessionVariable = '@Request.RequestContext.HttpContext.Session["SSNExists"]';
        alert(someSessionVariable);
        $("#remoteMessage").text(someSessionVariable);
    });
});

我目前的想法是尝试在单击提交按钮时禁用验证,但我还没有找到实现它的方法。我试过这个

HtmlHelper.ClientValidationEnabled = false;

在控制器中,但它从未命中服务器端代码。我在到达控制器之前收到验证错误。

更新#2

我在使用取消单击提交按钮时禁用了验证 class:

<input id="Submit1" type="submit" class="btn btn-primary cancel" value="Save" onclick="javascript: return ValidatonCoApplication();" />

这解决了该字段的问题,但禁用了所有其他字段的验证。有人可以建议另一种方法在不关闭验证的情况下做我想做的事吗?

总而言之,这是 asp.net 带 Razor 的 MVC。用户在文本框中输入 SSN 后,我需要在屏幕上显示一条消息,说明 SSN 是否有效。目前我在模型中有一个验证属性,但这不仅显示消息,它还声明模型无效,因此不允许用户继续到下一页。我希望验证消息出现,但不希望模型无效。如果您能给我任何帮助,我将不胜感激。谢谢。

您可以将验证放在响应 header 中,然后使用 jQuery 显示它,如下所示

[HttpGet]
public JsonResult IsSSNExist(string ApplicantSSN)
{
    if (Session["viewapp"] == null)
    {
        if (obj_BllApp.IsSSNExist(ApplicantSSN)){
            Response.AddHeader("SSN-DUPLICATED", "SSN already exists. ");
            return Json(true, JsonRequestBehavior.AllowGet);
        }
        else
            return Json(true, JsonRequestBehavior.AllowGet);
    }
    else
    {
        return Json(true, JsonRequestBehavior.AllowGet);
    }
}

并添加一个 span 来显示远程消息,并且一些 jQuery 在您的视图中如下所示

<label>
     SSN
</label>
@Html.TextBoxFor(m => m.ApplicantSSN, 
      new { @class = "input-small",  @maxlength = "9", @onkeypress = "return ValidateNumberKeyPress(this, event);" })
<br />
@Html.HiddenFor(m => m.ApplicantSSNID, new { id = "hdnApplicantSSN" })

 <span id="spAppSSn" class="SSNmsg">
     @Html.ValidationMessageFor(m =>m.ApplicantSSN)</span>

 <span id="remoteMessage" class="SSNmsg">
      @Html.ValidationMessageFor(m =>m.ApplicantSSN)</span>


$(function () {
    $('#ApplicantSSNID').rules()
        .remote.complete = function (xhr) {
        var responseMessage=xhr.getResponseHeader('SSN-DUPLICATED');
        if (xhr.status == 200 && xhr.responseText === 'true') {
        jQuery('#remoteMessage')[0].innerHTML = 
              (responseMessage||'');
       }
    };
});

注意:请不要在 MVC 中使用 Session。这不是一个好习惯。

你不能真的按照你想要的方式做你想做的事。验证将通过或失败!您需要做的是删除 [Remote] 验证属性并在您提交表单的操作中进行检查。如果 SSN 存在,那么您必须在完成表格处理后传递此消息。

或者使用javascript和Ajax在SSN文本框失去焦点时检查SSN,然后可以在用户提交表单之前显示警告

因为你只想根据 ApplicantSSN 的值显示消息(不使模型无效),删除 [Remote] 属性,而是处理 .change() 事件调用控制器方法的文本框和 return 适当的消息。

控制器

public JsonResult IsSSNExist(string ApplicantSSN)
{
  bool isValid = // your logic
  if (isValid)
  {
    return Json(null, JsonRequestBehavior.AllowGet);
  }
  else
  {
    return Json(true, JsonRequestBehavior.AllowGet);
  }
}

查看

@Html.TextBoxFor(m => m.ApplicantSSN) // remove the onkeypress attribute
// add a placeholder for the message
<span class="field-validation-error"><span id="ssn-message">The SSN already exists.</span></span>

css

#ssn-message {
  display: none;
}

脚本

var url = '@Url.Action("IsSSNExist")';
var ssnMessage = $('#ssn-message');
$('#ApplicantSSN').change(function() {
  $.getJSON(url, { ApplicantSSN: $(this).val() }, function(response) {
    if(response) {
      ssnMessage.show();
    } else {
      ssnMessage.hide();
    }
  });
});

注意:如果用户输入了无效值并跳出控件,将显示该消息。如果用户再次开始在文本框中输入,您可能需要额外的逻辑来隐藏消息,在这种情况下,您还需要处理 keyup 事件