如何在没有表单的情况下将字符串数组发送到 ASP.NET MVC 控制器?

我正在创建一个小应用程序来自学 ASP.NET MVC 和 JQuery,其中一个页面是一个可以选择其中一些项目的列表。然后,我想按下一个按钮,并使用 JQuery 的 Post 函数向控制器发送一个 List (或类似的东西) ,其中包含所选项的 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”..。

有什么建议吗?

239413 次浏览

不要以数组的形式发布数据

您不应该需要一个表单来执行此操作。您只需要一个键/值对列表,可以将其包含在对 $的调用中。邮寄。

我修改了我的响应,以包含一个测试应用程序的代码。

更新: 我已经更新了 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 函数时,我会得到一个提示“ list 中的第一项: ‘ item1’”。

供参考: JQuery 改变了它们序列化发布数据的方式。

Http://forum.jquery.com/topic/nested-param-serialization

你必须将“传统”设置为真,否则

{ Values : ["1", "2", "3"] }

就会变成

Values[]=1&Values[]=2&Values[]=3

而不是

Values=1&Values=2&Values=3

这个答案在我的情况下帮了我很多,所以谢谢你。 然而,为了将来的参考,人们应该绑定到一个模型,然后进行验证。Phil Haack 的这篇文章为 MVC 2描述了这一点。译自: 美国《科学》杂志网站(http://haacked.com/archive/2010/04/15/send-json-to-an-asp-net-mvc-action-method-argument.aspx) http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

希望这对谁有帮助。

谢谢大家的回答。另一个快速解决方案是使用 JQuery param方法,将 传统参数设置为 没错,将 JSON 对象转换为字符串:

$.post("/your/url", $.param(yourJsonObject,true));

正如我所说的 给你,

如果你想把定制的 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);
}

.NET4.5MVC 5

Javascript:

JS 中的 object: enter image description here

机制,确实后。

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

收到目标:

enter image description here

希望这能为你节省点时间。

另一个同样使用对象列表(而不仅仅是字符串)的实现:

约翰逊:

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

假设“ selectedValue”是对象数组。

在控制器中,参数是相应 ViewModel 的列表。

public JsonResult SaveList(List<ViewModel> values)
{
return Json(new {
Result = String.Format("Fist item in list: '{0}'", values[0].Name)
});
}

可以设置全局参数

jQuery.ajaxSettings.traditional = true;