2011-07-06 20 views
5

ASP.NET MVC 3を使用していて、View Modelの大部分が読み取り専用である複数のページがあります。例えば、フィールドは、このようなようなものだ:ASP.NET MVC 3 - ビュー内のモデルを処理するためのベストプラクティス

<div class="display-label">My Field</div> 
<div class="display-field">@Model.MyField</div> 

私は、ユーザーがそのようないくつかの検証テキストで入力しなければならない分野があります:ユーザーがフォームを送信すると、それは私に当たると

@Html.LabelFor(model => model.Verification) 
@Html.PasswordFor(model => model.Verification) 

をコントローラの場合、ViewModelのフィールドは検証フィールドを除くすべてnullです。

@Html.HiddenFor(model => model.MyField) 

しかし、これは本当に速い醜い取得します。私はこの問題を回避得ている方法は、これまで、そのようなようないくつかのHiddenForフィールドを持つことです。ビューの状態でモデルを処理するためのより良い方法があるので、フォーム提出のPOST中に、私はすべてのフィールドを取得できますか?これは、POST中に検証テキストが一致しない場合に重要で、ビューモデルをデータベースから再取得せずに返す必要があります。

ありがとうございます。

答えて

3

データベースから値を再取得する必要はありません。その理由は、MVCのモデルバインディングは、アクションのモデルにMyFieldをバインドするGETまたはPOSTパラメータのみを調べ、GET/POSTパラメータにMyFieldの値がない場合は、そのプロパティをnullとして保持する必要があるためです値が何であるべきかを知っていますか?)

MyFieldの値をG30/GET/POSTパラメータに渡すことは、モデルのバインダーが表示するためには、明示的にビューのフォームに値をHtml.HiddenFor()で渡します。ビューがpost/getパラメータでそのプロパティを送信することを自動的に知る方法はありません。

は、しかし、あなたが見ることができます 1つのアイデアは、フィールド名と式(x => x.MyField)を取りレイザー(またはHTML)ヘルパーメソッドを作成することで、あなたのために、次の出力を書き込みます。

<div class="display-label">My Field</div> 
<div class="display-field">@Model.MyField</div> 
@Html.HiddenFor(model => model.MyField) 

これは、あなただけの1行のコード(代わりに、これらの3行の@Html.ShowReadOnlyField(x => x.MyField, "My Field")のようなものを書かなければならないことしかし、これはまた、どこでも、あなたがこれをしたいが、同じdivの構造を持っていることを前提とし

編集:。。強行読み取り専用フィールドに関するセキュリティ上の懸念を覚えておいてください。これらは読み取り専用ではないためです。このデータをコントローラ内のすべてのものに使用する場合は、データベースからこのデータを再取得する方が良いです。これは、HTML形式でのみ読み込まれていても、ユーザーはPOST/GETデータを操作することによって、この値を任意の値に設定できるためです。

+0

あなたはHtml.AntiForgeryToken() '@'ヘルパーを使用して、セキュリティ上の問題を回避することはできますか? – Brandon

+1

私はそれを疑う。私はAntiForgeryTokenの機能についてあまり知らないが、ほとんどの場合、ユーザーはページのソースを見て、それが動作するために必要なトークンを確認することができます。偽造トークンは、クロスサイトスクリプティング攻撃のためのものであり、価値の保護のためのものではありません。今では、フィールドが提供されるべきかどうかを知る方法があります。セキュアであることが必要なものはサーバー側で処理する必要があり、セキュリティのためにクライアント側の機能に頼ることはできません – KallDrexx

+0

コントローラでオブジェクトインスタンスを再ロードするだけです。 – Brandon

0

ページでモデルをシリアル化してから投稿してください。これは問題を解決すべきです。

<%= Html.Serialize("User",Model) %> 

[HttpPost] 
public ActionResult Register([DeserializeAttribute] User user, FormCollection userForm) 
{ 

} 
+0

こんにちはViewState! –