質問: 数週間前からC#を触り始めたばかりなので、用語等間違いがあればすみません。 C#のASP.NET(?)でMVCモデルののWebアプリケーション開発を行っています。 ### 前提・実現したいこと 環境としてはWin10,visual studio2015,.net Framework 4.8です。 1Viewで、formのsubimtボタン押下イベントからControllerのメソッドを呼び出す 2Controllerでバリデーションチェック、DB検索処理などを行う 3バリデーションエラーや、表示するデータが存在しない場合には、エラーを表示する 4バリデーションチェック、またDB検索処理の結果、表示するデータが存在した場合は別タブで別Controllerのページを開く ### 発生している問題・エラーメッセージ 3まではうまく動いているのですが、4の実現ができず詰まっています。 呼び出しているControllerのメソッドでは、ActionResultを戻り値としており、 エラーなどがあった場合にはViewModelにエラーメッセージを持たせ、自身を再度表示するような処理になっています。 (この辺りは既存の実装を元にしているため、この方法から大きく外れたくないと思っています。 簡単に調べた感じではよくある実装のように見えました。) しかし、チェックを抜けた後にこのメソッド内で「別タブで別の画面を開く」が実装できなく、良い方法があれば教えていただきたいです。 「別タブ」と「別のController画面」の二つ解決しなくてはならないのですが、どちらも調べてみたのですがよい方法が見つけられませんでした。 ### 該当のソースコード ``` public ActionResult SearchItem(MyViewModel vm) { // バリデーションチェックなどを行う if (!ModelState.IsValid) { // viewにエラーメッセージを持たせているので、エラーが表示された画面へリダイレクトする return View("Index", vm); } // チェックを抜けた先で何をreturnすればいいのかわからない // ViewやRidirectAction等では望む挙動を得られなかった return ??? } ``` ### 試したこと 上記を一度あきらめて、js側で実現しようとしました。(Controllerのメソッドをajax通信で呼び出し、処理を振り分けようとした) ~~ですが、razor htmlでformとsubmitを作成し用いており、通常のsubmitを止めることができず断念しました。 `event.preventDefault();`をjsの中に挟みましたがどうしてもactionが発動してしまい、 実装画面のリダイレクトやらがかかってしまいました。~~ jsの他の部分でエラーが出ていることが原因でしたので、jsについては解決しました。 (その際に参考にした記事:jQueryでフォームをAjax送信する際の基本パターンのチュートリアル。二重送信の防御とか。)
回答: 質問のコメントに反応がないですが、とりあえず回答欄に書いておきます。フィードバックがなければこれで終わりにします。 post-redirect-get パターンというのがありますが、なぜそういうパターンが推奨されるかはご存じですか? (ちなみに、ASP.NET MVC でスキャフォールディングを使うとそのパターンになります) 2 画面 (別タブも含む) 開くのは、セキュリティの問題を含め、好ましからざる状況に陥る可能性がありますが、それは承知の上の話ですか? そういう普通でないことをすることによって生ずる好ましからざる副作用・問題点は十二分に承知の上ということであれば・・・ 別タブで開くというと、JavaScript の window.open を思いつきます。例えば home/index を別タブで開くとすると window.open('/home/index'); で開くことができます・・・がポップアップブロックが問題です。 ポップアップブロックはなんとかできるということであれば、アクションメソッドで ViewBag に別タブで開くか否かのフラッグを設定した後 return View(); とし、その View で ViewBag のフラッグを見てフラッグが立っていてら window.open('/home/index'); とすれば別タブを開くことができると思います。 ポップアップブロックはダメということですと、自動的には無理そうで、View が表示された後ユーザーによって手動(クリック操作とか)で別タブを開いてもらうぐらいしかなさそうです。 手動は NG であろうと思いますが、であれば、部分ビューで表示できるようなものなら、同じページのどこかに部分ビューで表示するということを検討してはいかがですか。