Форма входа jQuery ajax с asp.net mvc

#jquery #ajax #asp.net-mvc-3

#jquery #ajax #asp.net-mvc-3

Вопрос:

У меня есть простая форма входа в моем приложении MVC (обратите внимание, что я не использую встроенную), которая выглядит примерно так:

 @using (Html.BeginForm())
{
    <label for="UserName" class="placeholder">Email address or username</label>
    @Html.TextBoxFor(m => m.UserName)

    <label for="Password" class="placeholder">Password</label>
    @Html.PasswordFor(m => m.Password)

    <button type="submit" title="Log in">Log in amp;#9658;</button>
}
  

У меня есть некоторый jquery, который должен отправлять данные с помощью ajax. Если пользователь указан правильно, отправьте его на правильную страницу, в противном случае отобразится ошибка. Однако я испытываю трудности. Может ли кто-нибудь указать мне правильное направление, поскольку в настоящее время я также получаю успех, даже если данные учетной записи неверны, и я потерял функцию перенаправления при успешном входе в систему из-за preventdefault.

 $('form').live('submit', function (event) {

                    // Stop the form from doing a native postback
                    event.preventDefault();

                    $.ajax({
                        type: 'POST',
                        timeout: 5000,
                        url: $(this).attr('action'),
                        data: $('form').serialize(),
                        success: function (responseHtml) {
                            // what goes here... as the form is always successful even if the account details are incorrect
                        },
                        error: function (jqXHR, textStatus, errorThrown) {

                            alert('error');
                        }
                    });
                });
  

C#

 [HttpGet]
public ActionResult Login()
{
    if (Session["UserID"] != null)
    {
        return RedirectToAction("Index", "Home", new { area = "Dashboard" });
    }

    return View();
}

[HttpPost]
public ActionResult Login(User user, string returnUrl)
{
    // Validate the email and password
    if (users.Login(user.UserName, user.Password, Request.UserHostAddress))
    {
        FormsAuthentication.SetAuthCookie(user.UserName, true);

        if (Url.IsLocalUrl(returnUrl) amp;amp; returnUrl.Length > 1 amp;amp; returnUrl.StartsWith("/")
            amp;amp; !returnUrl.StartsWith("//") amp;amp; !returnUrl.StartsWith("/\"))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Home", new { area = "Dashboard" });
        }
    }
    else
    {
        return View();
    }
}
  

Комментарии:

1. 1 в этом вопросе нет ничего плохого

Ответ №1:

Ваше действие должно возвращать данные, а не html, потому что вы хотите использовать результат при обратном вызове javascript,

Например, вы можете вернуть объект json с uservalidated таким свойством, как это:

 [HttpPost]
public JsonResult Login(User user, string returnUrl)
{
    // Validate the email and password
    if (users.Login(user.UserName, user.Password, Request.UserHostAddress))
    {
        FormsAuthentication.SetAuthCookie(user.UserName, true);

        // build redirectUrl ...
        var redirUrl = ...
        return Json(new { uservalidated = true, url = redirUrl });
    }
    else
    {
        return Json (new { uservalidated = false, url = null });
    }
}
  

Ваш вызов ajax имеет два обратных вызова. Обратный вызов с ошибкой предназначен только для случая, когда вызов ajax по какой-либо причине идет неправильно.

Независимо от того, предоставил пользователь правильные учетные данные или нет, вы всегда будете возвращаться к своему успешному обратному вызову, потому что сам вызов ajax не должен завершаться ошибкой.

Редактировать:

Хорошо, из комментариев, которые я интерполирую, вы хотите, чтобы ваш метод action работал с включенным javascript и без него.

У вас есть две возможности:

  • Используйте два метода действия — один возвращает JsonResult, другой возвращает ActionResult
  • Используйте метод one action, который автоматически определяет, соответствует его запросу ajax или нет, и возвращает полный просмотр / перенаправление или данные JSON при вызове через ajax.

Это пример для последнего:

 [HttpPost]
public ActionResult Login(User user, string returnUrl)
{
    // do login logic like shown above.
    bool userAuthenticated = ...
    string redirectUrl = ...

    if (Request.IsAjaxRequest()) {
        return Json(new { userAuthenticated = userAuthenticated, url = redirectUrl });
    }
    else {
        return Redirect(redirectUrl);
    }        
}
  

Последняя часть посвящена тому, как использовать возвращенные данные JSON в вашем коде javascript. Вы можете получить к ней доступ при успешном обратном вызове следующим образом:

 $.ajax({
    ...
    success: function (data) {
                 if (data.userAuthenticated) {
                     window.location.href = data.url;
                 } else {
                     // show some fancy invalid credentials message...
                 }
             },
    ...
  

Комментарии:

1. Я бы сказал, что это uservalidated более семантическое имя переменной, чем success для ответа JSON, особенно когда вы собираетесь вводить его в success обработчик запроса ajax, но 1 независимо от этого, поскольку это будет работать идеально.

2. Ну, это все еще должно быть ActionResult на случай, если у них отключен JS!

3. Когда у них включен js, ваш ajax-вызов никогда не достигнет сервера. Метод action возвращает просто JsonResult, поэтому нет необходимости указывать ActionResult в качестве возвращаемого типа.

4. Однако это не сработает, потому что, если пользователь отключил JS, он просто получит возврат JSON и ничего не сможет с этим сделать! Следовательно, почему я хочу использовать ActionResult!

5. И как бы я использовал данные JSON?

Ответ №2:

События успеха и сбоя ajax-вызова относятся к статусу самого ajax-вызова. Если вызов завершен, но пользователь был недопустимым, что касается вызова ajax, то он прошел успешно.

В контроллере, на который отправляется этот ajax, вам необходимо вернуть флаг, в каком формате вы предпочитаете (текст, xml, json), чтобы указать, был ли вход в систему успешным.

Затем вы сможете получить доступ к этому значению в своей функции успеха, поскольку оно передается в качестве responseHtml переменной. Если этот флаг показывает, что вход был правильным, вы можете перенаправить с помощью location.assign("page.aspx") в нужное место.

Комментарии:

1. @Cameron Смотрите ответ Яна, поскольку он поместил его туда.