web-dev-qa-db-ja.com

MVC Razor非表示の入力と値の受け渡し

私はここで何か間違ったことをしていると確信しています。過去2か月間、MVCとRazorを使用してWebアプリを開発してきましたが、フォーム要素を使用することは考えていませんでした。マスターページとサブページでは既に多くのことが行われているため、フォーム要素を使用するためにほとんどのコードを再構築し、ページ上に複数のフォーム要素を作成することになります。

それはさておき、Asp.Netで、C#コードの背後にあるコントロールにアクセスする場合は、ID = "SomeID"とRUNAT = "SERVER"を指定するだけです。次に、コードビハインドでその値とプロパティを設定できます。

Razorでこれを行う場合、次のような行を使用します。

 <input id="hiddenPostBack" runat="server" type="hidden" />

コントローラーでこれにアクセスできないのはなぜですか?ポストバックを検出し、ページが初めて読み込まれる場合は値をfalseに設定し、そうでない場合は値をtrueに設定します。次に、これに基づいて、サーバー側またはクライアント側のいずれかで読み取り、何かを行います。

私の本当の質問は、フォーム要素がない場合、サーバー側とクライアント側の両方で「何か」を行うにはどうすればよいかということです。クライアントからサーバーに値をやり取りしたい場合、これを行う最も簡単な方法は非表示の入力を使用することであるという印象を受けました。しかし、MVC3とかみそりでこれを達成する方法がわかりません。

よろしくお願いします。

18
Francis Rodgers

WebFormsからMVCへの移行には、ロジックとブレインプロセスの完全な変更が必要です。サーバー側とクライアント側の両方で「フォーム」と対話しなくなりました(実際、クライアント側と対話していなかったWebFormsでさえも)。 WebFormsとRUNAT="SERVER"を使用して、Webページのbuildingと対話するだけであるという点で、あなたはおそらく少し考えを混同しているでしょう。

MVCは、モデル(ユーザーが表示するものを作成するために必要なデータ)を作成するサーバー側コードを持っているという点で多少似ていますが、HTMLを作成したら、サーバーとユーザーの間のリンクを理解する必要がありますもはや存在しない。 HTMLのページがあります、それだけです。

したがって、作成しているHTMLは読み取り専用です。モデルをRazorページに渡すと、そのモデルに適したHTMLが作成されます。

これが最初のビューであるかどうかに応じてtrueまたはfalseを設定する非表示要素が必要な場合、モデルにブール値が必要であり、フォローアップに応答する場合はアクションでTrueに設定します。これは、リクエストが[HttpGet]か[HttpPost]かによって異なるアクションを実行することで実行できます(フォームの設定に適している場合:最初の訪問に対するGETリクエストとPOSTリクエストフォームを送信する場合)。

あるいは、モデルは作成時にTrueに設定できます(ページに初めてアクセスする場合)が、after値をTrueまたはFalseとしてチェックします(boolはデフォルトでFalseに設定されるためインスタンス化されます)。次に使用:

@Html.HiddenFor(x => x.HiddenPostBack)

フォームに、非表示のTrueを配置します。フォームがサーバーにポストバックされると、モデルの値はTrueに設定されます。

あなたの質問はwhyに関して具体的ではないので、それ以上のアドバイスをするのは難しいです。 Steve SandersonのPro ASP.NET MVCなど、WebFormsからMVCへの移行に関する優れた本を読むことはおそらく重要です。

36
Steve Owen

Razorを使用している場合、フィールドに直接アクセスすることはできませんが、その値を管理することはできます。

アイデアは、最初のMicrosoftのアプローチが開発者をWeb開発から遠ざけ、デスクトッププログラマーが(たとえば)Webアプリケーションを簡単に作成できるようにすることです。

一方、Web開発者は、ASP.NETのこのトリッキーな奇妙な方法を理解していませんでした。

実際、この非表示の入力はクライアント側でレンダリングされ、ASPはアクセスできません(アクセスできませんでした)。しかし、やがてその素晴らしい方法が表示され、依存する可能性がありますWeb開発は、デスクトップまたはモバイルとは異なります。

モデルは論理ユニットであり、非表示フィールド(およびビューページ全体)はデータの単なる代表的なビューです。したがって、アプリケーションまたはドメインロジックに専念することができ、ビューは単に消費者に提供するだけです。つまり、ビューに詳細なアクセスおよび「ブレインストーミング」機能は必要ありません。

コントローラは実際に、非表示または一般的なセットアップを管理するために必要な作業を行います。モデルは特定の論理ユニットのプロパティと機能を提供し、ビューは単にエンドユーザーにそれをレンダリングするだけです。 [〜#〜] mvc [〜#〜] の詳細をご覧ください。

モデル

public class MyClassModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string MyPropertyForHidden { get; set; }
}

これはコントローラーのアクションです

public ActionResult MyPageView()
{
    MyClassModel model = new MyClassModel(); // Single entity, strongly-typed
    // IList model = new List<MyClassModel>(); // or List, strongly-typed
    // ViewBag.MyHiddenInputValue = "Something to pass"; // ...or using ViewBag

    return View(model);
}

ビューは以下です

//This will make a Model property of the View to be of MyClassModel
@model MyNamespace.Models.MyClassModel // strongly-typed view
// @model IList<MyNamespace.Models.MyClassModel> // list, strongly-typed view

// ... Some Other Code ...

@using(Html.BeginForm()) // Creates <form>
{
    // Renders hidden field for your model property (strongly-typed)
    // The field rendered to server your model property (Address, Phone, etc.)
    Html.HiddenFor(model => Model.MyPropertyForHidden); 

    // For list you may use foreach on Model
    // foreach(var item in Model) or foreach(MyClassModel item in Model)
}

// ... Some Other Code ...

ViewBagを使用したビュー:

// ... Some Other Code ...

@using(Html.BeginForm()) // Creates <form>
{
    Html.Hidden(
        "HiddenName",
        ViewBag.MyHiddenInputValue,
        new { @class = "hiddencss", maxlength = 255 /*, etc... */ }
    );
}

// ... Some Other Code ...

Html Helperを使用してHiddenフィールドをレンダリングするか、手動で書き込むことができます-<input name=".." id=".." value="ViewBag.MyHiddenInputValue">も。

ViewBagは、ビューに対する何らかのデータキャリアです。モデルを制限するものではありません-好きなものを配置できます。

8
Rolice

すでにお気付きかもしれませんが、Asp.Net MVCはAsp.Net(webforms)とは異なるパラダイムです。サーバーとクライアント間のフォーム要素へのアクセスは、Asp.Net MVCで異なるアプローチを取ります。

これについては、ウェブ上でさらに多くの読み物をグーグルで検索できます。今のところ、Ajaxを使用してデータを取得またはサーバーに送信することをお勧めします。 _input type="hidden"が、ViewDataからの値またはRazorの場合はViewBagで初期化します。

たとえば、コントローラーは次のようになります。

public ActionResult Index()
{
     ViewBag.MyInitialValue = true;
     return View();
} 

ビューでは、ViewBagの値で初期化される入力要素を持つことができます。

<input type="hidden" name="myHiddenInput" id="myHiddenInput" value="@ViewBag.MyInitialValue" />

次に、ajaxを介してクライアントとサーバー間でデータを渡すことができます。たとえば、jQueryを使用する場合:

$.get('GetMyNewValue?oldValue=' + $('#myHiddenInput').val(), function (e) {
   // blah
});

代わりに $.ajax$.getJSON$.post 要件に応じて。

1
Alex R.

まず、ASP.NET MVCはWebFormsと同じようには機能しません。 runat="server"全体がありません。 MVCは、WebFormsが提供した抽象化レイヤーを提供しません。おそらく、コントローラーとアクションが何であるかを理解してから、モデルバインディングを調べる必要があります。 MVCに関する初心者レベルのチュートリアルは、クライアントとサーバー間でデータを渡す方法を示しています。

0
user840210