2017-07-27 166 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框架內的行爲更加專業化。你不能,也許最好說你不應該,只是從一個動作中爲另一個動作調用一個動作,就好像它只是任何舊的方法。大多數情況下,這是因爲控制器具有上下文,您必須實例化它們並將它們設置得恰到好處,以便一切正常。這在行動方法內部並不重要,它會讓你的代碼變得糟糕透頂。

真的有兩種選擇。如果您只是想要採取行動的結果,最好的方法是利用HttpClient並實際提交一個HTTP請求,就像任何其他請求會激活它一樣。

但是,根據您的問題描述,選項二可能更合適。您可以創建一個基類,然後從中繼承。例如,如果你知道兩個控制器都將需要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

相關問題