使用json.stringify MVC3控制器空参数控制器、参数、json、stringify

2023-09-10 17:41:13 作者:半言半语半虚静/*

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

I have a very simple controller method that accepts a Guid parameter, like so

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

参数总是空使用JSON.stringify()在Chrome,IE和Firefox的时候。示例...

The parameter is always null when using JSON.stringify() in Chrome, IE and Firefox. Example...

$(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中工作过。什么是奇怪的是,在下列情况的工作。

This has worked before in ASP.NET 4.0. What is odd is that the following DOES work.

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

如果我跑......

If I run...

$(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。如果我跑

displayed, proper JSON. And if I run

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

如果GET

C21803C3-1385-462E-ACEA-AFA1E554C635

其他注意事项,

Additional notes,

我已经试过这是一个ajax后,同样的问题。的我想在有限的职位,但请参见下面的完整的工作虽然。的

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

I have tried to insert white space, as JSON.stringify(o, null, 2), same issue.

使用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是在一个jQuery对话框打开的窗体如果启动Javascript并创建一个可点击的表。

Using jquery-1.7.1.min.js, jquery-ui-1.8.16.custom.min.js, jquery.unobtrusive-ajax.js, jquery.validate.min.js, and jquery.validate.unobtrusive.min.js. The only other JS is to open forms in a jquery dialog if javascript is enabled and to create a clickable table.

$.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');
    }
});

以下不工作:

The following does NOT work:

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相当于

Thus, removing POST as type causes the call to fail. Note that according to jQuery documentation, $.getJSON is equivalent to

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

注意,没有定义的类型。不知道在哪里完全错误所在,但东西是越来越错过的地方。特别是因为通过在$ .getJSON实际JSON对象的实际工作。

Notice, there is not a type defined. Not sure where exactly the error lies, but something is getting missed somewhere. Especially since passing in an actual JSON object on $.getJSON actually works.

推荐答案

我觉得现在的问题是使用默认模式粘结剂忽略了最低接受GET方法传递直通查询字符串JSON。

I think that the problem is with the default model binder that dosen't accept GET methods passing JSON thru QueryString.

例如:

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

将生成此GET请求 GET 的http://本地主机 {%22id%22:%22test%22}?HTTP / 1.1

Will generate this GET request GET http://localhost?{%22id%22:%22test%22} HTTP/1.1

这似乎是ModelBinder的有问题绑定。 如果没有字符串化

Here it seems like the modelbinder have problem to bind it. Without stringify

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

将生成此GET请求 GET 的http://本地主机/ ID =测试 HTTP / 1.1

will generate this GET request GET http://localhost/?id=test HTTP/1.1

和它可能的MVC来绑定,职高它在相同的QueryString发送。 使用POST insted的将正常工作。

And its possible for MVC to bind it, couse its the same as sending it in QueryString. Using POST insted will work fine.

但你也可以实现定制绑定,也许这样的事情(我不知道究竟是如何做到这一点)

But you can also implement a custom binder, maybe something like this (I don't know exactly how to do this)

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
}