我正在创建一个小应用程序来自学 ASP.NET MVC 和 JQuery,其中一个页面是一个项目列表,其中一些可以选择。然后我想按下一个按钮并使用 JQuery 的 Post 函数向我的控制器发送一个列表(或等效的东西),其中包含所选项目的 ID。
我设法获得了一个包含所选元素 id 的数组,现在我想发布它。我可以做到这一点的一种方法是在我的页面中有一个带有隐藏值的虚拟表单,然后使用所选项目设置隐藏值,然后发布该表单;不过,这看起来很糟糕。
有没有更简洁的方法来实现这一点,将数组直接发送到控制器?我尝试了一些不同的方法,但看起来控制器无法映射它接收的数据。这是到目前为止的代码:
function generateList(selectedValues) {
var s = {
values: selectedValues //selectedValues is an array of string
};
$.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}
然后我的控制器看起来像这样
public ActionResult GenerateList(List<string> values)
{
//do something
}
我设法得到的只是控制器参数中的“null”......
有小费吗?
Request["values[]"]
访问相同的数据
我修改了我的回复以包含我所做的测试应用程序的代码。
更新:我已更新 jQuery 以将“传统”设置设置为 true,因此这将再次起作用(根据 @DustinDavis 的回答)。
首先是javascript:
function test()
{
var stringArray = new Array();
stringArray[0] = "item1";
stringArray[1] = "item2";
stringArray[2] = "item3";
var postData = { values: stringArray };
$.ajax({
type: "POST",
url: "/Home/SaveList",
data: postData,
success: function(data){
alert(data.Result);
},
dataType: "json",
traditional: true
});
}
这是我的控制器类中的代码:
public JsonResult SaveList(List<String> values)
{
return Json(new { Result = String.Format("Fist item in list: '{0}'", values[0]) });
}
当我调用该 javascript 函数时,我收到一条警报,提示“列表中的第一项:'item1'”。
仅供参考:JQuery 改变了他们序列化发布数据的方式。
http://forum.jquery.com/topic/nested-param-serialization
您必须将“传统”设置设置为 true,否则
{ Values : ["1", "2", "3"] }
会出来
Values[]=1&Values[]=2&Values[]=3
代替
Values=1&Values=2&Values=3
$.ajax({ ..., traditional: true});
将有助于恢复到传统的序列化。
ints
。当我使用 traditional: true
时,它起作用了,您的答案和链接解释了它的为什么。当我使用 type: "POST"
而不使用 traditional: true
时,它也可以工作。这是为什么?能否请您详细说明。仅供参考,我正在使用 Asp.Net Mvc。
谢谢大家的回答。另一个快速的解决方案是使用 jQuery.param 方法将传统参数设置为 true 将 JSON 对象转换为字符串:
$.post("/your/url", $.param(yourJsonObject,true));
不要将数据作为数组发布。 To bind to a list, the key/value pairs should be submitted with the same value for each key.
您不需要表格来执行此操作。您只需要一个键/值对列表,您可以将其包含在对 $.post 的调用中。
在 .NET4.5
,MVC 5
Javascript:
https://i.stack.imgur.com/5kTwZ.png
确实发布的机制。
$('.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)
{
....
}
收到的对象:
https://i.stack.imgur.com/pgI2k.png
希望这可以节省您一些时间。
另一个也使用对象列表的实现,而不仅仅是字符串:
JS:
var postData = {};
postData[values] = selectedValues ;
$.ajax({
url: "/Home/SaveList",
type: "POST",
data: JSON.stringify(postData),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data){
alert(data.Result);
}
});
假设“selectedValues”是对象数组。
在控制器中,参数是对应 ViewModel 的列表。
public JsonResult SaveList(List<ViewModel> values)
{
return Json(new {
Result = String.Format("Fist item in list: '{0}'", values[0].Name)
});
}
正如我所讨论的 here ,
如果你想将自定义 JSON 对象传递给 MVC 操作,那么你可以使用这个解决方案,它就像一个魅力。
public string GetData() {
// InputStream contains the JSON object you've sent
String jsonString = new StreamReader(this.Request.InputStream).ReadToEnd();
// Deserialize it to a dictionary
var dic =
Newtonsoft.Json.JsonConvert.DeserializeObject < Dictionary < String,
dynamic >> (jsonString);
string result = "";
result += dic["firstname"] + dic["lastname"];
// You can even cast your object to their original type because of 'dynamic' keyword
result += ", Age: " + (int) dic["age"];
if ((bool) dic["married"])
result += ", Married";
return result;
}
此解决方案的真正好处是您不需要为每个参数组合定义一个新类,除此之外,您可以轻松地将对象转换为其原始类型。
您可以使用这样的辅助方法来促进您的工作:
public static Dictionary < string, dynamic > GetDic(HttpRequestBase request) {
String jsonString = new StreamReader(request.InputStream).ReadToEnd();
return Newtonsoft.Json.JsonConvert.DeserializeObject < Dictionary < string, dynamic >> (jsonString);
}
您可以设置全局参数
jQuery.ajaxSettings.traditional = true;
答案在我的情况下帮助了我很多,所以谢谢你。但是,为了将来参考,人们应该绑定到模型,然后进行验证。 Phil Haack 的这篇文章针对 MVC 2 进行了描述。http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx
希望这可以帮助某人。
dataType: 'JSON'
会导致 jQuery 尝试将响应解析为 JSON,如果它不是有效的 JSON,则会出错。dataType: 'json'
用于返回类型,不需要将数组发送到操作。contentType: "application/json; charset=utf-8"
,是其中之一,但在某些情况下,不需要这样。var postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };