アクションメソッド内から別のコントローラーでメソッドを呼び出す方法を誰か教えてもらえますか? リダイレクトしたくありません。文字列を返す別のコントローラーでメソッドを呼び出し、アクション メソッド内で応答を使用したいと考えています。
7 に答える
私の耳には、アプリケーションをリファクタリングし、文字列を生成する機能を新しい別のクラスに抽出し (または、適合するクラスがある場合は既存のクラスを再利用し)、両方のコントローラーがそのクラスを使用できるようにする必要があるように聞こえます。
Action
の方法でこれを実現できますHtmlHelper
。
ビューでは、次のようにします。
@Html.Action("OtherAction")
HtmlHelper
ただし、(設計上) アクション メソッドでのインスタンスを取得するのは簡単ではありません。実際、それはとても恐ろしいハックなので、投稿することさえためらっています...
var htmlHelper = new HtmlHelper(new ViewContext(
ControllerContext,
new WebFormView(ControllerContext, "HACK"),
new ViewDataDictionary(),
new TempDataDictionary(),
new StringWriter()),
new ViewPage());
var otherViewHtml = htmlHelper.Action("ActionName", "ControllerName");
これは MVC 3 で機能します。MVC 2、IIRC のコンストラクターStringWriter
から引数を削除する必要がある場合があります。ViewContext
</ハック>
アクション メソッドでコントローラをインスタンス化し、必要な他のメソッドを呼び出すことはできますか?
public ActionResult YourActionMethod()
{
SomeController c = new SomeController();
ActionResult result = c.SomeMethod();
return View();
}
私は Castle Windsor IoC を使用していませんが、理論的には、カスタム コントローラー ファクトリ クラスを作成し、それを Global.asax.css ファイルに登録することによって、このカスタム コントローラー ファクトリを使用するように MVC フレームワークに指示できるはずです。 、Application_Start イベントで:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactor());
}
[Pro Asp.Net MVC 2 フレームワーク、Steven Sanderson、Apress、64 ~ 66 ページを参照]
そうすれば、コードのどこからでもコントローラーをインスタンス化できます。
「現在の」コントローラーまたは他のコードから別のコントローラーのアクションを呼び出さないという概念は、まったく間違っています。コントローラーは単なるクラスです。それらは、MVC フレームワークによって特別な方法で呼び出された場合にのみ「コントローラー」になります。
したがって、これの正誤は、あなたがこれをすべきかどうかではなく、なぜあなたがこれをしているのかに帰着します。
コントローラーをクラスとして使用するだけであれば、これで問題ありません。これを使用してユーザーに応答を送信しようとしている場合は、上記のように RedirectToAction を使用する必要があります。
コントローラーをコントローラーとしてではなく、クラスとして使用する理由はいくつかあります。たとえば、コントローラーをテストするとき。したがって、コントローラーをクラスとして扱うことは、間違っているのではなく必要です。
コントローラをクラスとして使用する非テスト シナリオの例:
私は、MVC フレームワークのテンプレート機能を利用して HTML メール用の HTML を生成するミニ フレームワークを作成しています。これは、すべての Web アプリが何らかの理由で行う必要があることです (注文確認メールなど)。
非常に大まかに言えば、NormalController のアクション (メールを送信する必要がある) で MailManagerController をインスタンス化し (簡単にするために、IoC を使用していないと仮定します)、次のようにします。
MailManagerController mailmanager = new MailManagerController();
string html = mailmanager.OrderConfirmation(order).RenderToString();
Postman.SendEmail(html, order.UserEmailAddress, "MyApp order confirmation");
ここで、RenderToString は、(ViewResultBase オブジェクトを返す) Action の出力を文字列にレンダリングする ViewResultBase の拡張メソッドであり、Postman は、テキストを取得した後に電子メールの送信を処理する静的クラスです。
この手法の優れた点は、MVC フレームワークを使用してテンプレート化された電子メールを作成できることです。なぜなら、OrderConfirmation アクションには、送信しようとしている電子メールの html テンプレートではないにしても、関連付けられたビューがあるからです。
コントローラが設計されていないことをしようとしているようです。必要なメソッドをいくつかのクラスのパブリックメソッドとして設計し、両方のコントローラーアクションから呼び出します。
私は同じものを探していましたが、真剣に人々、なぜそのような複雑な答えを書く必要があるのですか.
これは非常に簡単に答える投稿です: Using Html.ActionLink to call action on different controller
基本的には、アクションリンクのこのオーバーロードを使用するだけです:
ActionLink(HtmlHelper, String, String, String, Object, Object)
したがって、次のようになります。
ActionLink("linkText", "actionName", "controllerName", routeValues, htmlAttributes)
routeValues (アクションの入力) または htmlAttributes がない場合は、null として設定する必要があります。
呼び出しの例を次に示します。
@Html.ActionLink("Add New Student", "Create", "Student", null, new { @class = "btn btn-primary" })