ModelState.IsValid返回true,即使必需的字符串为null

Sim*_*mon 6 asp.net webforms model-binding linq-to-sql

情况

我有一个LINQ-TO-SQL模型,其中包含一个包含三列的表.通常的ID(身份,自动生成的),然后类型的INT型的VARCHAR(MAX) .所有列都在数据库中定义为NOT NULL.

WebForms页面上,我声明了一个绑定到项目的DetailsView:

<asp:ValidationSummary runat="server" ShowModelStateErrors="true" />
<asp:DetailsView DataKeyNames="Id" runat="server" ItemType="test.MyTable"
    SelectMethod="..." UpdateMethod="...">
      <Fields>
        <asp:DynamicField DataField="A" />
        <asp:TemplateField>
            <EditItemTemplate>
                <asp:TextBox ID="B" runat="server" TextMode="MultiLine" Columns="80" Rows="8" Text="<%# BindItem.B %>" />
            </EditItemTemplate>
            <ItemTemplate>
                <pre><asp:Label runat="server" Text="<%# Item.B %>"  /></pre>
            </ItemTemplate>
        </asp:TemplateField>
      </Fields>
</asp:DetailsView>
Run Code Online (Sandbox Code Playgroud)

所有这些代码都在ASP.NET 4.5上的Visual Studio 2012中运行.

怎么了

到现在为止还挺好.更新和查看作品.当我输入无效值时,问题就开始了.对字段A使用"" 会在页面顶部显示一条漂亮的错误消息.好极了!但是,当我使用""作为字段B的值时会发生这种情况:

    public void DetailsView_UpdateItem(int id)
    {
      var item = db.MyTable.Where(row => row.Id==id).Single();
      TryUpdateModel(item);
      if (ModelState.IsValid)
        db.SubmitChanges();
    }
Run Code Online (Sandbox Code Playgroud)
  1. 调用UpdateItem方法
  2. TryUpdateModel可以将表单值填充到项目中.
  3. 调试时,我可以看到item.Bnull,正如预期的那样
  4. 然后ModelState.IsValid返回true?!?
  5. db.SubmitChanges()的调用失败并出现异常

问题

我不明白为什么当数据模型指定B不能为null时,ModelState.IsValid将返回true.有人可以解释一下吗?我究竟做错了什么?

解决方法

我尝试过的一件事是通过包含以下代码将Data Annotations添加到数据类.它没用.

  [MetadataType(typeof(MyTableMetadata))]
  public partial class MyTable
  {
  }

  public class MyTableMetadata
  {
    [Required]
    [StringLength(255,MinimumLength=1)]
    public string B { get; set; }
  }
Run Code Online (Sandbox Code Playgroud)

很明显,我可以在UpdateItem方法中手动检查null,或者我可以添加RequiredFieldValidator - 但我不想这样做.

Art*_*dod 1

只是一些任意的建议:确保您引用的是 System.ComponentModel.DataAnnotations 3.5。(不是 3.6)或其他一些正确的命名空间(据我所知,有一些仅适用于 WCF RIA 服务)。尝试 [DisplayFormat(ConvertEmptyStringToNull = ... )] 的不同设置确保您正在执行 POST 请求 =)