Ответ 1
Вероятно, вы хотите использовать свойство TempData
, это будет сохраняться до следующего HTTP-запроса.
У меня есть окно входа в мой MasterPage. Всякий раз, когда данные входа неверны, я оцениваю ViewData["loginError"]
, чтобы показать сообщение об ошибке пользователю.
Вход - это действие UserController, поэтому форма, содержащая логин, имеет action = "/User/Login"
.
Как пользователь может попытаться войти в систему с любой страницы, в случае успеха я перенаправляю его на личную страницу, но в случае ошибки я хочу, чтобы он остался на той же странице, где он пытался войти. Я обнаружил, что это работает:
return Redirect(Request.UrlReferrer.ToString());
но кажется, что, поскольку я не возвращаю надлежащее представление, данные в ViewData теряются, поэтому я не могу показать сообщение об ошибке.
Любое предложение о том, как решить эту и подобные проблемы?
Спасибо
Вероятно, вы хотите использовать свойство TempData
, это будет сохраняться до следующего HTTP-запроса.
Почему бы не обработать логин через AJAX вместо полного сообщения? Вы можете легко предоставить статус, URL-адрес перенаправления и любые сообщения об ошибках через JSON.
public ActionResult Logon( string username, string password )
{
...
// Handle master page login
if (Request.IsAjaxRequest())
{
if (success)
{
return Json( new { Status = true, Url = Url.Action( "Index", "Home" ) } );
}
else
{
return Json( new { Status = false, Message = ... } );
}
}
else // handle login page logon or no javascript
{
if (success)
{
return RedirectToAction( "Index", "Home" );
}
else
{
ViewData["error"] = ...
return View("Logon");
}
}
}
Клиентская сторона
$(function() {
$('#loginForm input[type=submit]').click( function() {
$('#loginError').html('');
$.ajax({
url: '<%= Url.Action("Logon","Account") %>',
dataType: 'json',
type: 'post',
data: function() { return $('#loginForm').serialize(); },
success: function(data,status) {
if (data.Status) {
location.href = data.Url;
}
else {
$('#loginError').html( data.Message );
}
}
});
return false;
});
});
Обычно для большинства веб-сайтов, когда пользователь не может пройти аутентификацию (из-за пароля или так), он перейдет на другую страницу, которая поможет пользователю (например, восстановить пароль или попросить пользователя зарегистрироваться), что редко встречается Оставайтесь на той же странице. Я думаю, вы можете подумать, что вам действительно нужна навигационная система, которую вы используете.
ОК, одно решение, если вы действительно хотите придерживаться своей модели, заключается в том, что вы можете прикрепить ошибку входа в URL. Например, http://www.example.com/index.aspx?login_error=1 указывает на эту ошибку, и вы можете использовать BEGIN_REQUEST (или HTTP-модуль), чтобы зафиксировать это, и сообщить состояние модели об ошибке:
ModelState.AddModelError(...);
BTW, добавление ошибки модели на самом деле является более правильным способом информировать представление о любой ошибке, а не использовать ViewState (это похоже на исключение throw и исключение целого числа результата выполнения в старые времена).
При использовании AJAX для входа в систему (как предложено tvanfosson) вполне достижимо и иногда превосходит пользовательский интерфейс, классическая полноценная запись все еще невосприимчива (подумайте, что какой-то пользователь отключит javascript или даже на моей дампе WM6-телефоне, t поддержка javascript).
Я в замешательстве. Не
return View();
просто верните текущую страницу назад?
Итак, в вашем случае, когда логин завершается с ошибкой, установите ваши viewdata и вызовите return View();
то есть.
if (!FailedLogin) {
//Go to success page
}else{
//Add error to View Data or use ModelState to add error
return View();
}
Используете ли вы [Authorize] декоратор? Автоматическая процедура входа в систему MVC запрашивает страницу входа в систему, а затем возвращает вас к действию контроллера, которое вы пытались выполнить. Сокращает много перенаправлений.
Следующий пример, надеюсь, поможет вам решить эту проблему:
View.aspx
<%= Html.ValidationSummary("Login was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) { %>
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
<%= Html.TextBox("username") %>
<%= Html.ValidationMessage("username") %>
</p>
<p>
<label for="password">Password:</label>
<%= Html.Password("password") %>
<%= Html.ValidationMessage("password") %>
</p>
<p>
<%= Html.CheckBox("rememberMe") %> <label class="inline" for="rememberMe">Remember me?</label>
</p>
<p>
<input type="submit" value="Log On" />
</p>
</fieldset>
</div>
<% } %>
AccountController.cs
private bool ValidateLogOn(string userName, string password)
{
if (String.IsNullOrEmpty(userName))
{
ModelState.AddModelError("username", "You must specify a username.");
}
if (String.IsNullOrEmpty(password))
{
ModelState.AddModelError("password", "You must specify a password.");
}
if (!MembershipService.ValidateUser(userName, password))
{
ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
}
return ModelState.IsValid;
}
Вы не сможете захватить информацию, добавленную в ViewData после действия Redirect. поэтому правильный подход заключается в том, чтобы вернуть тот же View() и использовать ModelState для ошибок, как упоминалось также "xandy".
Надеюсь, что это дало бы начало с проверкой формы.