Как работает RedirectToAction()

221
21 мая 2018, 15:30

Сначала я думал, что RedirectToAction() срабатывает сразу и как бы просто вызывается другой метод. Но стало казаться, что RedirectToAction() сначала отправляет запрос клиенту, чтобы тот перешел на такой-то метод с таким-то контроллером.
Вся суть в юнит тесте:

ViewResult result = controller.Index() as ViewResult;
Assert.AreEqual("Main", result.ViewName);

Кстати метод Index возвращает ActionResult, в примерах я видел, что as ViewResult должен ActionResult привести к ViewResult. Но в самом методе происходит RedirectToAction("Main") в котором возвращается представление Main. В таком случае в result остается null.
Но можно и так:

ActionResult result = controller.Index();

Хотя в таком случае никакую полезную информацию из result я достать не смогу.

Answer 1

Но стало казаться, что RedirectToAction() сначала отправляет запрос клиенту, чтобы тот перешел на такой-то метод с таким-то контроллером.

Вам не просто кажется, это так и есть на самом деле. Слово "redirect" в web-разработке испокон веков означало ответ клиенту с кодом из диапазона 300-399, получив который браузер должен перейти по адресу указанному в заголовке Location.

Что же до тестов - тут все просто. Во-первых, если вы знаете что метод должен вернуть ViewResult - ничто не мешает сделать приведение типа:

var result = (ViewResult)controller.Index();

Отмечу, что в тестах предпочтительнее использовать именно такую форму приведения типа вместо as. Операция as нужна если события могут пойти по-разному, метод может вернуть ViewResult а может и не вернуть его. Но тест на то и тест что вы должны заранее знать что метод возвращает, и приведение типа через скобки работает одновременно как проверка.

Во-вторых, помните: ActionResult - это лишь пожелание со стороны контроллера, а еще не действие! Ни один наследник ActionResult не начинает исполняться просто из-за того что его вернул вам контроллер из своего метода.

Когда приходит запрос от браузера - ASP.NET сначала вызывает метод контроллера, потом отдельно исполняет ActionResult (вызывает его метод ExecuteResult). Но если вы в своем тесте не вызовете ExecuteResult - то и исполняться он не будет.

Кстати, RedirectToAction возвращает RedirectToRouteResult.

В-третьих, не нужно пытаться протестировать в одном тесте сразу несколько контроллеров. Вы убедились что Index редиректит на Main - ок, эта проверка пройдена. Проверять метод Main нужно в другом тесте.

Answer 2

Я подумал что лучше было бы сделать так:

 ActionResult result = controller.Authorization(model);
 if((result as ViewResult) == null)
 {
     string action = (result as RedirectToRouteResult).RouteValues["action"] as string;
     string controller= (result as RedirectToRouteResult).RouteValues["controller"] as string;
 }

в таком случае в action и controller будет информация по переадресации

READ ALSO
Exception при отправке писем вне домена // SMTP // C#

Exception при отправке писем вне домена // SMTP // C#

При отправке писем с помощью данного метода, письмо отправляются только на доменные п/яПри попытке отправить на иные (Google, Mail

171
Задержка при вызове событий OnMouse()

Задержка при вызове событий OnMouse()

Создал собственный Control для всех кнопок, чтобы все кнопки имели графический видПример кода:

129
Не работает MetroMessageBox

Не работает MetroMessageBox

У MetroMessageBox нет метода ShowMetroFrameWork установлен и подключен

186
Проблема при вычислении хэша

Проблема при вычислении хэша

Вычисляю HMAC SHA1, алгоритм следующий:

148