これは、Asp.Net MVC 2でスタイルの作成アクションを使用してエンティティを作成しようとすると発生します。
POCOには次のプロパティがあります。
public int Id {get;set;}
[Required]
public string Message {get; set}
エンティティの作成時に、IDは自動的に設定されるため、作成アクションではIDは不要です。
ModelStateには「Idフィールドは必須です」とありますが、そのように設定していません。ここで自動で何かが行われていますか?
編集-明らかになった理由
この問題の理由は、ブラッド・ウィルソンがポール・スペランザを介して、以下のコメントのいずれかで回答しています(ポール、歓声)。
IDの値を提供しているのに、自分が自分だとは知りませんでした。デフォルトルートのルートデータ( "{controller}/{action}/{id}")にあり、デフォルト値は空の文字列であり、intには無効です。 IDを除外するには、アクションパラメーターの[バインド]属性を使用します。デフォルトのルートは次のとおりです。new{controller = "Customer"、action = "Edit"、id = ""} //パラメーターのデフォルト
編集-モデルテクニックの更新
TryUpdateModelとそれに関連付けられたexcludeパラメータ配列を使用して、実際にこれを行う方法を実際に変更しました。
[HttpPost]
public ActionResult Add(Venue collection)
{
Venue venue = new Venue();
if (TryUpdateModel(venue, null, null, new[] { "Id" }))
{
_service.Add(venue);
return RedirectToAction("Index", "Manage");
}
return View(collection);
}
次の属性を追加できます。
[Bind(Exclude = "Id")]
クラスではなくメソッドのパラメーターで、作成時にそれを除外することができ、編集時には引き続き必須です:
public ActionResult Create([Bind(Exclude = "Id")] User u)
{
// will exclude for create
}
public ActionResult Edit(User u)
{
// will require for edit
}
「オブジェクト」をリストに動的に追加するフォームでこの問題に遭遇しました。したがって、ユーザーは追加、削除、または更新できました。新しいアイテムが作成された場合を除き、すべて正常に機能しました。このため、私の場合、Idプロパティを除くオプションではありませんでした。 解決策はIDをNullableにすることでした:
public int? Id { get; set; }
この方法では、既存のアイテムには値があり、新しいアイテムには代わりにnullがあります。いい物。
すばらしい質問と回答は、私の...を助けました。ただし、何かを追加する必要があります。
の代わりに
[Bind(Exclude = "Id")]
使用したほうがいいと思う
[Bind(Include = "Prop1, Prop2, Prop3, etc")]
..ここで、Prop1、Prop2、およびProp3は、アクションレベルでバインドされる唯一のプロパティです。
これはブラックリストとは対照的にホワイトリストであるためです。ホワイトリストはより安全で安全です。これにより、過剰な投稿や過少な投稿のリスクも解決できます。 Brad Wilsonの投稿 を参照してください。
Idはクライアントから0として送信される必要があります。モデルにはId = 0の問題はありません。これはintのデフォルトです。問題は、クライアントからの値が表示されないか、スペースまたはnullが含まれていることです。 Id(または複雑なオブジェクトNestedPropertyId/NestedProperty.Id)を表す入力が非表示になっているため、値がゼロで始まることを確認します。
<input type="hidden" id="id" value="0" />
<input type="hidden" id="eventId" value="0"/>
<input type="hidden" id="contactId" value="0"/>
また、クライアント側でフォームを追加して新規エンティティを追加するときに、非表示をゼロで初期化するようにします。
これが楽になることを願っています。
エフィ
[Bind(Exclude = "Id")]
public class Hebe
{
public int Id {get;set;}
[Required]
public string Message {get; set}
}
上記の方法では、作成時にモデルのIDプロパティをバインドしません
ビューを確認してください。 idフィールドにhiddenfieldがある場合は削除します。これは編集のみに使用されます。 @ Html.HiddenFor(Model => Model.Id)
POCOでRC2を使用すると、同じ問題が発生します。プロパティIDに名前を付けたが、それに検証属性を付けないが、IsValidはそれが必須であると言う場合プロパティにId以外の名前を付けると、これは起こりません。 IDを除外する必要があるのはなぜですか?
ありがとう
追加しますか? intへ
[Key]
[HiddenInput(DisplayValue = false)]
public int? ID { get; set; }
新しいMVC2プロジェクトを作成し、シンプルなPOCOとコントローラーおよびビューを追加しました。私が理解していることから、あなたはモデルバインディングを使用してオブジェクトを作成している、つまり
using System.ComponentModel.DataAnnotations;
public class SimpleObject
{
public int Id {get;set;}
[Required]
public string Message { get; set; }
}
コントローラーには
[HttpPost]
public ActionResult Create(SimpleObject created)
{
/// do something
}
そして、ビューでは、IDフィールド用のエディタはありませんか?
これにより、エラーメッセージが表示されることはありません。代わりに、IDは0であるdefault(int)に設定されることになっています。これは私にとってはうまくいきます。どのバージョンのMVC2を使用していますか(私が想定するRC)?
誤解しないでください。IDがモデルバインダーにバインドされないようにすることが重要です。攻撃者がオブジェクトのIdを改ざんする可能性があるためです。それにもかかわらず、デフォルトのモデルバインダーは、説明した動作を示すべきではありません。
私の場合、問題はIDがstring
型であるという事実から生じていました。 int
(null不可)に変更すると、修正されました。 string
タイプは、設計が不適切なデータベースをリバースエンジニアリングした結果です。
私もあなたと同じ問題に直面し、今私はすでにこれを解決しました。 HttpGetでは、View will emptyモデルを返す必要があります。といった
[HttpGet]
public ActionResult Add()
{
//Your code here
return View(new Venue);
}
それがあなたの役に立つことを願っています。
上記の答えは正しいです。一人一人が異なるシナリオをたどる方法。私の解決策は、同じ問題に対して次のとおりです。 IDが主キーである場合、それを開始する必要があります。つまり、getメソッドで表示するモデルを渡すときは、その前に新しいオブジェクトを作成するだけです。 IDにnullではなく0を設定します。
私は同じ問題を抱えていましたが、モデルに3つの整数フィールドがありました。誤って必要な整数プロパティをすべてnull可能intに設定することで、それを回避することができました。
この暗黙的な検証を無効にするには、 AddImplicitRequiredAttributeForValueTypes
オプションを DataAnnotationsModelValidatorProvider
に設定して、Application_Start
に以下を追加します。
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
さらに読む:
私は同じ問題を抱えていましたが、CreateメソッドのGET呼び出し中に、ビューモデルの空のインスタンスをビューに渡すだけで解決できました。
//GET: DocumentTypes/{Controller}/Create
public ActionResult Create()
{
return View(new DocumentTypeViewModel());
}
//POST: DocumentTypes/{Controller}/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(DocumentTypeViewModel viewModel)
{
if(ModelState.IsValid) {
var result = AddDocumentType(viewModel);
if(!result.HasValidationErrors) {
return RedirectToAction("Index");
}
ModelState.Update(result);
}
return View(viewModel);
}
そして、私の見解では、私が持っていることを確認します
@Html.HiddenFor(m => m.ID)
このように、バインド属性を明示的に指定する必要はありません