4

最近、MVCを使い始めましたが、その前は「クラシック」なASP.NETを使用していました。

Ruby on Rails(RoR)を使用した後、RoRの動作と同様にMVCでPOSTリクエスト処理を実装する方法を知りたいと思います。RoRではこのPostメソッドを使用するため、ビューに必要な関数は1つだけです。

ASP.NET MVCでは、との2つの別々の関数を使用する必要がGETあるPOSTため、同じデータを2回初期化する必要があり、コードで何かを繰り返すのは好きではありません。

リクエストがPOST1つのメソッドにあるかどうかを確認するにはどうすればよいですか?

アップデート:

解決策が見つかりました:Request.HttpMethodを使用する必要があります。

ありがとうございました!

4

5 に答える 5

9

同じことを知りたくてこの質問に出くわしました。以下は、私の状況と私が使用した解決策の詳細な説明です(ここで提供されている他の回答を利用しています)。私はもともと 2 つの別々のメソッド アプローチを使用しようとしましたが、これらのメソッドのメソッド シグネチャが同一になったときに問題が発生しました。

レポート データを表示するページがあります。ページの上部には、いくつかのフィールドを含むフォームがあり、ユーザーは開始日、終了日などのレポート パラメータを指定できます。

私は当初、Get メソッドと Post メソッドを処理する 2 つの別個のメソッドを作成することで、これに取り組みました。post メソッドはブラウザーを get メソッドにリダイレクトします。これにより、指定されたすべてのパラメーターがクエリ文字列に追加され、ブラウザーが入力したデータを再送信するというダイアログをユーザーに表示しなくなります。リフレッシュする場合。注:フォーム要素のメソッド属性を「Get」に設定することでこれを達成できることに後で気付きましたが、理想的にはコントローラーはビューがどのように実装されているかを知っているべきではないと思うので、私の意見ではそれは無関係です。

これら 2 つのメソッドを開発していると、最終的にはメソッド シグネチャが同じになる状況に陥りました。さらに、これら 2 つのメソッドのコードはほぼ同じになったので、それらを 1 つのメソッドにマージし、リクエスト動詞をチェックして、リクエストが「Get」でない場合に少し異なることを実行できるようにすることにしました。私の 2 つの方法の簡単な例を以下に示します。

    // this will not compile because the method signatures are the same

    public ActionResult MyReport(DateRangeReportItem report)
    {
        // if there are no validation errors and the required report parameters are completed
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // retrieve report data and populate it on the report model
            report.Result = GetReportData(report.CreateReportParameters());
        }

        return View(report);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult MyReport(DateRangeReportItem report)
    {
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
            // this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
            return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
        }
        else
        {
            // there were validation errors, or the report parameters are not yet complete
            return View(report);
        }
    }

モデル オブジェクトを get メソッドのパラメーターとして受け入れるのはなぜですか? その理由は、モデル オブジェクトに既に組み込まれている検証ロジックを利用したかったからです。クエリ文字列ですべてのパラメーターが既に指定されている状態で誰かが私のページに直接移動した場合、先に進んでレポート データを取得し、ページに表示したいと考えています。ただし、クエリ文字列で指定されたパラメーターが無効な場合は、検証エラーもページに表示する必要があります。モデル オブジェクトをパラメーターとして配置することにより、MVC フレームワークは自動的にモデル オブジェクトの入力を試み、追加の作業を行わなくても検証エラーをキャプチャします。

この質問に対して投稿された他の回答を使用して、プロジェクトのベース コントローラー クラスに RequestHttpVerb プロパティを作成しました。

    public HttpVerbs RequestHttpVerb
    {
        get { return (HttpVerbs)Enum.Parse(typeof(HttpVerbs), this.Request.HttpMethod, true); }
    }

したがって、最終的に私の統合メソッドは次のようになります。

    [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
    public ActionResult MyReport(DateRangeReportItem report)
    {
        // check if there are any validation errors in the model
        // and whether all required report parameters have been completed
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // this is unnecessary if the form method is set to "Get"
            // but within the controller I do not know for sure if that will be the case in the view
            if (HttpVerbs.Get != this.RequestHttpVerb)
            {
                // redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
                // this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
                return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
            }

            // there were no validation errors and all required report parameters are complete
            // retrieve report data and populate that data on the model
            report.Result = GetReportData(report.CreateReportParameters());
        }

        // display the view with the report object
        // Any model state errors that occurred while populating the model will result in validation errors being displayed
        return View(report);
    }

それが問題に対する私の現在の解決策です。リダイレクトを実行する必要があるかどうかを判断するために Request.HttpMethod プロパティを確認する必要はありませんが、問題に対する別の解決策が見つかりませんでした。Get リクエストと Post リクエストを処理するために 2 つの別々のメソッドを保持していれば問題ありませんでしたが、同じメソッド シグネチャがこれを妨げていました。Post アクション ハンドラー メソッドの名前を変更して、メソッド シグネチャの競合を回避し、何らかのメカニズムを使用して、名前を変更したメソッドが "MyReport" アクションを引き続き処理する必要があることを MVC フレームワークに示すことをお勧めしますが、そのようなメカニズムを認識していません。 MVC フレームワークで。

于 2010-03-24T20:43:04.857 に答える
5

GET と POST のメソッド シグネチャが異なる場合にのみ、別々のメソッドが必要です。1 つのアクション メソッドで GET メソッドと POST メソッドを処理できない理由はありません。

GET か POST かを知る必要がある場合は、アクションで Request.HttpMethod を使用して確認できますが、他のポスターで提案されている [AcceptVerbs(HttpVerbs.Post)] 属性で装飾された別のメソッドを使用することをお勧めします.

于 2010-02-23T23:58:27.990 に答える
3

ASP.NET MVC をチェックインしません。[AcceptVerbs(HttpVerbs.Post)]メソッドが投稿のみに適用されることを示す属性でメソッドを装飾し、投稿を処理するために使用されるメソッドでモデルを受け入れます。

ASP.NET MVC フレームワークについて理解を深めるために、 NerdDinnerのウォークスルーを実行することを強くお勧めします。

于 2010-02-23T19:30:33.817 に答える
1

Request.HttpMethodプロパティを見てください。

于 2010-02-23T19:30:10.820 に答える
0

正しい方法は、Post リクエスト中に ModelBinding を使用することです。

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(EmployeeViewModel model)
{
 //validate data, save employee, handle validation errors...
}

これにより、データを再度初期化する必要がなくなります。

于 2010-02-23T19:30:49.430 に答える