Название может быть не таким ясным (потому что я не мог найти лучшего), но я пытаюсь понять, когда у вас есть нормальное (в отличие от частичного) представление, обычно есть метод действия GET который просто отображает представление с новым экземпляром модели представления и методом действия POST (обычно с тем же именем), который принимает экземпляр модели представления в качестве параметра. Внутри метода действия POST вы проверяете ModelState, действительно ли вы делаете то, что должны делать, если не визуализируете представление снова с тем же экземпляром модели представления, чтобы отобразить любые ошибки.
Это действительно одна из вещей, которые мне действительно нравятся в ASP.NET MVC, но как это работает с частичными представлениями? Если я рендеринг частичного представления с экземпляром модели представления, он отображает только частичное представление с белым фоном, вне контекста всего веб-приложения. И если я отправляю обратно обычный View, передавая экземпляр модели представления, это вызывает StackOverflowException.
Вот пример:
public ActionResult Login()
{
return PartialView(new LoginViewModel());
}
[HttpPost]
public ActionResult Login(LoginViewModel dto)
{
bool flag = false;
if (ModelState.IsValid)
{
if (_userService.AuthenticateUser(dto.Email, dto.Password, false)) {
var user = _userService.GetUserByEmail(dto.Email);
var uSession = new UserSession
{
ID = user.Id,
Nickname = user.Nickname
};
SessionManager.RegisterSession(SessionKeys.User, uSession);
flag = true;
if(dto.RememberMe)
{
_appCookies.Email = dto.Email;
_appCookies.Password = dto.Password;
}
}
}
if (flag)
return RedirectToAction("Index", "Home");
else
{
ViewData.Add("InvalidLogin", "The login info you provided were incorrect.");
return View(dto); //causes a StackOverflowException
}
}
ОБНОВЛЕНИЕ: Вот логин:
@inherits ModelWebViewPage<Sharwe.MVC.ViewModels.LoginViewModel>
<div class="userFormHeader"><h2>Login</h2></div>
<div id="loginBox">
@using(Html.BeginForm("Login", "User", FormMethod.Post))
{
@Html.ValidationSummary(true)
<div id="loginFormFields">
<div class="display-field">@this.TextBox(m => m.Email).Class("emailField").Attr("rel", "email").Class("autoText")</div>
<div class="display-field">@this.TextBox(m => m.Password).Class("passwordField").Attr("rel", "password").Class("autoText")</div>
<div>@this.CheckBox(m => m.RememberMe) <span class="smallText">remember me</span></div>
</div>
<div id="loginFormActions">
<div><input type="submit" id="loginSubmit" class="okButton" name="loginSubmit" value="Ok" /></div>
<div> @this.Html.ActionLink("forgot password", "ForgotPassword", "User", new { @class = "verySmallText" } )</div>
</div>
}
</div>
Так как мне это сделать? Какие-либо предложения?
ОБНОВЛЕНИЕ: (после ответа Дарина)
Вот как теперь выглядит мой метод действий при входе:
[HttpPost]
public ActionResult Login(LoginViewModel dto)
{
bool flag = false;
if (ModelState.IsValid)
{
if (_userService.AuthenticateUser(dto.Email, dto.Password, false))
{
var user = _userService.GetUserByEmail(dto.Email);
var uSession = new UserSession
{
ID = user.Id,
Nickname = user.Nickname
};
SessionManager.RegisterSession(SessionKeys.User, uSession);
flag = true;
if (dto.RememberMe)
{
//create the authentication ticket
var authTicket = new FormsAuthenticationTicket(
1,
user.Id.ToString(), //user id
DateTime.Now,
DateTime.Now.AddMinutes(20), // expiry
true, //true to remember
"", //roles
"/"
);
//encrypt the ticket and add it to a cookie
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(cookie);
}
}
}
if (flag)
{
return Json(new { redirectTo = Url.Action("Index", "Home") });
}
else
{
ViewData.Add("InvalidLogin", "The login info you provided were incorrect.");
return PartialView(dto);
}
}