2012-01-12 16 views
1

空のasp.net mvc 3アプリケーションを作成できます。 コードはHtml.BeginFormの奇妙な動作

namespace MvcApplication1.Controllers 
{ 
public class MyModel 
{ 
    public int Id { get; set; } 
} 

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return Index1(new MyModel() {Id = 100}); 
    } 
    public ActionResult Index1(MyModel model) 
    { 
     var nm = new MyModel(); 
     nm.Id = model.Id + 1; 
     return View("test", nm); 
    } 
} 

テストと呼ばれる共有ビューを作成することができますです。ビューのコードは、我々はすべてOKですフォームを初めて投稿するとき

@using MvcApplication1.Controllers 
@model MyModel 

@if (Model != null) 
{ 
    using (Html.BeginForm("Index1", "Home", FormMethod.Post, new { autocomplete = "off" })) 
    { 
    <div id="compareQuestions"> 
     <p>@Model.Id</p> 
     @Html.HiddenFor(m => m.Id) 
     @Html.TextBoxFor(m => m.Id) 
     <input type="submit" value="save"/> 
    </div> 
    } 
} 

ですが、それは間違ったテキストボックスに最初のポスト値の後にリロードするとき。この値を変更してコントローラーにポストを保存すると、誤った値でモデルが生成されますが、入力されません。これはどのように可能ですか?

+1

は、隠しフィールドの値は101ですか?そうでない場合は、不正確な値は何か、正しい値は何か? – danludwig

+0

eah、間違った値は101 – Ph0en1x

+0

何が '

@ Model.Id

'によってレンダリングされますか? '@ H​​tml.HiddenFor(m => m.Id)'によってレンダリングされるものは? '@ H​​tml.TextBoxFor(m => m.Id)'はどうでしょうか? – danludwig

答えて

2

<p>@Model.Id</p>@Html.HiddenFor(m => m.Id)の間には大きな違いがあります。

フォームをPOSTすると、POSTされたすべての値はModelStateに格納されます。
HtmlHelperメソッドを使用する場合は、最初に値をModelStateから引き出します。 ModelStateに値が含まれていない場合は、実際にはm.Idが表示されます。

フォームを最初に取得すると、ModelStateはありません。しかしフォームをPOSTすると、値はModelStateに格納されるため、非表示の入力ではm.Idの代わりにその値が使用されます。

あなたは常にm.Idを使用したい場合は、あなたのコントローラでModelStateをクリアする必要があります。第2のポストに

public ActionResult Index1(MyModel model) 
{ 
    ModelState.Clear(); 
    ... 
+0

しかし、実際にそのように実装するのはなぜですか? – Ph0en1x

+0

これは検証の仕組みです。入力が無効なフォームを送信すると、ModelStateはその入力を保持するので、フォームを再表示すると、フィールドは空白になりません。例えば、私のモデルが 'int'を必要とし、' abc'とタイプすると、フォームは 'abc'とエラーメッセージで再表示されます。 –

1

アクションメソッドを記述しているので、これは正しい動作です。ビューでは、同じ正確なモデルプロパティのテキストボックスと非表示フィールドの両方をレンダリングしています。

投稿時にIDを1ずつインクリメントすると、テキストボックスと非表示フィールドの値が増えています。

2番目の投稿の後にテキストボックスと非表示フィールドの値が異なるようにするには、モデルに別のプロパティが必要です。

同じ名前の2つの異なる<input要素があるため、フォームが非表示フィールドまたはテキストボックスから値を送信するかどうかはわかりません。これらの2つのフィールドの値が異なる場合は、モデル上で異なるプロパティである必要があります。それらが常に同じ値になるようにするには、TextBoxまたはHiddenをビューに配置しますが、両方ではありません。

+0

いいえ、分かりません質問。もちろん、それは同じ値をレンダリングしますが、値は間違っています。

@ Model.Id

@ Html.HiddenFor(m => m.Id)は異なる値を持っていますが、それらは同じである必要があります – Ph0en1x