状況
3 つの列を含むテーブルを持つ LINQ-TO-SQL モデルがあります。通常のID (ID、自動生成)、次にint型の Aとvarchar(MAX)型のB。データベースでは、すべての列が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>
このコードはすべて、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();
}
- UpdateItem メソッドが呼び出されます
- TryUpdateModel が機能し、フォームの値をitemに入力します。
- デバッグすると、予想どおりitem.Bがnullであることがわかります
- その後、ModelState.IsValidはtrueを返します?!?
- db.SubmitChanges()の呼び出しが例外で失敗する
問題
データ モデルでBをnullにできないと指定したときに、 ModelState.IsValidがtrueを返す理由がわかりません。誰か説明できますか?私は何を間違っていますか?
回避策
私が試したことの 1 つは、次のコードを含めて、データ クラスにデータ注釈を追加することでした。うまくいきませんでした。
[MetadataType(typeof(MyTableMetadata))]
public partial class MyTable
{
}
public class MyTableMetadata
{
[Required]
[StringLength(255,MinimumLength=1)]
public string B { get; set; }
}
UpdateItemメソッドで手動でnullをチェックしたり、RequiredFieldValidator を追加したりできることは明らかですが、私はそうしたくないでしょう。