ASP.NET MVC - 重用动作行为

时间:2009-08-18 20:40:56

标签: asp.net-mvc code-reuse

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

假设我有一个像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");
}

3 个答案:

答案 0 :(得分:4)

我不明白为什么你需要让你的可重用方法成为一种动作方法。为什么不只是一个返回void / bool / etc的私有方法来指示save的结果,让你的public action方法返回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肯定没有意义,所以我认为这个例子对于你的场景来说是更合适的方法。

答案 1 :(得分:1)

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

我期待其他意见。

答案 2 :(得分:1)

我个人同意Kurt的观点。删除未受保护的页面的概念应与控制器应执行的操作分离。其次,从代码中混淆页面受到保护时会发生什么。在一个操作中,它重定向到索引,在第二个操作中,它重定向到“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");
}