使用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'); });