web-dev-qa-db-ja.com

asp.net c#MVC:ViewStateなしで生活するにはどうすればよいですか?

私はちょうどWebFormsをMVCに変換することを検討しています:

.net MVCでは、ViewStateを不要にする概念は何ですか?

フォームが自分自身などにポストバックされた場合(ポストバックなど)ページ/ユーザーコントロールはどのように状態を維持しますか?

セッションの状態に頼らずに、ある種の状態を維持するために人々が行っているトリックは何ですか?

確かに、完全にステートレスな環境は存在できませんか?

52
Mark Redman

しかし、もちろんできます。実際、Web isステートレスです。それどころか、考えは異常です。

MVCではWebコントロールがなくなりました。サーバー側で発生するイベントはありません。これは、URLとPOSTデータの2つの異なるメカニズムによって置き換えられます。これらを適切に使用すると、ViewStateが不要になります。

従来のASP.NET Webアプリケーションでは、機能Xを実行するLinkBut​​tonをWebページに配置します。ASP.NETは、ユーザーがボタンをクリックしたときに多くのViewState cruft、javascriptおよびその他のものをWebページに貼り付けます。 ASP.NETは、Webサイトに「ポストバック」して(存在することを誰も知らないフォームを送信することにより)、発生した内容を再構築し、特定のボタンイベントハンドラーを実行する必要があると判断します。

MVCでは、特定のルートにアクセスするためのリンクを作成します。ルートは、ユーザーが何をしたいのかを説明します-/ Users/Delinquent/Index(すべての非行ユーザーのリストを表示します)。 MVCのルーティングシステムは、このルートを処理するコントローラーと、そのコントローラーで実行するメソッドを決定します。追加の情報は、URLクエリ文字列値(非行の5ページ目は?Page = 5)によってコントローラーメソッドに送信できます。

URLに加えて、HTMLフォームを使用してPOSTより複雑な情報(フォームのデータなど)またはファイルなどのクエリ文字列に収まらないものを戻すことができます。 。

したがって、クエリ文字列とPOST values。)の形式で状態を「維持」します。実際には、最終的に維持する状態はそれほど多くないことがわかります。多くの状態を維持することは、デザインが欠けていること、またはWebサイトモデルに適合しない何かをしようとしていることを示す良い兆候です。

79
Will

viewstateは、大きくて見苦しい隠しフォームフィールドです。

独自の非表示フォームフィールドを書き出し、必要に応じて暗号化します。

幸いなことに、大量のデータをページにダンプする簡単な方法はないため、保存する内容について慎重に判断する必要があります。

9

フォームがそれ自体にポストバックされる場合(ポストバックなど)ページ/ユーザーコントロールはどのように状態を維持しますか?セッションの状態に頼らずに、ある種の状態を維持するために人々が行っているトリックは何ですか?

ポストされたViewData(またはページにバインドされた厳密に型指定されたオブジェクト)は、再びビューにプッシュできます。 このページの「検証とビジネスルールロジックとモデルクラスの統合」を参照してください。 フォームの投稿方法を示します。検証し、エラーが発生した場合はフォームにフィールドを返します。

.net MVCでは、ViewStateを不要にする概念は何ですか?

Representational State Transfer(REST)。

4
Robert Harvey

ASP.NET MVCは状態を使用しないという回答はすべて正しいです。しかし、ASP.NET MVCは実際には何らかの状態を使用しますが、ViewStateのような機能はありません。

通常、誰かがアプリケーションにデータをPOSTするとき、データが検証され、データが有効でない場合はエラーが表示されます。ただし、エラーメッセージを含むページをすぐに返す場合、ユーザーがF5キーを押してページをリロードすると、データが再送信されます。これは通常、あなたが望むものではありません。したがって、POSTされたデータが有効ではないことに気付いた場合、ユーザーにページ(または別のページ)をGETしてエラーメッセージを表示するように指示する必要があります。そのためには、HTTPリダイレクトステータスコードを返します。しかし、ユーザーのGETリクエストが届いたら、どのエラーメッセージを表示するかをどのように知るのでしょうか? (サーバー)がPOSTを処理しているときからGETを処理するまで、何らかの形でこれを覚えておく必要があります。

これを行うには、TempDataと呼ばれるASP.NET MVC機能を使用します。これは実際にはSessionの単なるラッパーであり、TempDataディクショナリに押し込んだものはすべて、次のリクエストまでそこにとどまり、それ以上は存在しません。

3
Rune

MVCにはWebFormsよりもいくつかの利点がありますが、いくつかの欠点もあります。詳細は この回答 で説明しました。あなたが自問しなければならない基本的な質問は、ViewStateがあなたのために問題であるかどうかであると思います-そしてそれはあなたがあなたを書き直さなければならないような問題ですか?応用?そうでない場合、MVCの学習は価値のある目標ですが(実際には非常にクールです)、ビジネスのリスクを冒すものではありません。

そうは言っても、驚くほど多くの場合、ViewStateを実際に無効にすることができます。主にポストバックを通じてコン​​トロールの価値を維持するために使用されます。したがって、たとえば、値をサーバー側で確認する必要があるテキストボックスと他の多くのフィールドがある場合、ViewStateを使用すると、ポストバックを処理し、エラーをキャッチ(およびラベルを表示)してから、すべてのエントリをそのままにして、ユーザーをフォームに戻します。ただし、フォームがonlyに記入されてポストバックされ、別のページにリダイレクトされる場合は、安全に無効にすることができます。

最後に、セッション状態を回避するために人々が何をしているのかを尋ねます。セッション状態を回避する理由はありますか?確かにそこに多くの情報は必要ありませんが、それを完全に回避することは本当に必要ではなく、実際、あなたの武器庫で最も強力なツールの1つに費用がかかります。

3

WebプログラミングのRESTの動きは、プログラムの状態がbadであるという考えに基づいているという事実を考慮してください。ウィキペディアには、適切な説明と参照があります: http://en.wikipedia.org/wiki/Representational_State_Transfer

従来のASP.NETとそれが提供する豊富なイベントモデルから生まれたMVCは、非常に不快なものになる可能性があります。 does以前は見えなかったものを管理する必要がありますが、テスト容易性の観点から価値があると思います(RESTページは作成せずに簡単にトリガーできます)複雑なビューステートであり、定義によりサーバーが状態を保持していないため、ページ/機能を個別にテストできます)学習曲線を相殺します。

ASP.NETおよびRESTでのMVCの説明: http://blog.wekeroad.com/2007/12/06/aspnet-mvc-using-restful-architecture/

2
Godeke

状態は、データベースにあるモデルです。データベースを慎重にキャッシュして、ページのロード時間を短縮できます。

0
Tamas Czinege

自動生成されたビューステートはMVCには存在しませんが、非表示フィールドを使用するだけで独自に作成できます。

MVCでは、ページの上部にほとんどの暗号化された文字は表示されませんが、ほとんどの文字は必要ありません。

0
Amr Elgarhy

MVC3Futuresプロジェクト でビューステートを模倣できます。モデル全体をビューに保存します。

あなたがしなければならないのは、モデルをシリアル化し、ビューで暗号化することです。

@Html.Serialize("Transfer", Model, SerializationMode.EncryptedAndSigned)

そして、コントローラーに非シリアル化された属性を追加します。

public ActionResult Transfer(string id,[Deserialize(SerializationMode.EncryptedAndSigned)]Transfer transfer)
0
jan salawa

実際にそうです。永続性がビューステートでどのように構成されたかを忘れる必要があります。

また、「コントローラーを呼び出す」ために、ポストバックをページに変換する必要があります。これにより、後で物事を理解しやすくなります。 pageを呼び出す代わりに、ビューを返すコントローラーを呼び出しています。そのため、呼び出しのたびに「ページ」全体を何度も作成するか、アクションによって実際に影響を受けるものだけに対処することにします。ボタンがdivを変更している場合、ページ全体をリロードする理由。コントローラーを呼び出して、divの新しいデータを返すだけです。

たとえば、マスター/詳細シナリオを想像してみましょう。

<h2>Groups</h2>
    <div id="GroupList">
    </div>
    <div id="GroupDetail" title="Detail Group">
</div>

グループのリストはdivに一度ロードされ、グループのリストの各項目に対してコントローラーに対して可能なajax呼び出しがあります:

<%= Ajax.ActionLink("Edit", "DetailLocalisationGroup", 
                     new { id = group.Id }, 
                     new AjaxOptions() { 
                         UpdateTargetId = "DetailLocalisationGroup", 
                         OnSuccess = "InitialisationDetailGroup" })%>

これは、div GroupDetailにhtmlをフィードするこのアクションDetailLocalisationGroupを呼び出します。

[AcceptVerbs("POST")]
public ActionResult DetailLocalisationGroup(int id)
{
    LocalisationGroup group = servicelocalisation.GetLocalisationGroup(id);
    return View("DetailGroup", group);
}

Divにフォームがあり、このフォームの送信ボタンを押すと、本当に必要な情報をコントローラーに送信し、コントローラーはデータベースにデータを保存します。

これらのすべてのイベントの間、GroupListはクライアント画面に表示されるものでいっぱいになりましたが、そこでは相互作用は必要なかったので、なぜこれらのビューステートで気にしますか...

0
Arthis

これらすべての投稿を読んだ後、MVCはLOBの種類のアプリケーションには向いていないようです。多くのコントロールとCRUD操作があり、コントロールの状態を維持する必要があります。送信操作が完了した後、ユーザーが同じビューの状態を維持することを望む多くの理由があります。たとえば、エラーの表示、サーバー側の検証メッセージ、成功メッセージ、その他のアクションの実行。これらのメッセージを表示するためにユーザーを他のビューにリダイレクトすることは実用的ではありません。

0
LP13

任意のオブジェクトをセッション状態で保存できます。

 HttpContext.Session["userType"] = CurrentUser.GetUserType();
0
fireydude