Назначение публичных методов NonAction в MVC

Я только начал работать в MVC, и у меня есть одно сомнение.

Вместо метода Nonaction мы можем создать частный метод в контроллере или мы также можем написать метод в модели и вызвать это из контроллера.

Итак, какова реальная цель использования общедоступного метода Nonaction в MVC?

Ответ 1

(Я реорганизовал ответ, чтобы лучше ответить на вопросы в комментариях)

Я думаю, этот атрибут здесь только для лучшей гибкости. Как разработчик фреймворка, вы хотите как можно больше уменьшить ограничения кодирования у конечного пользователя. Требование об отсутствии публичных недействительных действий может звучать хорошо "в целом", но может быть слишком ограничительным для некоторых проектов. Добавление [NonAction] решает их проблему (хотя их плохо продуманный дизайн) - и, очевидно, вы не вынуждены использовать этот атрибут, поэтому он является беспроигрышной с точки зрения дизайнера каркаса.

Другая причина может быть устаревшей - в более ранних версиях MVC только методы, помеченные [Action], где рассматриваются как действия. Поэтому, когда они смягчили требование (и все общедоступные методы стали рассматриваться как действия), они сохранили [NonAction], чтобы разработчики не слишком запутались.


В целом, использование NonAction - плохая практика - именно по причинам, которые вы указали. Если что-то не должно быть действием, оно не должно быть public в первую очередь.

Проблема с общедоступными методами non-action на контроллере заключается в том, что они заставляют людей пытаться создать экземпляр вашего контроллера и вызвать метод вместо выделения общей логики:

Сравнение

public class MyController : IController
{
    public ActionResult Foo(long orderId)
    {
        var order = new OrdersController().GetOrder(orderId); //GetOrder is public
        ...
    }
}

с

public class MyController : IController
{
    public ActionResult Foo(long orderId)
    {
        var order = _orderService.GetOrder(orderId);
        ...
    }
}

Первый подход приводит к усилению связи между контроллерами и непрямым кодом в действиях. Код становится трудно поддающимся проверке и рефактору, и громоздким для издевательства/тестирования.

Помимо расширенной связи любой публичный метод non-action - это дыра в безопасности - если вы забыли пометить его с помощью [NonAction] (или, лучше, смените общественность) - поскольку он рассматривается как нормальное действие и может быть вызван извне, Я знаю, что исходный вопрос предполагает, что вы наверняка никогда не забудете приложить атрибут, если это необходимо, но также важно понять, что может произойти, если вы хотите;) Ну ладно, и, как мы это делаем, мне кажется, что "забывание атрибута" более теоретически возможно, по сравнению с "забыванием сделать метод приватным".


Иногда люди говорят, что для модульного тестирования требуется public не-действия, но опять же, когда что-то не является действием, его скорее всего можно изолировать в отдельном классе и протестировать отдельно. Более того, даже если это невозможно по какой-либо причине, маркировка метода public для целей тестирования является лишь плохим привычкой - рекомендуется использовать internal и InternalsVisibleTo.

Ответ 2

Такая ситуация может быть вызвана требованиями некоторой структуры тестирования, например, вам нужно выполнить единичное тестирование по этому методу, тогда вы можете разоблачить его, хотя его плохая конструкция, но не может изменить их, пришлось вынести.

По умолчанию структура MVC рассматривает все общедоступные методы класса контроллера как методы действий. Если ваш класс контроллера содержит общедоступный метод, и вы не хотите, чтобы он был методом действия, вы должны отметить этот метод с помощью атрибута NonActionAttribute.

Реальная цель использования public NonAction

Чтобы ограничить доступ к методу non-action для уведомления о структуре MVC, данный метод контроллера не является действием.

При попытке запустить метод с атрибутом NonAction по URL-адресу вы получите ошибку 404 в качестве ответа на запрос.

Ссылка: http://msdn.microsoft.com/en-us/library/dd410269%28v=vs.90%29.aspx

Подробнее: http://weblogs.asp.net/gunnarpeipman/archive/2011/04/09/asp-net-mvc-using-nonactionattribute-to-restrict-access-to-public-methods-of-controller.aspx

Ответ 3

Это полезно, когда Url не чувствителен к регистру. Так, например, если у вас есть запрос Главная/О, это будет HomeController и О действии, а также hOmE/AbOUT подходит к тому же контроллеру и к тому же методу действий.

Как ниже

public class HomeController:Controller
{
....
    public ViewResult About()
    {
        return View();
    }

    public ViewResult aBOut()
    {
        return View();
    }
}

Кадр не может определить, какую функцию about вызывать, и выдает исключение, указывающее, что вызов неоднозначен.

enter image description here

Конечно, одним из способов решения этой проблемы является изменение имени действия.

Если по какой-то причине вы не хотите изменять имя действия, и одна из этих функций не является действием, вы можете украсить этот метод без действия атрибутом NonAction. Пример:

[NonAction]
public ActionResult aBOut()
{
   return View();
}

Ответ 4

Мы используем контроллеры как обязательные драйверы с настраиваемым конвейером ASP, каждый драйвер отвечает за отображение одного раздела (частичного представления) страницы результатов. Затем мы используем общедоступные методы, например:

[NonAction]
publi int GetOrder() 

чтобы разрешить порядок разделов на странице или другом, чтобы разрешить авторизацию для текущего пользователя (например, если текущий раздел доступен для редактирования или только для чтения).

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

Ответ 5

По умолчанию структура MVC рассматривает все общедоступные методы класса контроллера как методы действий. Если ваш класс контроллера содержит общедоступный метод, и вы не хотите, чтобы он был методом действия, вы должны пометить этот метод атрибутом NonActionAttribute.

Ответ 6

ASP.NET очень настраиваемый. Предположим, вы собираетесь изменить поведение платформы по умолчанию, переопределив обработчик HTTP MVC. Возможно, вы хотите настроить логику регистрации в зависимости от используемого контроллера. Некоторые контроллеры реализуют ваш интерфейс ILoggingController с помощью метода IControllerLogger GetLogger(). Для этого метода вам нужно написать общедоступный метод бездействия.