The situation
I have a LINQ-TO-SQL model with a table that contains three columns. The usual ID (identity, autogenerated), then A of type int and B of type varchar(MAX). All columns are defined in the database as NOT NULL.
On a WebForms-page I declared an DetailsView that binds to the items:
<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>
All this code runs in Visual Studio 2012, on ASP.NET 4.5.
What happens
So far so good. Updating and viewing works. The problem begins when I enter invalid values. Using "" for field A results in a nice error message at the top of the page. Yay! However, when I use "" as value for field B this happens:
public void DetailsView_UpdateItem(int id)
{
var item = db.MyTable.Where(row => row.Id==id).Single();
TryUpdateModel(item);
if (ModelState.IsValid)
db.SubmitChanges();
}
- The UpdateItem method is called
- TryUpdateModel works and fills the form values into item.
- When debugging I can see that item.B is null, as expected
- Then ModelState.IsValid returns true?!?
- The call to db.SubmitChanges() fails with an exception
The problem
I do not understand why ModelState.IsValid would return true when the data model specified that B cannot be null. Can somebody explain? What am I doing wrong?
Workarounds
One thing I tried was adding Data Annotations to the data classes by including the following code. It didn't work.
[MetadataType(typeof(MyTableMetadata))]
public partial class MyTable
{
}
public class MyTableMetadata
{
[Required]
[StringLength(255,MinimumLength=1)]
public string B { get; set; }
}
It's obvious that I could manually check for null in the UpdateItem method or that I could add a RequiredFieldValidator - but I'd prefer not to.