3

这个问题主要与良好的设计有关。

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

想法?

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");
}
4

3 回答 3

4

我不明白为什么需要将可重用方法设为操作方法。为什么不只是一个返回 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
}

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

于 2009-08-18T21:02:19.843 回答
1

我个人同意库尔特的观点。删除未受保护页面的概念应该与控制器应该执行的操作分离。其次,当页面受到保护时,代码会让人感到困惑。在一个动作中它重定向到索引,在第二个动作中它重定向到“IllegalOperation”视图。就个人而言,我会做一些类似...

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");
}
于 2009-08-18T21:32:57.863 回答
1

在我看来,您的可重用代码是一个 Action,因为它返回的是一个 ActionResult。所以你的使用没问题。DeletePage(Page page)可能会保持公开。

我期待其他意见。

于 2009-08-18T20:53:54.743 回答