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

时间:2008-11-21 15:32:24

标签: jquery asp.net-mvc json

我正在创建一个小应用程序来自学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”...

任何提示?

9 个答案:

答案 0 :(得分:238)

我修改了我的回复以包含我所做的测试应用的代码。

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

答案 1 :(得分:105)

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

答案 2 :(得分:24)

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

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

答案 3 :(得分:8)

不要将数据作为数组发布。 To bind to a list, the key/value pairs should be submitted with the same value for each key.

您不应该需要表单来执行此操作。您只需要一个键/值对列表,您可以在$ .post。

的调用中包含这些键

答案 4 :(得分:6)

.NET4.5MVC 5

<强>使用Javascript:

JS中的

对象: 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

希望这可以节省你一些时间。

答案 5 :(得分: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);
    }
});

假设&#39; selectedValues&#39;是对象数组。

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

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

答案 6 :(得分:1)

正如我所讨论的那样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);
}

答案 7 :(得分:0)

您可以使用

设置全局参数
jQuery.ajaxSettings.traditional = true;

答案 8 :(得分:-1)

在我的情况下,答案对我帮助很大,所以非常感谢。 但是为了将来参考,人们应该绑定到模型然后验证。 Phil Haack的这篇文章为MVC 2描述了这一点。http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

希望这有助于某人。