Могу ли я использовать метод сокрытия для ActionResult, имеющего ту же сигнатуру, что и базовый контроллер?

У меня есть 2 контроллера, один наследующий другой. Мне нужно переопределить ActionResult из базового контроллера, потому что мне нужно изменить код, чтобы реализовать разбиение на страницы в плагине для nopCommerce. Однако я получаю исключение AmbiguousMatchException из-за нового ActionResult.

Базовый контроллер:

public class BaseController : Controller {
    public ActionResult Category(int categoryId, CatalogPagingFilteringModel command)
    {
        //original action result code
    }
}

Контроллер клиента с наследованием

public class CustomController : BaseController {
    public new ActionResult Category(int categoryId, CatalogPagingFilteringModel command)
    {
        // my pagination code with different model/view
    }
}

Информация о маршруте: здесь я удаляю маршрут для базового контроллера и добавляю новый маршрут для использования контроллера CustomCatalog.

routes.Remove(routes["OriginalCategory"]);
            routes.MapLocalizedRoute(
                            "OriginalCategory",
                            "Category/{categoryId}/{SeName}",
                            new { controller = "CustomCatalog", action = "Category", SeName = UrlParameter.Optional },
                            new { categoryId = @"\d+" },
                            new[] { "Nop.Plugin.Common.Web.Controllers" });

Затем я получаю исключение AmbiguousMatchException

[AmbiguousMatchException: текущий запрос действия «Категория» для типа контроллера «CustomCatalogController» неоднозначен для следующих методов действия: System.Web.Mvc.ActionResult Category (Int32, Nop.Web.Models.Catalog.CatalogPagingFilteringModel) для типа Nop. Plugin.Common.Web.Controllers.CustomCatalogController System.Web.Mvc.ActionResult Category (Int32, Nop.Web.Models.Catalog.CatalogPagingFilteringModel) для типа Nop.Web.Controllers.CatalogController]

ИЗМЕНИТЬ. Базовый контроллер находится в ядре приложения, а CustomController находится в подключаемом модуле, что означает, что я не могу изменить тип базового контроллера.


person Matt R    schedule 19.11.2012    source источник


Ответы (2)


Вы не можете переопределить метод, который не был объявлен virtual.

Вы можете определить новый метод с другой подписью или инкапсулировать функциональность исходного класса, сохранив частную ссылку на него в классе-оболочке. Это помогает, если у вас есть интерфейс, который вы можете реализовать из базовой библиотеки (потому что это позволяет вам заменить класс-оболочку, где будет использоваться базовый класс, реализующий тот же интерфейс), но вы также можете сделать это без интерфейса.

// Base class source code is not modifiable
class BaseClass {
   public ActionResult Category(...) {}
   public ActionResult Other() {}
}

// Wrapper class can modify the behavior
class Wrapper {
  private BaseClass baseClass = new BaseClass();  // Instantiate appropriately

  public ActionResult Category(...) {
    // do some stuff
  }

  public ActionResult Other() {
    return baseClass.Other();
  }
}
person Peter Gluck    schedule 19.11.2012

Как насчет использования virtual в базовом контроллере и override в производном контроллере вместо new?

база:

public virtual ActionResult Category(...) { }

полученный:

public override ActionResult Category(...) { }
person Peter Gluck    schedule 19.11.2012
comment
К сожалению, я не могу изменить тип базового ActionResult, поскольку он является частью ядра, а не плагина. - person Matt R; 20.11.2012