Как инкапсулировать форму / сообщение / проверку [/ перенаправление] в ViewUserControl в ASP.Net MVC 2

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

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

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

Подробная информация о том, чего я пытаюсь достичь:

  • инкапсулировать форму входа (или любую другую) для повторного использования на сайте
  • отправить себе
  • при сбое входа / проверки показать исходную страницу со сводкой проверки
    • (some might argue to just post to Login Page and show Validation Summary there; if what I'm trying to achieve isn't possible, I will just go that route)
  • при успешном входе в систему перенаправьте в / App / Home / Index
  • также хочу:
    • stick to PRG principles
    • avoid ajax
    • keep Login Form (UserController.Login()) as encapsulated as possible; avoid having to implement HomeController.Login() since the Login Form might appear elsewhere

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

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

Отлично работает, когда: ModelState или User Credentials не работают - return View () уступает Home / Index и отображает соответствующую сводку проверки.

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

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

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

Кстати, работает: ASP.Net 4, MVC 2, VS 2010, веб-сервер для разработки / отладки

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

Итак, какие у меня варианты? Или где я ошибаюсь в своем подходе? тиа!


person paul    schedule 28.05.2010    source источник
comment
эти два других сообщения касаются связанных проблем, но решения не работали или не соответствовали моим критериям (если это вообще возможно): stackoverflow.com/questions/ 2056421 / stackoverflow.com/ вопросы / 2022182 /   -  person paul    schedule 28.05.2010


Ответы (2)


Я бы выбрал частичный вид (например, «_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», в противном случае перенаправленное с того места, где была отправлена ​​форма.

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

person Daniel Fisher lennybacon    schedule 08.04.2011

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

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

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

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

Публикуя его, потому что он работает, он поддерживает инкапсуляцию, и это немного менее ужасно, чем решение return-a-view-contain-a-Javascript-redirect, которое я видел, но я все же хотел бы получить лучшее представление о том, как этого добиться. вид упаковки более MVC-способом.

person Whelkaholism    schedule 16.06.2014