如何将一个string数组发送到ASP.NET MVC控制器没有窗体?
我正在创build一个小型应用程序来自学ASP.NET MVC和JQuery,其中一个页面是一些可以select的项目列表。 然后,我想按下一个button,并使用JQuery的Post函数向包含所选项目的ID的控制器发送一个List(或类似的东西)。
我设法得到一个数组与选定的元素的ID,现在我想发布。 我可以这样做的一种方式是在页面中创build一个虚拟表单,其中包含一个隐藏的值,然后使用所选项目设置隐藏值,然后发布该表单; 虽然这看上去很蹩脚。
有一个更清洁的方式来实现这一点,通过发送数组直接到控制器? 我尝试了一些不同的东西,但是看起来控制器不能映射它所接收的数据。 以下是目前的代码:
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 }
我设法得到的是控制器参数中的一个“空”…
有小费吗?
我修改了我的回应,包括我做的testing应用程序的代码。
更新:我已经更新了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
感谢大家的答案。 另一个快速解决scheme是使用传统参数设置为true的 jQuery.param方法将JSON对象转换为string:
$.post("/your/url", $.param(yourJsonObject,true));
不要将数据作为数组发布。 要绑定到列表,键/值对应为每个键提交相同的值。
你不应该需要一个表单来做到这一点。 您只需要一个键/值对的列表,您可以在$ .post的调用中包含该列表。
在.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) { .... }
收到的对象:
希望这可以为你节省一些时间。
另一个实现也是使用对象列表,而不仅仅是string:
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) }); }
正如我在这里讨论的,
如果你想传递自定义的JSON对象到MVC动作,那么你可以使用这个解决scheme,它就像一个魅力。
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; }
这个解决scheme的真正好处是,你不需要为每个参数组合定义一个新的类,除此之外,你可以很容易地把你的对象转换成原来的types。
你可以使用这样的辅助方法来帮助你的工作
public static Dictionary<string, dynamic> GetDic(HttpRequestBase request) { String jsonString = new StreamReader(request.InputStream).ReadToEnd(); return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString); }
这个答案在我的情况下帮了我很多,所以非常感谢。 然而,为了将来的参考,人们应该绑定到一个模型,然后validation。 菲尔·哈克的这篇文章描述了这个MVC 2. http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx
希望这有助于某人。