Asp.net mvc ASP.NET MVC-重用操作行为

Asp.net mvc ASP.NET MVC-重用操作行为,asp.net-mvc,code-reuse,Asp.net Mvc,Code Reuse,这个问题主要涉及好的设计 假设我有一个控制器操作,比如DeletePage,它可以在同一控制器的两个单独视图中调用。假设delete逻辑不包含在操作本身中,而是包含一些调用正确业务逻辑的条件检查等,那么当我可以使用一个私有方法返回一个ActionResult时,复制delete操作的结构是没有意义的,因为我在两个操作中都调用了ActionResult,这可能导致删除。我的问题是,在哪里放置这样一个可重用的操作方法是最好的?现在我只是将它们标记为private,并将它们粘贴在controller类

这个问题主要涉及好的设计

假设我有一个控制器操作,比如DeletePage,它可以在同一控制器的两个单独视图中调用。假设delete逻辑不包含在操作本身中,而是包含一些调用正确业务逻辑的条件检查等,那么当我可以使用一个私有方法返回一个ActionResult时,复制delete操作的结构是没有意义的,因为我在两个操作中都调用了ActionResult,这可能导致删除。我的问题是,在哪里放置这样一个可重用的操作方法是最好的?现在我只是将它们标记为private,并将它们粘贴在controller类的一个区域中,但是对于这样一个方法,或者完全其他地方,一个密封的内部类可能更有意义

想法

public ActionResult EditPage(int id, FormCollection formCollection)
{
    var page = _pagesRepository.GetPage(id);

    if (page == null)
        return View("NotFound");
    if (page.IsProtected)
        return View("IllegalOperation");

    if (formCollection["btnSave"] != null)
    {
        //...
    }
    else if (formCollection["btnDelete"] != null)
    {
        return DeletePage(page);
    }
    return RedirectToAction("Index");
}

public ActionResult DeletePage(int id)
{
    var page = _pagesRepository.GetPage(id);

    if (page == null)
        return View("NotFound");

    return DeletePage(page);
}

// Reusable Action
private RedirectToRouteResult DeletePage(Page page)
{
    if(page != null && !page.IsProtected)
    {
        _pagesRepository.Delete(page);
        _pagesRepository.Save();

        FlashMessage(string.Format(PageForms.PageDeleted, page.Name), MessageType.Success);

        return RedirectToAction("Index");
    }
    return RedirectToAction("Index");
}

在我看来,您的可重用代码是一个动作,因为它返回一个ActionResult。所以你的用途很好。
DeletePage(Page)
可能仍然是公共的


我期待其他意见。

我不明白为什么需要将可重用方法变成一种操作方法。为什么不只是一个返回void/bool/etc指示保存结果的私有方法,并让您的公共操作方法返回RedirectToAction()?实际上,这是同样的结果,但我认为这是一个更清晰的方法

public ActionResult DeletePage(int id)
{
        var page = _pagesRepository.GetPage(id);

        if (page == null)
                return View("NotFound");

        DeletePage(page);
        return RedirectToAction("Index");
}

//reusable method
private void DeletePage(Page page)
{
    //your same validation/save logic here
}

将来您可能会考虑将这个私有DeleTePad方法移动到执行验证和/或保存的单独服务类中。在这种情况下,返回ActionResult肯定没有意义,因此我认为这个示例对于您的场景更合适。

我个人同意Kurt的观点。删除不受保护的页面的概念应该与控制器应该执行的操作分离。其次,当页面受到保护时,代码会混淆应该发生什么。在一个操作中,它重定向到索引,在第二个操作中,它重定向到“非法操作”视图。就我个人而言,我会做一些像

public ActionResult DeletePage(int id) {
    var page = _pagesRepository.GetPage(id);
    if (!PageIsValidForDeletion(page)) {
         string invalidPageView = FindViewForInvalidPage(page);
         return View(invalidPageView);
    }
    DeletePage(page);
    return RedirectToAction("Index");
}

你对把它放在一个封闭的内部类中,这样它与其他动作方法的有意隔离对其他人来说是显而易见的,你有什么看法?@lakario,坦白地说,如果你达到这个程度,我想这可能会让我感到困惑。如果我不想将该方法与所有控制器的操作方法直接内联,我会将验证和保存逻辑完全放在一个单独的类中。formCollection[“btnDelete”]!=为了简洁起见,我删除了Edit操作的null子句,如果这增加了一些混乱,那么很抱歉。不管怎样,这都是一个很好的建议。