Как мне инкапсулировать форму / публикацию / проверку [/ редирект] в ViewUserControl в ASP.Net MVC 2 - PullRequest
2 голосов
/ 28 мая 2010

Короткая версия: нужен ViewUserControl (т. Е. Форма входа), чтобы публиковать сообщения для себя и иметь возможность перенаправлять (т. Е. При успешном входе в систему) или возвращать исходный вид (т. Е. Home / Index) со сводкой проверки, а не мешать другим ViewUserControls на странице.

Кроме того, HomeController / Index должен иметь минимальные знания о внутренней работе формы входа. В идеале, Html.RenderAction («Логин», «Пользователь») или аналогичный - это все, что требуется.

В данный момент застрял на перенаправлении, дающем «Дочерним действиям не разрешено выполнять действия перенаправления». Я знаю почему, но мне интересно, есть ли способ обойти это или как-то еще, как мне следует это делать.

Детали того, чего я пытаюсь достичь:

  • инкапсулирует форму входа (или любую) для повторного использования на сайте
  • пост для себя
  • при неудачном входе в систему / проверке показать исходную страницу с Сводной информацией о проверке
    • (некоторые могут поспорить, чтобы просто опубликовать на странице входа в систему и показать там Сводную информацию о проверке; если то, что я пытаюсь достичь, невозможно, я просто пойду по этому пути)
  • при успешном входе в систему перенаправьте в / App / Home / Index
  • также хочу:
    • придерживаться принципов PRG
    • избегать ajax
    • сохранить форму входа (UserController.Login ()) как можно более инкапсулированной; Избегайте реализации HomeController.Login (), так как форма входа может появиться в другом месте

Все, кроме перенаправления, работает. Мой подход до сих пор был:

  • Home/Index включает регистрационную форму: <%Html.RenderAction("Login","User");%>
  • User/Login ViewUserControl<UserLoginViewModel> включает в себя:
    • using(Html.BeginForm()){}
    • включает скрытое поле формы "userlogin"="1"
public class UserController : BaseController {
    ...
    [AcceptPostWhenFieldExists(FieldName = "userlogin")]
    public ActionResult Login(UserLoginViewModel model, FormCollection form){
        if (ModelState.IsValid) {
            if(checkUserCredentials()) {
                setUserCredentials()
                <b>return this.RedirectToAction<Areas.App.Controllers.HomeController>(x => x.Index());</b>
            }
        else {
            <b>return View();</b>
        }
    }
    ...
}

Отлично работает при : сбой учетных данных ModelState или пользователя - return View () уступает Home / Index и отображает соответствующую сводку проверки.

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

Сбой при : действительные учетные данные ModelState и пользователя - RedirectToAction <> () выдает следующую ошибку:
«Дочерним действиям запрещено выполнять действия перенаправления.»

Похоже, что в классические дни ASP это было бы решено с помощью Response.Buffer=True. Есть ли эквивалентная настройка или обходной путь сейчас?

Кстати, работает: ASP.Net 4, MVC 2, VS 2010, Dev / Debugging Web Server

Надеюсь, все это имеет смысл.

Итак, каковы мои варианты? Или где я иду не так в моем подходе? ТИА!

Ответы [ 2 ]

0 голосов
/ 16 июня 2014

Древний вопрос, но это в основном то же самое, что я делаю сейчас, и мои поиски все еще не выявили ответов, которые соответствуют всем критериям; Я не понимаю, почему так трудно полностью инкапсулировать процесс входа в систему, как это, но, возможно, я просто пропускаю четко написанный пример.

Мое решение, которое работает отлично, это просто использовать старый стандарт

System.Web.HttpContext.Current.Response.Redirect(url, true);

... в контроллере для процесса входа в систему.

Размещая его, потому что он работает, он поддерживает инкапсуляцию, и это немного менее ужасно, чем решение «перенаправить представление, содержащее a Javascript-перенаправление», которое я видел, но мне все же хотелось бы получить лучшее представление о том, как чтобы достичь такого вида упаковки более MVC-способом.

0 голосов
/ 08 апреля 2011

Я бы пошел с частичным представлением (например, "_Login.cshtml" или "_Login.ascx"), которое может быть помещено в MasterPage / _Layout. Внутри частичного представления вы пишете тег формы, который публикует действие на контроллере (скажем, «AuthController» и действие «LogIn»). Чтобы вспомнить, откуда вы пришли

Вот как могло бы выглядеть это действие:

public ActionResult LogIn(string username, string password) 
// name the id's of the form elements as the parameters
{
    if(YouAuthMethodHere(username, password))
    {
         return View("Welcome");
    }
    else
    {
         return Redirect(HttpContext.Current.Request.Referer.AbsolutUri);
    }
}

После успешной аутентификации пользователя возвращается представление с именем «Welcome.cshtml» / «Welcome.aspx», в противном случае оно перенаправляется из того места, где была отправлена ​​форма.

Примечание: реферер может быть нулевым (например, если не браузер, такой как fiddler или скрипт делает запрос), так что осталось немного обработки ошибок.

...