我有一個控制器是從一個基礎控制器繼承,我想知道如何利用基礎控制器的所有邏輯,但返回一個不同於基礎控制器使用的視圖。如何繼承ASP.NET MVC控制器並只更改視圖?
基本控制器填充一個模型對象並將該模型對象傳遞給它的視圖,但我不知道如何在子控制器中訪問該模型對象,以便我可以將它傳遞給子控制器的視圖。從我的應用程序
我有一個控制器是從一個基礎控制器繼承,我想知道如何利用基礎控制器的所有邏輯,但返回一個不同於基礎控制器使用的視圖。如何繼承ASP.NET MVC控制器並只更改視圖?
基本控制器填充一個模型對象並將該模型對象傳遞給它的視圖,但我不知道如何在子控制器中訪問該模型對象,以便我可以將它傳遞給子控制器的視圖。從我的應用程序
基於此線程給出的反饋,我實現了一個類似Antony Koch提出的解決方案。
取而代之的是使用抽象方法,我使用了一個具體的,虛擬的GetIndex方法,這樣我就可以爲它的基礎控制器放置邏輯。
public class SalesController : Controller
{
// Index view method and model
public virtual ActionResult GetIndex()
{
return View("Index", IndexModel);
}
protected TestModel IndexModel { get; set; }
public virtual ActionResult Index()
{
ViewData["test"] = "Set in base.";
IndexModel = new TestModel();
IndexModel.Text = "123";
return GetIndex();
}
[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Index(TestModel data, FormCollection form)
{
TryUpdateModel(data, form.ToValueProvider());
IndexModel = data;
return GetIndex();
}
}
// This class will need to be in a different namespace or named differently than the
// parent controller
public class SalesController : MyApp.Controllers.BaseControllers.SalesController
{
// Index view method and model
public override ActionResult GetIndex()
{
return View("ClientIndex", IndexModel);
}
public override ActionResult Index()
{
return base.Index();
}
[AcceptVerbs(HttpVerbs.Post)]
public override ActionResult Index(TestModel data, FormCollection form)
{
return base.Index(data, form);
}
}
我面臨着同樣的問題,任何人都可以幫助我嗎? [我的問題](http://stackoverflow.com/questions/12720611/cant-add-controller-which-uses-class-which-is-inherited-from-other-class) – user1668543 2012-10-05 06:25:04
樣品:
基類:
public abstract class BaseTableController<T,TU> : BaseController where TU : IGenericService<T>,IModelWrapperService
{
protected readonly TU _service;
public BaseTableController(TU service)
{
_service = service;
_service.ModelWrapper = new ControllerModelStateWrapper(ModelState);
}
public ActionResult Index()
{
return View(_service.List());
}
繼承:
public class SeverityController : BaseTableController<Severity, ISeverityService>
{
public SeverityController(ISeverityService service)
: base(service)
{
}
//NO CODE INSIDE
}
SeverityController.Index()導致查看/嚴重性/的Index.aspx 。只需準備視圖。嚴重性是我的錯誤跟蹤應用程序中的一個詞典。每個字典都有類似的邏輯,所以我可以分享一些代碼。
我最終只是在基礎控制器 - viewName上添加了一個額外的參數。
似乎工作得很好。
我錯過了任何主要的缺點?
public class SalesController : Controller
{
public virtual ActionResult Index(string viewName)
{
ViewData["test"] = "Set in base.";
TestModel model = new TestModel();
model.Text = "123";
return String.IsNullOrEmpty(viewName) ? View(model) : View(viewName, model);
}
[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Index(TestModel data, FormCollection form, string viewName)
{
TryUpdateModel(data, form.ToValueProvider());
return String.IsNullOrEmpty(viewName) ? View(data) : View(viewName, data);
}
}
public class SalesController : MyApp.Controllers.BaseControllers.SalesController
{
public override ActionResult Index(string viewName)
{
return base.Index("ClientIndex");
}
[AcceptVerbs(HttpVerbs.Post)]
public override ActionResult Index(TestModel data, FormCollection form, string viewName)
{
return base.Index(data, form, "ClientIndex");
}
}
我擔心的是用戶可以通過http將參數發送到控制器中的ActionResult。如果用戶能夠在不覆蓋「索引」的控制器上調用索引,從而能夠傳遞具有意外結果的視圖名稱,就會冒風險。不太可能,但仍然有可能。 – 2009-10-14 16:00:35
我不喜歡這個解決方案。您不必指定視圖名稱。想象一下你有一個BaseController和兩個繼承 - ChildOneController和ChildTwoController。如果您調用〜/ ChildOne/Index,它會從〜/ ChildOne/Index/Index.aspx中查看。如果您調用/ ChildTwo/Index,它會從〜/ ChildTwo/Index/Index.aspx中查看。視圖名稱相同,但是來自不同的地方。 – LukLed 2009-10-14 16:09:00
我面臨着同樣的問題,任何人都可以幫助我嗎? [我的問題](http://stackoverflow.com/questions/12720611/cant-add-controller-which-uses-class-which-is-inherited-from-other-class) – user1668543 2012-10-05 07:13:05
public class BaseController : Controller {
protected BaseController() {}
public ActionResult Index()
{
return GetIndex();
}
public abstract ActionResult GetIndex(); }
public class MyController : BaseController {
public MyController() {}
public override GetIndex()
{
return RedirectToAction("Cakes","Pies");
}
}
只需使用抽象給你打電話從子類需要的位。
我做了類似的事情。看到我的新答案。我希望避免爲每個控制器操作創建輔助方法,但我想這是最好的方法。 – 2009-10-14 17:30:17
有幾點。如果您知道這就是您要返回的所有內容,則可以將您的返回值輸入爲ViewResult。然後你可以從重寫的實現中詢問這個值。更重要的是,根據MVC v1源代碼,調用View(object)只需在控制器上設置ViewData.Model,然後構造一個ViewResult。
Controller.cs:440
protected internal ViewResult View(object model) {
return View(null /* viewName */, null /* masterName */, model);
}
Controller.cs:456
protected internal virtual ViewResult View(string viewName, string masterName, object model) {
if (model != null) {
ViewData.Model = model;
}
return new ViewResult {
ViewName = viewName,
MasterName = masterName,
ViewData = ViewData,
TempData = TempData
};
}
因此,所有你需要做的是調用基方法,並調用視圖(串)。
namespace BaseControllers
{
public class CoolController
{
public virtual ViewResult Get()
{
var awesomeModel = new object();
return View(awesomeModel);
}
}
}
public class CoolController : BaseControllers.CoolController
{
public override ViewResult Get()
{
var ignoredResult = base.Get();
// ViewData.Model now refers to awesomeModel
return View("NotGet");
}
}
當然,你浪費CPU週期來構造你忽略的ViewResult。因此,你可以這樣做:
public class CoolController : BaseControllers.CoolController
{
public override ViewResult Get()
{
var baseResult = base.Get();
baseResult.ViewName = "NotGet";
return baseResult;
}
}
如果你的基本控制器返回的ActionResult,你就必須改變之前VIEWNAME把它轉換爲的ViewResult。
您是否嘗試從基本控制器繼承並準備視圖? – LukLed 2009-10-14 15:31:08