【问题标题】:Input validation generating data-* attributes ONLY on Primary key and checkbox type input tags输入验证仅在主键和复选框类型输入标签上生成 data-* 属性
【发布时间】:2017-02-10 16:28:24
【问题描述】:

我创建了一个使用VS2015-Update3 创建的示例ASP.NET MVC Core 1.1 Web 应用程序。它仅在作为主键的模型属性和 bool 类型的属性上生成带有 data -* attributes 的输入标签。例如,在以下示例中,生成的 html(如下所示)仅显示为模型的属性 MyEntityIdProp2 生成的输入标记上的数据属性。 注意:我使用的是默认的 ASP.NET Core Web 应用程序模板,它会自动安装 Jquery、Bootstrap 等。

型号

public class MyEntity
{
    public int MyEntityId { get; set; }

    public string Prop1 { get; set; }

    [Column(TypeName = "char(2)")]
    [RegularExpression(@"^[0-9]{2,2}$", ErrorMessage = "Must enter two digit numbers"), StringLength(2)]
    public string TestCode { get; set; }

    public DateTime? StartDate { get; set; }

    public bool Prop2 { get; set; }
}

查看

<form asp-controller="TestController" asp-action="TestAction" method="post" class="form-horizontal">
    <div asp-validation-summary="All" class="text-danger"></div>
    <div><input type="hidden" asp-for="MyEntityId" /></div>

    <div class="form-group">
        <label asp-for="Prop1" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="Prop1" class="form-control" style="margin-top:15px;" />
            <span asp-validation-for="Prop1" class="text-danger"></span>
        </div>
    </div>
    <div class="form-group">
        <label asp-for="TestCode" class="col-md-2 control-label"></label>
        <div class="col-md-2">
            <input asp-for="TestCode" class="form-control" />
            <span asp-validation-for="TestCode" class="text-danger"></span>
        </div>
    </div>

    <div class="form-group">
        <label asp-for="StartDate" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="StartDate" type="date" class="form-control" />
            <span asp-validation-for="StartDate" class="text-danger"></span>
        </div>
    </div>
    <div class="form-group">
        <label asp-for="Prop2" class="col-md-2 control-label"></label>
        <div class="col-md-1">
            <input asp-for="Prop2" class="form-control" style="zoom:0.5;margin-top:25px;" />
            <span asp-validation-for="Prop2" class="text-danger"></span>
        </div>
    </div>
    <button type="submit" name="submit" value="testVal">Save</button>
</form>

生成的 Html

<div><input type="hidden" data-val="true" data-val-required="The MyEntityId field is required." id="MyEntityId" name="MyEntityId" value="54321"></div>
<div class="form-group">
    <label class="col-md-2 control-label" for="StateName">Prop1</label>
    <div class="col-md-2">
        <input class="form-control" readonly="" type="text" id="Prop1" name="Prop1" value="TestVal">
        <span class="text-danger field-validation-valid" data-valmsg-for="Prop1" data-valmsg-replace="true"></span>
    </div>
</div>
<div class="form-group">
    <label class="col-md-2 control-label" for="TestCode">TestCode</label>
    <div class="col-md-2">
        <input class="form-control" type="text" id="TestCode" name="TestCode" value="">
        <span class="text-danger field-validation-valid" data-valmsg-for="TestCode" data-valmsg-replace="true"></span>
    </div>
</div>
<div class="form-group">
    <label class="col-md-2 control-label" for="StartDate">Start Date</label>
    <div class="col-md-10">
        <input type="date" class="form-control" id="StartDate" name="StartDate" value="2015-10-01">
        <span class="text-danger field-validation-valid" data-valmsg-for="StartDate" data-valmsg-replace="true"></span>
    </div>
</div>
<div class="form-group">
    <label class="col-md-2 control-label" for="Prop2">Test Prop2</label>
    <div class="col-md-1">
        <input class="form-control" data-val="true" data-val-required="Test Prop2 is required." id="Prop2" name="Prop2" style="zoom:0.5;margin-top:25px;" type="checkbox" value="true">
        <span class="text-danger field-validation-valid" data-valmsg-for="Prop2" data-valmsg-replace="true"></span>
    </div>
</div>

【问题讨论】:

  • 根本无法复制,这不是正常行为。我只能假设您必须在某处覆盖了默认行为。我建议一开始,您将&lt;input asp-for="StartDate" type="date" class="form-control" /&gt; 注释掉并替换为@Html.TextBoxFor(m =&gt; m.StartDate) 并发布为此呈现的html(这将有助于缩小问题范围)
  • 请注意,即使可以为空的属性也会生成data-val-* 属性,例如StartDate 你会得到data-val-date="The field StartDate must be a date.
  • @StephenMuecke 你是对的,因为当我仅使用上述示例创建测试应用程序时,我可能会在某处覆盖默认行为。它确实显示了TestCodedata-* 属性。但是,对于 StateDate,它没有显示 data-* 属性:对于标签助手,它显示 &lt;input type="date" class="form-control" id="StartDate" name="StartDate" value=""&gt;,而对于 html 助手,它显示 &lt;input id="StartDate" name="StartDate" type="text" value=""&gt;。原因可能是我使用DateTime 作为可选DateTime?
  • 这没什么区别 - TextBoxFor() 方法将添加 data-val-date="..." 因为该值必须是 null 或有效日期(如果用户输入“xyx”,它将生成验证错误说它必须是一个日期。如果它没有为您添加该属性,那么您在某处有一些代码覆盖了正常行为(例如自定义扩展方法或EditorTemplate
  • @StephenMuecke 嗯。它可能与我的 VS2015 设置有关,因为我创建了一个新的 MVC 核心应用程序,只有上面的示例和 Individual User Authentication 选项。除了它们的内置代码和我上面的示例之外,没有其他任何东西。

标签: asp.net-mvc visual-studio-2015 asp.net-core-mvc asp.net-mvc-validation


【解决方案1】:

我假设您的问题是 TestCode 没有对其进行验证,尽管同时应用了 RegularExpressionStringLength 属性。 MyEntityIdProp2 不可为空,因此需要对它们进行隐式验证,而 Prop1StartDate 可以为空且未应用任何显式验证。因此,这些都没有得到验证。

TestCode 不过很奇怪。我不确定你是否真的会得到data-* 属性,因为正则表达式和字符串长度都可以分别使用HTML 属性patternmaxlength 来满足。 但是,您应该将patternmaxlength 应用于TestCode 的输入,但事实并非如此。

根据docs,您拥有的代码应该可以工作,至少,似乎StringLength 是通过data-val-maxlength 应用的,而不是(或者可能是除了)使用maxlength 属性。要么有一些错误在起作用,要么你的代码库中有其他东西阻止了正确行为的发生。但是,没有更多的代码,这是不可能的。

【讨论】:

  • 感谢您澄清为什么对其中两个属性进行隐式必需验证,以及为什么其他两个可为空的属性没有 data-* 属性。你的假设是正确的。 TestCode 更是一个问题。你知道TesCode实际上允许我在客户端输入abc。只有当 SQL 服务器(如预期)抱怨 char(2) 不能包含三个字符时,它才会在服务器端抱怨。这让我相信它与TestCode 上未生成的 data-* 属性有关
  • 不,即使客户端验证出现问题,modelbinder 仍应在服务器端捕获它。只要您正确检查ModelState.IsValid,您就永远不会保存到数据库,更不用说获得数据库完整性异常了。确认您使用的是正确的类,该类实际上对属性进行了此验证,并且您的代码已完全编译。例如,可能构建失败,而您仍在运行不包含此验证的先前版本。
猜你喜欢
  • 2011-12-10
  • 2013-09-05
  • 2022-11-25
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
相关资源
最近更新 更多