将 Json 对象从控制器操作返回到 jQuery [英] Returning Json object from controller action to jQuery

查看:19
本文介绍了将 Json 对象从控制器操作返回到 jQuery的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使其正常工作(现在是 2 天).我正在登录,我从 jQuery 调用控制器操作,向它传递一个 JSON 对象(使用 json2.js)并从控制器返回一个 Json 对象.我可以很好地调用该操作,但无法将响应放在我想要的位置,它只是打开一个新窗口,并在屏幕上打印:

{"Message":"无效的用户名/密码组合"}

并且 URL 看起来像 http://localhost:13719/Account/LogOn 所以不是调用操作而不是重新加载页面而是将用户带到控制器,这并不好.

那么现在对于一些代码,首先是控制器代码

[HttpPost]public ActionResult LogOn(LogOnModel 模型,字符串 returnUrl = ""){如果(模型状态.IsValid){var login = ObjectFactory.GetInstance>();var user = login.FindOne(x => x.Login == model.Username && x.Pwd == model.Password);如果(用户==空)return Json(new FailedLoginViewModel { Message = "无效的用户名/密码组合"});别的{如果 (!string.IsNullOrEmpty(returnUrl))返回重定向(returnUrl);别的return RedirectToAction("Index", "Home");}}return RedirectToAction("Index", "Home");}

和 jQuery 代码

$("#signin_submit").click(function () {var 登录 = getLogin();$.ajax({类型:POST",url: "../账户/登录",数据:JSON.stringify(登录),数据类型:'json',contentType: '应用程序/json;字符集=utf-8',错误:函数(xhr){$("#message").text(xhr.statusText);},成功:功能(结果){}});});函数 getLogin() {var un = $("#username").val();var pwd = $("#password").val();var rememberMe = $("#rememberme").val();返回 (un == "") ?null : { 用户名:un,密码:pwd,RememberMe:rememberMe };}

如果您还需要在此处查看实际的登录表单

<div><span id="message"></span>

<% 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.用户名,*")%><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="记住"><input id="signin_submit" value="登录" tabindex="6" type="submit"/><%= Html.CheckBoxFor(m => m.RememberMe, new { @class = "inputbox", @tabindex = "7", @id = "rememberme" })%><%=Html.LabelFor(m=>m.RememberMe)%><p class="忘记了"><a href="#" id="forgot_password_link" title="单击此处重置您的密码.">忘记密码?</a></p><p class="忘记用户名"><a href="#" id="forgot_username_link" title="忘记了您的登录名?我们可以提供帮助">忘记了您的用户名?</a></p></p><%= Html.ValidationSummaryJQuery("请修正以下错误.", new Dictionary { { "id", "valLogOnContainer" } })%><%}%></fieldset>

登录表单加载到主页上

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

不确定这是否与此有关,但我想我会提到它.

登录表单的加载类似于 Twitter 登录,单击一个链接,该表单将在 jQuery & 的帮助下加载.CSS

解决方案

想想@user350374 所说的关于让我的动作签名 JsonResult 而不是 ActionResult 我做了一些修补并修改了我的原始解决方案以利用 JsonResult 并在 jQuery 中而不是在动作中进行所有检查/重定向.

我的操作更改为

[HttpPost,MoveFormsScript]public JsonResult LogOn(LogOnModel 模型,字符串 returnUrl = ""){如果(模型状态.IsValid){var login = ObjectFactory.GetInstance>();var user = login.FindOne(x => x.Login == model.Username && x.Pwd == model.Password);如果(用户==空)return Json(new LoginResult { Success = false, Message = "Invalid login" });别的{返回 Json(新登录结果{成功=真,Message = "重定向...",ReturnUrl = (!string.IsNullOrEmpty(returnUrl)) ?returnUrl : string.Format("Account/Index/{0}", user.Photographer.Key)});}}别的{return Json(new LoginResultDTO { Success = false, Message = "Incomplete fields" });}}

还有我的 jQuery 调用

$("#signin_submit").click(function () {var f = $($("form")[0]);f.提交(函数(){var loginData = f.serialize();$.post(f.attr("action"), loginData, function (result, status) {如果(!结果.成功){$("#message").text(result.Message);$("#username").focus();$("#username").select();}别的 {window.location.replace(result.ReturnUrl);}}, "json");返回假;});});

LoginResult 是一个简单的类,只是为了保存部分

公共类 LoginResult{公共布尔成功{得到;放;}公共字符串消息 { 获取;放;}公共字符串 ReturnUrl { 获取;放;}}

感谢@user35037 的提示,现在我有两种方法可以解决这个问题.

I'm attempting to get this working properly (2 days now). I'm working on a log in where I'm calling the controller action from jQuery, passing it a JSON object (utilizing json2.js) and returning a Json object from the controller. I'm able to call the action fine, but instead of being able to put the response where I want it it just opens a new window with this printed on the screen:

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

And the URL looks like http://localhost:13719/Account/LogOn so instead of calling the action and not reloading the page it's taking the user to the controller, which isn't good.

So now for some code, first the controller code

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

And the jQuery code

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

In case you need to see the actual login form here that is as well

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

The login form is loaded on the main page with

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

Not sure if that has any bearing on this or not but thought I'd mention it.

EDIT: The login form is loaded similar to the Twitter login, click a link and the form loads with the help of jQuery & CSS

解决方案

Thinking about what @user350374 said about making the signature of my action JsonResult instead of ActionResult I did some tinkering and modified my original solution to utilize JsonResult and did all the checking/redirecting in jQuery instead of in the action.

My action changed to

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

}

And my jQuery call to

$("#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 is a simple class just to hold the parts

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

Thanks for the tip @user35037, now I have 2 ways to approach this in the future.

这篇关于将 Json 对象从控制器操作返回到 jQuery的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆