使用json.stringify的MVC3 Controller null参数

时间:2012-02-06 15:20:38

标签: jquery ajax json asp.net-mvc-3

我有一个非常简单的控制器方法,它接受一个Guid参数,就像这样

public JsonResult GetById(Guid id)
{
    var results = from a in repository.AsQueryable<Department>()
                  where a.Id == id
                  orderby a.Name
                  select new { id = a.Id, name = a.Name };

    return Json(results, JsonRequestBehavior.AllowGet);
}

在Chrome,IE和Firefox中使用JSON.stringify()时,参数始终为null。实施例...

$(document).ready(function () {
    var o = new Object();
    o.id = 'C21803C3-1385-462E-ACEA-AFA1E554C635';

    $.getJSON('@Url.Action("GetById", "User")', JSON.stringify(o), function () {
        alert('Completed');
    });
});

这在ASP.NET 4.0中已经有用了。奇怪的是,以下内容有效。

$(document).ready(function () {
    $.getJSON('@Url.Action("GetById", "User")', { "id": "C21803C3-1385-462E-ACEA-AFA1E554C635" }, function () {
        alert('Completed');
    })
    .error(function (a, b, c) {
        alert(a.responseText); alert(b); alert(c);
    });
});

如果我跑......

$(document).ready(function () {
    var o = new Object();
    o.id = 'C21803C3-1385-462E-ACEA-AFA1E554C635';

    alert(JSON.stringify(o));
});

我得到了

{"id":"C21803C3-1385-462E-ACEA-AFA1E554C635"}

显示,正确的JSON。如果我跑

$(document).ready(function () {
    var o = new Object();
    o.id = 'C21803C3-1385-462E-ACEA-AFA1E554C635';

    var json_text = JSON.stringify(o, null, 2);
    alert(json_text);

    var your_object = JSON.parse(json_text);

    alert(your_object.id);
});

如果获得

C21803C3-1385-462E-ACEA-AFA1E554C635

补充说明,

我已经尝试过这个作为ajax帖子,同样的问题。 我尝试了一个有限的帖子,但是看看下面的完整作品。

我试图插入空格,如JSON.stringify(o,null,2),同样的问题。

使用jquery-1.7.1.min.js,jquery-ui-1.8.16.custom.min.js,jquery.unobtrusive-ajax.js,jquery.validate.min.js和jquery.validate.unobtrusive .min.js。唯一的其他JS是如果启用了javascript,则在jquery对话框中打开表单并创建可点击的表。

$.ajaxSetup({ cache: false });

$(document).ready(function () {
    $(".openDialog").live("click", function (e) {
        e.preventDefault();

        $("<div></div>")
                .addClass("dialog")
                .attr("id", $(this).attr("data-dialog-id"))
                .appendTo("body")
                .dialog({
                    title: $(this).attr("data-dialog-title"),
                    close: function () { $(this).remove() },
                    modal: true
                })
                .load(this.href);
    });

    $(".close").live("click", function (e) {
        e.preventDefault();
        $(this).closest(".dialog").dialog("close");
    });



    var clickableTable = $('tr[data-tr-clickable-url]');

    if (clickableTable.length > 0) {
        clickableTable.addClass('clickable')   // Add the clickable class for mouse over
            .click(function () {
                window.location.href = $(this).attr('data-tr-clickable-url');
            });

        // Remove the last child, containing anchors to actions, from each row, including the header.
        $('tr :last-child').remove();
    }
});

更新

以下作品:

var o = new Object();
o.Id = 'C21803C3-1385-462E-ACEA-AFA1E554C635';

$.ajax({
    url: '@Url.Action("GetById", "User")',
    type: "POST",
    data: JSON.stringify(o),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function () {
        alert('completed');
    }
});

以下不起作用:

var o = new Object();
o.Id = 'C21803C3-1385-462E-ACEA-AFA1E554C635';

$.ajax({
    url: '@Url.Action("GetById", "User")',
    data: JSON.stringify(o),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function () {
        alert('completed');
    }
});

因此,删除POST类型会导致调用失败。请注意,根据jQuery文档,$ .getJSON等同于

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

注意,没有定义类型。不确定错误的确切位置,但某些地方有些遗漏。特别是因为传入$ .getJSON上的实际JSON对象实际上是有效的。

2 个答案:

答案 0 :(得分:2)

我认为问题在于默认模型绑定器不接受通过QueryString传递JSON的GET方法。

例如:

         $.getJSON('/', JSON.stringify({id:"test"}));

将生成此GET请求 GET http://localhost?{%22id%22:%22test%22} HTTP / 1.1

这里似乎模型绑定器有绑定它的问题。 没有stringify

         $.getJSON('/', {id:"test"});

将生成此GET请求 获取http://localhost/?id=test HTTP / 1.1

它可以让MVC绑定它,就像在QueryString中发送它一样。 使用POST insted将正常工作。

但你也可以实现一个自定义绑定器,可能是这样的(我不知道该怎么做)

public class Binder : IModelBinder
{
    #region IModelBinder Members

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var query = controllerContext.HttpContext.Request.Url.Query;
        var json = System.Web.HttpUtility.UrlDecode(query.Remove(0,1));
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        return serializer.Deserialize(json, bindingContext.ModelType.GetType());
    }

    #endregion
}

答案 1 :(得分:0)

我认为错误的是,你试图 stringify o对象,而你想要传递的id是在o对象内,而不是在o对象本身。

所以试试这段代码

$.getJSON('@Url.Action("GetById", "User")', JSON.stringify(o.id), function () {
    alert('Completed');
});