如何将带有 JSON、jQuery 的复杂对象数组发布到 ASP.NET MVC 控制器?
Posted
技术标签:
【中文标题】如何将带有 JSON、jQuery 的复杂对象数组发布到 ASP.NET MVC 控制器?【英文标题】:How to post an array of complex objects with JSON, jQuery to ASP.NET MVC Controller? 【发布时间】:2010-09-24 03:11:32 【问题描述】:我当前的代码如下所示。如何将我的数组传递给控制器,我的控制器动作必须接受什么样的参数?
function getplaceholders()
var placeholders = $('.ui-sortable');
var result = new Array();
placeholders.each(function()
var ph = $(this).attr('id');
var sections = $(this).find('.sort');
var section;
sections.each(function(i, item)
var sid = $(item).attr('id');
result.push( 'SectionId': sid, 'Placeholder': ph, 'Position': i );
);
);
alert(result.toString());
$.post(
'/portal/Designer.mvc/SaveOrUpdate',
result,
function(data)
alert(data.Result);
, "json");
;
我的控制器动作方法看起来像
public JsonResult SaveOrUpdate(IList<PageDesignWidget> widgets)
【问题讨论】:
【参考方案1】:我找到了解决方案。我使用 Steve Gentile 的解决方案,jQuery and ASP.NET MVC – sending JSON to an Action – Revisited。
我的 ASP.NET MVC 视图代码如下所示:
function getplaceholders()
var placeholders = $('.ui-sortable');
var results = new Array();
placeholders.each(function()
var ph = $(this).attr('id');
var sections = $(this).find('.sort');
var section;
sections.each(function(i, item)
var sid = $(item).attr('id');
var o = 'SectionId': sid, 'Placeholder': ph, 'Position': i ;
results.push(o);
);
);
var postData = widgets: results ;
var widgets = results;
$.ajax(
url: '/portal/Designer.mvc/SaveOrUpdate',
type: 'POST',
dataType: 'json',
data: $.toJSON(widgets),
contentType: 'application/json; charset=utf-8',
success: function(result)
alert(result.Result);
);
;
我的控制器动作被自定义属性修饰
[JsonFilter(Param = "widgets", JsonDataType = typeof(List<PageDesignWidget>))]
public JsonResult SaveOrUpdate(List<PageDesignWidget> widgets
自定义属性的代码可以在here 找到(链接现在已断开)。
由于链接已损坏,这是 JsonFilterAttribute 的代码
public class JsonFilter : ActionFilterAttribute
public string Param get; set;
public Type JsonDataType get; set;
public override void OnActionExecuting(ActionExecutingContext filterContext)
if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
string inputContent;
using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
inputContent = sr.ReadToEnd();
var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
filterContext.ActionParameters[Param] = result;
JsonConvert.DeserializeObject 来自 Json.NET
链接:Serializing and Deserializing JSON with Json.NET
【讨论】:
看起来很棒 - 博客文章和自定义属性代码链接不再起作用 - 你可以重新发布吗? 此解决方案需要在客户端和服务器端进行更改。我知道你很久以前就需要这个,但我不妨提供一个不同方法的链接,它使用一个简单的 jQuery 插件,可以将任何 javascript 对象转换为默认模型绑定器可以理解的形式,并将模型绑定到参数。不需要过滤器。 erraticdev.blogspot.com/2010/12/…我不知道你是如何解决验证错误的,但我也有一个解决方案:erraticdev.blogspot.com/2010/11/… 你能给出 JavaScriptConvert.DeserializeObject 的来源/出处吗? 这是 Newtonsoft Json 库 - 如果您打开 nuget 包管理器并在 Newtonsoft 上搜索,它会为您显示(现在是 2016 年)。可能现在这很明显,但以防万一有人想知道。【参考方案2】:动作过滤器、jquery stringify、bleh...
Peter,这个功能是 MVC 原生的。这是 MVC 如此出色的原因之一。
$.post('SomeController/Batch', 'ids': ['1', '2', '3'], function (r)
...
);
在行动中,
[HttpPost]
public ActionResult Batch(string[] ids)
像魅力一样工作:
如果您使用的是 jQuery 1.4+,那么您想研究设置传统模式:
jQuery.ajaxSettings.traditional = true;
如此处所述:http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters
这甚至适用于复杂的对象。如果您有兴趣,您应该查看有关模型绑定的 MVC 文档:http://msdn.microsoft.com/en-us/library/dd410405.aspx
【讨论】:
您可能是对的,但 JSON 模型绑定器对 MVC3 来说是新的,并且在 2008 年不支持此问题时提出了这个问题。在您的回答中值得一提。 这是一个传递复杂对象数组的例子吗? 不是,但该示例仍然适用(MVC 3+)。只要您的参数名称与您期望的模型匹配,您就不会遇到任何问题。 这里的关键是使用方法参数名称(“ids”)创建一个 JSON 对象,然后将复杂对象数组放入其中。此外,将第三个参数设为“true”,您将处理传统模式。【参考方案3】:在.NET4.5
、MVC 5
中不需要小部件。
Javascript:
JS 中的对象:
确实发布的机制。
$('.button-green-large').click(function()
$.ajax(
url: 'Quote',
type: "POST",
dataType: "json",
data: JSON.stringify(document.selectedProduct),
contentType: 'application/json; charset=utf-8',
);
);
C#
对象:
public class WillsQuoteViewModel
public string Product get; set;
public List<ClaimedFee> ClaimedFees get; set;
public partial class ClaimedFee //Generated by EF6
public long Id get; set;
public long JourneyId get; set;
public string Title get; set;
public decimal Net get; set;
public decimal Vat get; set;
public string Type get; set;
public virtual Journey Journey get; set;
控制器:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
....
收到的对象:
希望这可以为您节省一些时间。
【讨论】:
【参考方案4】:迈向Create REST API using ASP.NET MVC that speaks both JSON and plain XML的后半段,引述:
现在我们需要接受通过 HTTP POST 传递的 JSON 和 XML 负载。有时您的客户可能希望一次性上传一组对象以进行批处理。因此,他们可以使用 JSON 或 XML 格式上传对象。 ASP.NET MVC 中没有原生支持自动解析发布的 JSON 或 XML 并自动映射到 Action 参数。所以,我写了一个过滤器来做到这一点。”
然后他实现了一个动作过滤器,将 JSON 映射到 C# 对象并显示代码。
【讨论】:
我只是在写我的答案。但无论如何我都会发布它;-)【参考方案5】:首先下载这个 JavaScript 代码,JSON2.js,它将帮助我们将对象序列化为字符串。
在我的示例中,我通过 Ajax 发布 jqGrid 的行:
var commissions = new Array();
// Do several row data and do some push. In this example is just one push.
var rowData = $(GRID_AGENTS).getRowData(ids[i]);
commissions.push(rowData);
$.ajax(
type: "POST",
traditional: true,
url: '<%= Url.Content("~/") %>' + AREA + CONTROLLER + 'SubmitCommissions',
async: true,
data: JSON.stringify(commissions),
dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function (data)
if (data.Result)
jQuery(GRID_AGENTS).trigger('reloadGrid');
else
jAlert("A problem ocurred during updating", "Commissions Report");
);
现在在控制器上:
[HttpPost]
[JsonFilter(Param = "commissions", JsonDataType = typeof(List<CommissionsJs>))]
public ActionResult SubmitCommissions(List<CommissionsJs> commissions)
var result = dosomething(commissions);
var jsonData = new
Result = true,
Message = "Success"
;
if (result < 1)
jsonData = new
Result = false,
Message = "Problem"
;
return Json(jsonData);
创建一个 JsonFilter 类(感谢 JSC 参考)。
public class JsonFilter : ActionFilterAttribute
public string Param get; set;
public Type JsonDataType get; set;
public override void OnActionExecuting(ActionExecutingContext filterContext)
if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
string inputContent;
using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
inputContent = sr.ReadToEnd();
var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
filterContext.ActionParameters[Param] = result;
创建另一个类,以便过滤器可以将 JSON 字符串解析为实际的可操作对象:这个类 comissionsJS 是我的 jqGrid 的所有行。
public class CommissionsJs
public string Amount get; set;
public string CheckNumber get; set;
public string Contract get; set;
public string DatePayed get; set;
public string DealerName get; set;
public string ID get; set;
public string IdAgentPayment get; set;
public string Notes get; set;
public string PaymentMethodName get; set;
public string RowNumber get; set;
public string AgentId get; set;
我希望这个例子有助于说明如何发布一个复杂的对象。
【讨论】:
【参考方案6】: [HttpPost]
public bool parseAllDocs([FromBody] IList<docObject> data)
// do stuff
【讨论】:
【参考方案7】:不需要做任何特别的事情。仅在您的帖子部分执行以下操作:
$.post(yourURL, '': results)(function(e) ...
在服务器中使用这个:
public ActionResult MethodName(List<yourViewModel> model)...
【讨论】:
以上是关于如何将带有 JSON、jQuery 的复杂对象数组发布到 ASP.NET MVC 控制器?的主要内容,如果未能解决你的问题,请参考以下文章
WCF POST 通过 JQuery。如何在 JSON 中发送数组?
如何将 JSON 对象内的 JSON 数组传递给 jQuery 自动完成
如何使用 Javascript 或 Jquery 将 JSON 对象包装在数组中?