ASP .NET MVC在每个字段级别禁用客户端验证


74

我正在使用带有数据注释和jQuery验证插件的ASP .NET MVC 3。

有没有办法标记某个字段(或某些数据注释)仅应在服务器端进行验证?

我有一个带有屏蔽插件的电话号码字段,而正则表达式验证器在用户端发疯了。regex只是一种故障保护(以防万一有人决定破解javascript验证),因此我不需要它在客户端运行。但是我仍然希望其他验证可以在客户端运行。

Answers:


103

我不确定该解决方案是否适用于MVC3。它肯定可以在MVC4上运行:

您可以在呈现字段之前先在Razor视图中禁用客户端验证,然后在呈现字段后重新启用客户端验证。

例:

<div class="editor-field">
    @{ Html.EnableClientValidation(false); }
    @Html.TextBoxFor(m => m.BatchId, new { @class = "k-textbox" })
    @{ Html.EnableClientValidation(true); }
</div>

在这里,我们为BatchId字段禁用客户端验证。

我也为此开发了一个小帮手:

public static class YnnovaHtmlHelper
{
    public static ClientSideValidationDisabler BeginDisableClientSideValidation(this HtmlHelper html)
    {
        return new ClientSideValidationDisabler(html);
    }
}

public class ClientSideValidationDisabler : IDisposable
{
    private HtmlHelper _html;

    public ClientSideValidationDisabler(HtmlHelper html)
    {
        _html = html;
        _html.EnableClientValidation(false);
    }

    public void Dispose()
    {
        _html.EnableClientValidation(true);
        _html = null;
    }
}

您将按以下方式使用它:

<div class="editor-field">
    @using (Html.BeginDisableClientSideValidation()) {
        @Html.TextBoxFor(m => m.BatchId, new { @class = "k-textbox" })
    }
</div>

如果有人有更好的解决方案,请告诉我!

希望对您有所帮助。


2
很好,除了即使开始时它就关闭也可以启用验证。
伊恩·沃伯顿

4
当然可以增强!
Lorenzo Melato 2014年

我发现它在稍微复杂的情况下工作,可以通过找出特定验证提供者添加了哪些数据属性并将其设置为空字符串来删除该字段具有多个验证器的单个验证。到目前为止,一切正常。感谢您的建议。
stephenbayer 2015年

由于页面在源中加载的文本较少,因此这是一个非常好的解决方案。由于不必要的验证文本,因此显着缩短了加载时间。
劳埃德

92

您可以通过添加data-val='false'属性来关闭单个字段的客户端非侵入式验证:

@Html.TextBoxFor(m => m.BatchId, new { data_val = "false" })

data-val='true'由于任何System.ComponentModel.DataAnnotations属性,这将覆盖MVC添加的属性。HTML元素仍将使用其他验证属性(例如data-val-required)修饰,但不会起作用。

注意下划线data_val上方。MVC自动转换下划线来匿名类型属性连字符,所以data_val成为data-val呈现HTML时)


除非我下划线,否则IIS会给我一个例外。编译器错误消息:CS0746:无效的匿名类型成员声明符。必须使用成员分配,简单名称或成员访问来声明匿名类型成员。
csharpforevermore 2014年

2
这就像一个魅力,并且是我发现的这个问题的最干净的解决方案。
约翰·萨利

3
这很好用,是最干净的解决方案。谢谢!
Patrick

3
该@data_val不MVC 5.渲染“数据-VAL”
Soppus

它的工作方式如下:@ Html.EditorFor(model => model.Phone2,new {htmlAttributes = new {data_val_number =“必须为数字”}})
xeshu

19

MVC5使用jquery.validate

http://jqueryvalidation.org/rules/

如果要在MVC5客户端中删除验证,则需要执行以下操作:

删除所有关于“ myinput”的验证

$("#myinput").rules("remove");

具体验证

$("#myinput").rules("remove", "min max" );

列出验证可以帮助

$("#myinput").rules();

然后,您将需要更正“代码隐藏”以手动验证模型或以其他方式进行验证,因为ModelState.IsValid它将为假。使用ModelState.Clear()TryValidateModel然后可以很方便。

编辑:

禁用控件也会删除验证。

$("#myinput").attr('disabled', disabledValue);


4

为了在给定场景中实现此目标,我们需要进行两次调整。

客户端

要禁用客户端验证,我们需要强制禁用它。

@Html.EditorFor(model => model.Password, new { htmlAttributes = new {  @data_val = "false" , @class = "form-control"} })

请注意@ data_val =“ false”。它将禁用此字段上的验证。

服务器端(实际)

在后操作中验证模型后,由于未提供密码,因此ModelState.IsValid将始终返回false。在这里,我们必须提供模型的当前密码并重新验证模型。

var userObj = db.Users_Info.Where(a => a.Id == users_Info.Id).FirstOrDefault();
if (String.IsNullOrEmpty(users_Info.Password))
{
  users_Info.Password = userObj.Password;
}
ModelState.Clear();
TryValidateModel(users_Info);

让我解释一下,首先,我们检索保存在数据库中的当前信息,如果没有提供密码,则稍后将其用于分配给当前模型。最后两行实际上是重置ModelState以返回有关ModelState.IsValid的更新结果。


1

我遇到了data_val =“ true”的麻烦。我的模型中有一系列单选按钮绑定到单个属性。仅当我将data_val =“ true”应用于第一个@ Html.RadioButtonFor调用时,数据验证才起作用。

在调试时,我发现您还可以使用data_rule_ ??在客户端禁用或更改个别规则。这些规则可以在jquery验证文档中找到

例如;

@Html.RadioButtonFor(m => m.Answer, "Yes", new { data_rule_Required = "false" });
@Html.TextBoxFor(m => m.Answer, new { data_rule_minlength = "10" }

0

如果要在MVC5客户端中删除验证,则需要执行以下操作:

$("#Email").rules("remove", {
                        "required",
                        "minlength",
                        "email"                           
                        }
                    });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.