2017-07-27 13 views
-1

いくつかの異なるURLからMainController.GetData()アクションを呼び出し、コピー/ペーストされたコードを一切使用しないでください。人々がこれに取り組むのに好ましい方法はありますか?私はルーティングと同様にそれを行うことができるかもしれないように見えます。 GetMyData()アクションのバージョンを作成した場合、そのコードがすべて同じであるため、ビューとアクションを再利用したいだけです。コントローラのアクション/ビューを他のコントローラと共有する方法

**Example urls** 

*/main/getdata 
/other/getmydata 
/diffferent/getothersdata?userid=3 



public ActionResult MainController::GetData() 
{ 
    var data = GetData(); 
    return View(collection); 
} 

public ActionResult OtherController::GetMyData() 
{ 
    var userId = GetCurrentUserId(); 
    var data = GetData(userId); 
    return View("../main/getdata", collection); 
} 

答えて

2

コントローラは単純なクラスのように見えますが、MVCフレームワーク内での動作はより特殊です。あなたはそうではないかもしれないし、そうでなければならないと言っている方がいいかもしれません。ちょうど古い方法のように、別のアクションのアクションから1つのアクションを呼び出すだけです。ほとんどの場合、コントローラにはコンテキストがあり、インスタンス化してすべて正しく動作するように設定する必要があります。それはアクションメソッドの中で行うことは自明ではなく、あなたのコードを地獄のように醜いものにしようとしています。

本当に2つの選択肢があります。アクションの結果がほしいのであれば、HttpClientを利用し、それをアクティブにする他のリクエストと同じように、実際にHTTPリクエストを送信するのが最善の方法です。

ただし、問題の説明に基づいて、おそらくオプション2が適切です。基本クラスを作成してから継承することができます。あなたは二つのコントローラは両方GetDataを必要としている知っている場合たとえば、あなたが何かを行うことができます。つまり

public abstract class BaseController : Controller 
{ 
    protected IEnumerable<Data> QueryData(int? userId = null) 
    { 
     ... 
    } 
} 

public class MainController : BaseController 
{ 
    public ActionResult GetData() 
    { 
     var data = QueryData(); 
     return View(data); 
    } 
} 

public class OtherController : BaseController 
{ 
    public ActionResult GetMyData() 
    { 
     var userId = GetCurrentUserId(); 
     var data = QueryData(userId); 
     return View(data); 
    } 
} 

を、あなたは両方の派生コントローラ上のアクションの両方が使用できる何かに共通の機能を考慮する。

これはすべてこのシナリオで必要な作業ですが、ベースコントローラーでアクション全体を実装することもできます。たとえば、FooアクションをBaseControllerに追加した場合、MainControllerOtherControllerの両方が、実際に明示的に定義することなく、Fooの要求に応答します。必要に応じてこれらのアクションをオーバーライドすることもできます。

+0

私はベースコントローラーのアイデアが好きです。私はそれがコードをきれいに保つと思いますし、私はアクションコードとビューを再利用できるようになります。他のクリーナーソリューションが提示されない限り、私はこれを受け入れます。ありがとうございました! – user3953989

関連する問題