Asp.net mvc 将Json对象从控制器操作返回到jQuery

Asp.net mvc 将Json对象从控制器操作返回到jQuery,asp.net-mvc,json,jquery,controller,Asp.net Mvc,Json,Jquery,Controller,我正试图让它正常工作(2天了)。我正在处理一个登录,从jQuery调用控制器操作,向它传递一个JSON对象(利用json2.js),并从控制器返回一个JSON对象。我可以将该操作称为罚款,但不是将响应放在我想要的位置,而是打开一个新窗口,在屏幕上打印以下内容: {"Message":"Invalid username/password combination"} URL看起来像http://localhost:13719/Account/LogOn 因此,它不是调用操作,也不是重新加载页面,而

我正试图让它正常工作(2天了)。我正在处理一个登录,从jQuery调用控制器操作,向它传递一个JSON对象(利用json2.js),并从控制器返回一个JSON对象。我可以将该操作称为罚款,但不是将响应放在我想要的位置,而是打开一个新窗口,在屏幕上打印以下内容:

{"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");
}
如果您需要在此处查看实际登录表单,也可以

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

m、 用户名)%%>
m、 用户名,新的{@class=“inputbox”、@tabindex=“4”、@id=“Username”}>m.Username,“*”>

m、 密码)%%>
m、 密码,新的{@class=“inputbox”、@tabindex=“5”、@id=“Password”}>m.密码,“*”%>

m、 RememberMe,新的{@class=“inputbox”、@tabindex=“7”、@id=“RememberMe”})%> m、 记住)%>

登录表单将加载到主页面上

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

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


编辑:登录表单的加载方式与Twitter登录方式类似,单击一个链接,在jQuery&CSS的帮助下加载表单

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

return Json(your_object, JsonRequestBehavior.AllowGet);
我找到了

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

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(字符串日期)
{
列表=新列表();
// [...]
返回Json(列表,JsonRequestBehavior.AllowGet);
}

好的,我想到了一个解决方案,我想在这里分享一下,以防有人提出类似的问题。我没有使用$.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,因为我不知道这个问题。

你的行动签名如下:

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

     return Json(abcObj);
}

考虑到@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" });
    }

}
LoginResult是一个简单的类,仅用于保存部件

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

感谢@user35037的提示,现在我有两种方法可以在将来实现这一点。

谢谢提示,但是我把它作为ActionResult,因为如果它是一个有效的登录名,那么我会重定向到一个视图。你可以从服务器返回任何一种类型,我认为Json是最好的,因为你可以将你的部分视图序列化为Json,并将其发送回客户端,并且可能会在Json中附加一个isValid属性,你可以根据它选择wat在服务器上渲染如果这不是你不想考虑的事情,如果用户登录成功,则触发另一个调用FRM JS的部分。view@psycho我也有同样的问题。除了当通过jQuery调用重定向为ActionResult时无法工作这一事实之外,您的第一个代码返回“json文件”的主要原因是您没有让
返回false[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" });
    }

}
$("#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;
    });
});
public class LoginResult
{
    public bool Success { get; set; }
    public string Message { get; set; }
    public string ReturnUrl { get; set; }
}