2009-08-18 7 views
3

Этот вопрос относится в первую очередь к хорошему дизайну.ASP.NET MVC - Повторное использование действий

Предположим, что у меня есть действие контроллера, такое как 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

Я не понимаю, почему вам нужно сделать метод повторного использования методом действия. Почему не только частный метод, который возвращает 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 определенно не имеет смысла в этом случае, поэтому я думаю, что этот пример будет более подходящим подходом для вашего сценария.

+0

Как вы относитесь к тому, чтобы придерживаться его в запечатанном внутреннем классе, чтобы его намеренная изоляция от остальных методов действия была очевидна для других? –

+0

@lakario, честно говоря, я думаю, что просто может смутить меня, если вы пошли в такой степени. Если бы я не хотел, чтобы метод был встроен со всеми методами действия контроллера, я бы полностью поместил логику проверки и сохранения в отдельный класс. –

1

На мой взгляд, ваш многоразовый код является действием, потому что он возвращает ActionResult. Так что ваше использование в порядке. DeletePage(Page page) потенциально может оставаться открытым.

Я с нетерпением жду других мнений.

1

Лично я согласен с 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"); 
} 
+0

На самом деле была добавлена ​​дополнительная логика в formCollection ["btnDelete"]! = Null предложение действия Edit, которое я удалил для краткости, извините, если это добавило некоторую путаницу. В любом случае, большое предложение. –

Смежные вопросы