使用json.stringify的MVC3 Controller null参数

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

public JsonResult GetById(Guid id) { var results = from a in repository.AsQueryable() 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 

补充说明,

我试过这个作为ajaxpost,同样的问题。 我尝试了一个有限的post,但是请看下面的完整作品。

我试图插入空格,如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(); $("
") .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(); } });

UPDATE

以下作品:

 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对象实际上是有效的。

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

例如:

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

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

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

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

将生成此GET请求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 } 

我认为错误的是,你试图将o 字符串化 ,而你试图传递的id是在o对象内,而不是在o对象本身。

所以试试这个代码

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