2010-12-30 12 views
12

Próbuję uruchomić to poprawnie (2 dni). Pracuję nad logowaniem, w którym wywołuję działanie kontrolera z jQuery, przekazując mu obiekt JSON (wykorzystujący json2.js) i zwracając obiekt Json z kontrolera. Jestem w stanie wywołać grzywnę działania, ale zamiast być w stanie umieścić odpowiedź, gdzie chcę go po prostu otwiera nowe okno z tym drukowane na ekranie:Powracanie obiektu Json z akcji kontrolera do jQuery

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

A URL wygląda http : // localhost: 13719/Account/LogOn, więc zamiast wywoływać akcję i nie przeładowywać strony, przenosimy użytkownika do kontrolera, co nie jest dobre.

Więc teraz przez jakiś kod, najpierw kod kontrolera

[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"); 
} 

a kod 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 }; 
} 

w przypadku trzeba zobaczyć rzeczywisty formularz logowania tutaj, że jest tak dobrze

<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> 

Formularz logowania jest ładowany na stronę główną za pomocą

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

Nie jestem pewien, czy to ma jakikolwiek wpływ na to, czy nie, ale pomyślałem, że wspomnę o tym.

EDIT: Formularz logowania jest załadowany podobny do logowania Twitter, kliknij link i obciążeń tworzyć z pomocą jQuery & CSS

Odpowiedz

2

Myśląc o tym, co @ user350374 powiedział o co podpis mojego działania JsonResult zamiast ActionResult Zrobiłem trochę majsterkowania i modyfikowane moje oryginalne rozwiązanie wykorzystać JsonResult i zrobiłem wszystkie sprawdzanie/przekierowanie w jQuery zamiast w akcji.

Moje działanie zmienione na

[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" }); 
    } 

} 

I moje wezwanie 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 to prosta klasa po prostu trzymać części

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

Dzięki za cynk @ user35037, teraz mam 2 sposoby podejścia do tego w przyszłość.

+0

mojej przyjemności. i tak dzięki za ogłoszenie szczegółowe rozwiązanie .. – Baz1nga

+0

@psycho Miałem ten sam problem tutaj. Poza tym, że przekierowanie jako ActionResult nie zadziała, gdy zostanie wywołane przez jQuery, głównym powodem, dla którego twój pierwszy kod zwrócił "plik json", jest to, że nie masz 'return false;' w funkcji submit, więc zwrócenie JSON jako "pliku". –

9

Jeśli używasz MVC 2, masz coś do powrotu tak:

return Json(your_object, JsonRequestBehavior.AllowGet); 

Znalazłem to here

Dla innego użytku, tutaj jest mój kod.

JQuery:

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

i C#

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

Dziękuję Kerrubin, Jest to nie tylko dla MVC2, To jest dla MVC 3,4 i 5 –

2

Ok wymyślił uchwały, że pomyślałem, że podzielę się tutaj w przypadku gdy ktoś przychodzi wraz z simliar kwestii. Zamiast używać $ .ajax przeszedłem do korzystania $ .post i zmieniłem kod jQuery aby wyglądać i wszystko działa tak, jak ja początkowo spodziewałem się, że:

$("#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; 
    }); 
}); 

Dziękujemy wszystkim, którzy wyglądał na moje pytanie i na @kerrubin, ponieważ nie wiedziałem o tym problemie.

12

Twój podpis akcja będzie wyglądać następująco:

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

    return Json(abcObj); 
} 
+0

Dzięki za napiwek, ale mam to jako _ActionResult_, ponieważ jeśli jest to ważny login, to przekierowuję do widoku. – PsychoCoder

+0

WEB można zwrócić dowolny typ z serwera prawym i myślę, że Json jest najlepszy, możesz serializować ur częściowy widok jako json i wysłać go z powrotem do klienta i prawdopodobnie dołączyć właściwość isValid do json na podstawie którego wybierzesz wat renderować na stronie. – Baz1nga

+0

Również, jeśli nie jest to coś, co nie chcesz wziąć pod uwagę, co możesz zrobić, to jeśli użytkownik z powodzeniem loguje się do innego wywołania frm js, który dostaje częściowy widok – Baz1nga

Powiązane problemy