将 Json 对象从控制器操作返回到 jQuery

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4564341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 17:29:36  来源:igfitidea点击:

Returning Json object from controller action to jQuery

asp.net-mvcjsonjquerycontroller

提问by PsychoCoder

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:

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

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

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

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

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

和 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 };
}

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

编辑:登录表单的加载类似于 Twitter 登录,单击链接,表单将在 jQuery 和 CSS 的帮助下加载

采纳答案by PsychoCoder

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

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

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

我的 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;
    });
});

LoginResultis a simple class just to hold the parts

LoginResult是一个简单的类,只是为了保存零件

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.

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

回答by Baz1nga

Your action signature will look as follows:

您的操作签名将如下所示:

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

     return Json(abcObj);
}

回答by kerrubin

If you're using MVC 2, you have to return something like this :

如果您使用的是 MVC 2,则必须返回如下内容:

return Json(your_object, JsonRequestBehavior.AllowGet);

I've found it here

我在这里找到

For a different usage, here is my code.

对于不同的用法,这是我的代码。

JQuery :

查询:

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

And C#

和 C#

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

回答by PsychoCoder

Ok came up with a resolution that I thought I'd share here in case someone comes along with a simliar issue. Instead of using $.ajaxI switched to using $.postand changed my jQuery code to look like this and everything works just the way I initially expected it to:

好的,我想我会在这里分享一个解决方案,以防有人遇到类似的问题。我没有使用$.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;
    }); 
});

Thanks to all who looked at my question, and to @kerrubin as I was unaware of that issue.

感谢所有看了我的问题的人,感谢@kerrubin,因为我不知道这个问题。