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

Короткая версия: нужен 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()
                return this.RedirectToAction<Areas.App.Controllers.HomeController>(x => x.Index());
            }
        else {
            return View();
        }
    }
    ...
}

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

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

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

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

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

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

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

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", в противном случае оно перенаправляется из того места, где была отправлена ​​форма.

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

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

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

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

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

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

Другие вопросы по тегам