2010-12-30 2 views
12

Я пытаюсь заставить это работать правильно (2 дня). Я работаю над журналом, где я вызываю действие контроллера из jQuery, передавая ему объект JSON (используя json2.js) и возвращаю объект Json из контроллера. Я могу назвать штраф действий, но вместо того, чтобы быть в состоянии поставить ответ, где я хочу это он просто открывает новое окно с этим выводится на экран:Возврат объекта Json от действия контроллера к jQuery

{"Message":"Invalid username/password combination"} 

И URL выглядит HTTP : // localhost: 13719/Account/LogOn, поэтому вместо вызова действия и не перезагрузки страницы он берет пользователя на контроллер, что не очень хорошо.

Так что теперь для некоторого кода, первый код контроллера

[HttpPost] 
public ActionResult LogOn(LogOnModel model, string returnUrl = "") 
{ 
    if (ModelState.IsValid) 
    { 
     var login = ObjectFactory.GetInstance<IRepository<PhotographerLogin>>(); 

     var user = login.FindOne(x => x.Login == model.Username && x.Pwd == model.Password); 

     if (user == null) 
      return Json(new FailedLoginViewModel { Message = "Invalid username/password combination" }); 
     else 
     { 
      if (!string.IsNullOrEmpty(returnUrl)) 
       return Redirect(returnUrl); 
      else 
       return RedirectToAction("Index", "Home"); 
     } 
    } 
    return RedirectToAction("Index", "Home"); 
} 

И код JQuery

$("#signin_submit").click(function() { 
    var login = getLogin(); 
    $.ajax({ 
     type: "POST", 
     url: "../Account/LogOn", 
     data: JSON.stringify(login), 
     dataType: 'json', 
     contentType: 'application/json; charset=utf-8', 
     error: function (xhr) { 
      $("#message").text(xhr.statusText); 
     }, 
     success: function (result) { 

     } 
    }); 
}); 

function getLogin() { 
    var un = $("#username").val(); 
    var pwd = $("#password").val(); 
    var rememberMe = $("#rememberme").val(); 

    return (un == "") ? null : { Username: un, Password: pwd, RememberMe: rememberMe }; 
} 

В случае, если вам нужно, чтобы увидеть реальную форму входа здесь как хорошо

<fieldset id="signin_menu"> 
    <div> 
     <span id="message"></span> 
    </div> 
    <% Html.EnableClientValidation(); %>  
    <% using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { @id = "signin" })) 
     {%> 

     <% ViewContext.FormContext.ValidationSummaryId = "valLogOnContainer"; %> 
     <%= Html.LabelFor(m => m.Username) %> 
     <%= Html.TextBoxFor(m => m.Username, new { @class = "inputbox", @tabindex = "4", @id = "username" })%><%= Html.ValidationMessageFor(m => m.Username, "*")%> 
     <p> 
     <%= Html.LabelFor(m=>m.Password) %> 
     <%= Html.PasswordFor(m => m.Password, new { @class = "inputbox", @tabindex = "5", @id = "password" })%><%= Html.ValidationMessageFor(m => m.Password, "*")%> 
     </p> 
     <p class="remember"> 
     <input id="signin_submit" value="Sign in" tabindex="6" type="submit"/> 
     <%= Html.CheckBoxFor(m => m.RememberMe, new { @class = "inputbox", @tabindex = "7", @id = "rememberme" })%> 
     <%= Html.LabelFor(m => m.RememberMe) %> 
     <p class="forgot"> <a href="#" id="forgot_password_link" title="Click here to reset your password.">Forgot your password?</a> </p> 
     <p class="forgot-username"> <a href="#" id="forgot_username_link" title="Fogot your login name? We can help with that">Forgot your username?</a> </p> 
     </p> 
     <%= Html.ValidationSummaryJQuery("Please fix the following errors.", new Dictionary<string, object> { { "id", "valLogOnContainer" } })%> 
    <% } %> 
</fieldset> 

Форма входа для загрузки на основной странице:

<% Html.RenderPartial("LogonControl");%> 

Не уверен, что это имеет какое-либо отношение к этому или нет, но я думал, что упомянул об этом.

EDIT: Форма Войти загружается похожа на входе в систему Twitter, нажмите на ссылку и форму нагрузки с помощью JQuery & CSS

ответ

2

Думая о том, что @ user350374 сказал о том, чтобы подпись моих действий JsonResult вместо ActionResult Я сделал несколько попыток и изменить мое первоначальное решение используйте JsonResult и выполнили все проверки/перенаправления в jQuery, а не в действии.

Мои действия изменено на

[HttpPost,MoveFormsScript] 
public JsonResult LogOn(LogOnModel model, string returnUrl = "") 
{ 
    if (ModelState.IsValid) 
    { 
     var login = ObjectFactory.GetInstance<IRepository<PhotographerLogin>>(); 

     var user = login.FindOne(x => x.Login == model.Username && x.Pwd == model.Password); 

     if (user == null) 
      return Json(new LoginResult { Success = false, Message = "Invalid login" }); 
     else 
     { 
      return Json(new LoginResult 
      { 
       Success = true, 
       Message = "Redirecting...", 
       ReturnUrl = (!string.IsNullOrEmpty(returnUrl)) ? returnUrl : string.Format("Account/Index/{0}", user.Photographer.Key) 
      }); 
     } 
    } 
    else 
    { 
     return Json(new LoginResultDTO { Success = false, Message = "Incomplete fields" }); 
    } 

} 

И мой призыв JQuery к

$("#signin_submit").click(function() { 
    var f = $($("form")[0]); 
    f.submit(function() { 
     var loginData = f.serialize(); 
     $.post(f.attr("action"), loginData, function (result, status) { 
      if (!result.Success) { 
       $("#message").text(result.Message); 

       $("#username").focus(); 
       $("#username").select(); 
      } 
      else { 
       window.location.replace(result.ReturnUrl); 
      } 

     }, "json"); 
     return false; 
    }); 
}); 

LoginResult простой класс, просто держать детали

public class LoginResult 
{ 
    public bool Success { get; set; } 
    public string Message { get; set; } 
    public string ReturnUrl { get; set; } 
} 

Спасибо за отзыв @ user35037, теперь у меня есть 2 способа приблизиться к этому в будущее.

+0

мое удовольствие. и спасибо за сообщение подробного решения. – Baz1nga

+0

@psycho У меня была такая же проблема здесь. Помимо того факта, что перенаправление как ActionResult не будет работать при вызове через jQuery, основная причина, по которой ваш первый код возвращал «json-файл», состоит в том, что вы не получили «return false» в функции отправки, возвращая JSON как «файл». –

9

Если вы используете MVC 2, вы должны вернуть что-то как это:

return Json(your_object, JsonRequestBehavior.AllowGet); 

Я нашел это here

Для другого использования, вот мой код.

JQuery:

$(document).ready(function() { 
    $("#InputDate").live('click', function() { 
     var date = $("#InputDate").val(); 
     if (date != "") { 
      $.getJSON("/Home/GetNames", 
        { date: $("#InputDate").val() }, 
        function (data) { 
         $("#ProviderName").empty(); 
         // [...] 
         }); 
        }); 
     } 
    }); 
}); 

И C#

public JsonResult GetNames(string date) 
{ 
    List<Provider> list = new List<Provider>(); 
    // [...] 
    return Json(list, JsonRequestBehavior.AllowGet); 
} 
+1

Спасибо Керрубин, это не только для MVC2, но и для MVC 3,4 и 5 –

2

Хорошо придумали с разрешением, что я думал, что я поделюсь здесь в случае, если кто-то приходит с simliar вопросом. Вместо того чтобы использовать $ .ajax Я перешел на использование $ .post и изменил код JQuery, чтобы посмотреть, как это и все работает именно так, как я изначально ожидал, что это:

$("#signin_submit").click(function() { 
    var f = $($("form")[0]); 
    f.submit(function() { 
     var loginData = f.serialize(); 
     $.post(f.attr("action"), loginData, function (result, status) { 
      if (!result.Success) { 
       $("#message").text(result.Message); 
      } 
     }, "json"); 
     return false; 
    }); 
}); 

Спасибо всем, кто смотрел на мой вопрос, и на @kerrubin, поскольку я не знал об этом вопросе.

12

Ваше действие подпись будет выглядеть следующим образом:

public virtual JsonResult ActionName() 
{ 
    var abcObj = new ABC{a=1,b=2}; 

    return Json(abcObj); 
} 
+0

Спасибо за подсказку, но у меня это как _ActionResult_, потому что, если это действительный логин, я перенаправляю на представление. – PsychoCoder

+0

WEEL вы можете вернуть какой-либо один тип с сервера, и я думаю, что Json - это лучшее, потому что вы можете сериализовать ур частично в виде json и отправить его клиенту и, вероятно, добавить свойство isValid в json, на основе которого вы выбираете wat для отображения на странице. – Baz1nga

+0

Также, если это не то, что вы не хотите рассматривать, что вы можете сделать, это если логин пользователя успешно активирует другой вызов frm js, который получает частичное представление – Baz1nga