如何在没有表单的情况下将字符串数组发布到 ASP.NET MVC 控制器?
Posted
技术标签:
【中文标题】如何在没有表单的情况下将字符串数组发布到 ASP.NET MVC 控制器?【英文标题】:How can I post an array of string to ASP.NET MVC Controller without a form? 【发布时间】:2010-09-23 11:21:34 【问题描述】:我正在创建一个小应用程序来自学 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[]"]
访问相同的数据
【参考方案1】:
我修改了我的回复以包含我所做的测试应用的代码。
更新:我已更新 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'”。希望这会有所帮助!
【讨论】:
很高兴我找到了这个答案,现在我可以发送 Guid 数组,Action 将它们接收到 ListdataType: 'JSON'
会导致 jQuery 尝试将响应解析为 JSON,如果它不是有效的 JSON,则会出错。
@Thanigainathan dataType: 'json'
用于返回类型,不需要将数组发送到 Action。 contentType: "application/json; charset=utf-8"
, 是其中之一,但在某些情况下不需要这样。
@emzero 使用 var postData = id: 45, [myClassProp1: 1, myClassProp2: 2, ...], anotherParam: "some string" ;
【参考方案2】:
仅供参考: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);
将有助于恢复到传统的序列化。
我需要这个才能让 ASP.NET MVC 路由正确使用一个简单的 js 字符串值数组。
你的回答真的很有帮助。我有同样的情况,但它是ints
。当我使用traditional: true
时,它起作用了,您的答案和链接解释了它的为什么。当我使用type: "POST"
,而不使用traditional: true
时,它也可以工作。这是为什么?能否请您详细说明。仅供参考,我正在使用 Asp.Net Mvc。
有没有办法在 ASP.NET 中解析这样一个没有索引的匿名数组?值[]=1&Values[]=2&Values[]=3【参考方案3】:
感谢大家的回答。另一个快速的解决方案是使用 jQuery.param 方法并将 traditional 参数设置为 true 将 JSON 对象转换为字符串:
$.post("/your/url", $.param(yourJsonObject,true));
【讨论】:
效果很好,非常适合我,因为我使用的是 $.post() 而不是 $.ajax()。谢谢!【参考方案4】:不要将数据作为数组发布。 To bind to a list, the key/value pairs should be submitted with the same value for each key.
您不需要表单来执行此操作。您只需要一个键/值对列表,您可以将其包含在对 $.post 的调用中。
【讨论】:
谢谢。更新后的网址为:haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx【参考方案5】:在.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)
....
收到的对象:
希望这可以为您节省一些时间。
【讨论】:
【参考方案6】:另一个也使用对象列表的实现,而不仅仅是字符串:
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)
);
【讨论】:
【参考方案7】:正如我所讨论的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);
【讨论】:
【参考方案8】:你可以设置全局参数
jQuery.ajaxSettings.traditional = true;
【讨论】:
【参考方案9】:答案在我的情况下帮助了我很多,所以谢谢。 但是,为了将来参考,人们应该绑定到模型,然后进行验证。 Phil Haack 的这篇文章描述了 MVC 2。http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx
希望这对某人有所帮助。
【讨论】:
以上是关于如何在没有表单的情况下将字符串数组发布到 ASP.NET MVC 控制器?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有 ASP.NET Core 的情况下将 Json 数据从控制器发送到 javascript?
Django:如何在没有''的情况下将数组传输到javascript?