如何不使用表单将字符串数组发布到ASP.NET MVC Controller?


185

我正在创建一个小应用程序来自学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[]"]
Tocco

Answers:


246

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

更新:我已经更新了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'”。希望这可以帮助!


3
找到这个答案很好,现在我可以发送Guid's数组,并且Action可以将它们接收到List <Guid>。谢谢
Tx3

43
这里有两个重要的事情要注意。1)dataType:“ json” 2。)传统:true。没有它们,字符串数组将不会传递给动作方法
Thanigainathan 2011年

1
请注意,这dataType: 'JSON'会导致jQuery尝试将响应解析为JSON,如果它不是有效的JSON,则会出错。
SENNETT

8
@Thanigainathan dataType: 'json'是用于返回类型的,不需要将数组发送到Action。contentType: "application/json; charset=utf-8"是一个,但在某些情况下则不需要这样做。
2014年

1
@emzero使用var postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };
Nick M

108

仅供参考: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

8
这让我me了一段时间。设置$.ajax({ ..., traditional: true});将有助于恢复传统的序列化。
juhan_h 2011年

我需要此命令,以便ASP.NET MVC路由正确使用字符串值的简单js数组。
BrandonG '16

您的回答确实很有帮助。我有同样的情况,但事实是这样ints。当我使用时traditional: true,它有效,您的答案和链接说明了原因。我使用时也可以使用type: "POST",而无需使用traditional: true。这是为什么?请您详细说明。仅供参考,我正在使用Asp.Net Mvc。
巴恩斯

ASP.NET中有没有办法解析像这样没有索引的匿名数组?Values [] = 1&Values [] = 2&Values [] = 3
Charles Owen

24

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

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

当我使用$ .post()而不是$ .ajax()时,效果很好,非常适合我。谢谢 !
AFract


6

.NET4.5MVC 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

另一个实现也可以处理对象列表,而不仅仅是字符串:

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

1

正如我讨论这里

如果您想将自定义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);
}

0

您可以使用以下命令设置全局参数

jQuery.ajaxSettings.traditional = true;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.