如何将字符串数组发布到ASP中。没有表单的MVC控制器?

时间:2022-03-25 03:41:00

I am creating a small app to teach myself ASP.NET MVC and JQuery, and one of the pages is a list of items in which some can be selected. Then I would like to press a button and send a List (or something equivalent) to my controller containing the ids of the items that were selected, using JQuery's Post function.

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

I managed to get an array with the ids of the elements that were selected, and now I want to post that. One way I could do this is to have a dummy form in my page, with a hidden value, and then set the hidden value with the selected items, and post that form; this looks crufty, though.

我设法获得了一个数组,其中包含所选元素的id,现在我要发布它。我可以这样做的一种方法是在我的页面中有一个具有隐藏值的假表单,然后用选定的项设置隐藏值,然后发布那个表单;不过,这看起来crufty。

Is there a cleaner way to achieve this, by sending the array directly to the controller? I've tried a few different things but it looks like the controller can't map the data it's receiving. Here's the code so far:

是否有一种更干净的方法,通过直接将数组发送给控制器来实现这一点?我尝试了一些不同的东西,但是看起来控制器不能映射它接收的数据。下面是迄今为止的代码:

function generateList(selectedValues) {
   var s = {
      values: selectedValues //selectedValues is an array of string
   };
   $.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}

And then my Controller looks like this

我的控制器是这样的

public ActionResult GenerateList(List<string> values)
{
    //do something
}

All I managed to get is a "null" in the controller parameter...

我设法得到的是控制器参数中的“null”……

Any tips?

任何建议吗?

9 个解决方案

#1


230  

I modified my response to include the code for a test app I did.

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

Update: I have updated the jQuery to set the 'traditional' setting to true so this will work again (per @DustinDavis' answer).

更新:我已经更新了jQuery,将“传统”设置设置设置为true,因此这将再次工作(根据@DustinDavis的回答)。

First the javascript:

第一个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
    });
}

And here's the code in my controller class:

这是我的控制器类的代码:

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

When I call that javascript function, I get an alert saying "First item in list: 'item1'". Hope this helps!

当我调用这个javascript函数时,我得到一个警告,说“列表中的第一项:‘item1’”。希望这可以帮助!

#2


99  

FYI: JQuery changed the way they serialize post data.

FYI: JQuery改变了它们序列化post数据的方式。

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

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

You have to set the 'Traditional' setting to true, other wise

你必须把“传统”设置为真,其他的明智。

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

will come out as

会出来

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

instead of

而不是

Values=1&Values=2&Values=3

#3


24  

Thanks everyone for the answers. Another quick solution will be to use jQuery.param method with traditional parameter set to true to convert JSON object to string:

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

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

#4


8  

Don't post the data as an array. To bind to a list, the key/value pairs should be submitted with the same value for each key.

不要将数据作为数组发布。要绑定到列表,应该为每个键提交具有相同值的键/值对。

You should not need a form to do this. You just need a list of key/value pairs, which you can include in the call to $.post.

您不应该需要一个表单来实现这一点。您只需要一个键/值对列表,您可以在调用$.post时包含这些键/值对。

#5


4  

In .NET4.5, MVC 5

在MVC .NET4.5 5

Javascript:

Javascript:

object in JS: 如何将字符串数组发布到ASP中。没有表单的MVC控制器?

JS的对象:

mechanism that does post.

机制,并发布。

    $('.button-green-large').click(function() {
        $.ajax({
            url: 'Quote',
            type: "POST",
            dataType: "json",
            data: JSON.stringify(document.selectedProduct),
            contentType: 'application/json; charset=utf-8',
        });
    });

C#

c#

Objects:

对象:

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

Controller:

控制器:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}

Object received:

对象收到:

如何将字符串数组发布到ASP中。没有表单的MVC控制器?

Hope this saves you some time.

希望这能节省你一些时间。

#6


3  

Another implementation that is also working with list of objects, not just strings:

另一个实现也在使用对象列表,而不仅仅是字符串:

JS:

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

Assuming that 'selectedValues' is Array of Objects.

假设“selectedValues”是对象数组。

In the controller the parameter is a list of corresponding ViewModels.

在控制器中,参数是相应视图模型的列表。

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

#7


1  

As I discussed here ,

正如我在这里讨论的,

if you want to pass custom JSON object to MVC action then you can use this solution, it works like a charm.

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

The real benefit of this solution is that you don't require to define a new class for each combination of arguments and beside that, you can cast your objects to their original types easily.

这个解决方案的真正好处是,您不需要为每个参数组合定义一个新的类,除此之外,您可以轻松地将对象转换为它们的原始类型。

and you can use a helper method like this to facilitate your job

你可以使用像这样的辅助方法来帮助你的工作

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


0  

You can setup global parameter with

您可以设置全局参数

jQuery.ajaxSettings.traditional = true;

#9


-1  

The answer helped me a lot in my situation so thanks for that. However for future reference people should bind to a model and then validate. This post from Phil Haack describes this for MVC 2. http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

这个答案对我的处境有很大帮助,谢谢。但是,对于将来的引用,人们应该绑定到一个模型,然后进行验证。Phil Haack的这篇文章描述了MVC 2。http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

Hope this helps someone.

希望这可以帮助别人。

#1


230  

I modified my response to include the code for a test app I did.

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

Update: I have updated the jQuery to set the 'traditional' setting to true so this will work again (per @DustinDavis' answer).

更新:我已经更新了jQuery,将“传统”设置设置设置为true,因此这将再次工作(根据@DustinDavis的回答)。

First the javascript:

第一个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
    });
}

And here's the code in my controller class:

这是我的控制器类的代码:

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

When I call that javascript function, I get an alert saying "First item in list: 'item1'". Hope this helps!

当我调用这个javascript函数时,我得到一个警告,说“列表中的第一项:‘item1’”。希望这可以帮助!

#2


99  

FYI: JQuery changed the way they serialize post data.

FYI: JQuery改变了它们序列化post数据的方式。

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

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

You have to set the 'Traditional' setting to true, other wise

你必须把“传统”设置为真,其他的明智。

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

will come out as

会出来

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

instead of

而不是

Values=1&Values=2&Values=3

#3


24  

Thanks everyone for the answers. Another quick solution will be to use jQuery.param method with traditional parameter set to true to convert JSON object to string:

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

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

#4


8  

Don't post the data as an array. To bind to a list, the key/value pairs should be submitted with the same value for each key.

不要将数据作为数组发布。要绑定到列表,应该为每个键提交具有相同值的键/值对。

You should not need a form to do this. You just need a list of key/value pairs, which you can include in the call to $.post.

您不应该需要一个表单来实现这一点。您只需要一个键/值对列表,您可以在调用$.post时包含这些键/值对。

#5


4  

In .NET4.5, MVC 5

在MVC .NET4.5 5

Javascript:

Javascript:

object in JS: 如何将字符串数组发布到ASP中。没有表单的MVC控制器?

JS的对象:

mechanism that does post.

机制,并发布。

    $('.button-green-large').click(function() {
        $.ajax({
            url: 'Quote',
            type: "POST",
            dataType: "json",
            data: JSON.stringify(document.selectedProduct),
            contentType: 'application/json; charset=utf-8',
        });
    });

C#

c#

Objects:

对象:

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

Controller:

控制器:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}

Object received:

对象收到:

如何将字符串数组发布到ASP中。没有表单的MVC控制器?

Hope this saves you some time.

希望这能节省你一些时间。

#6


3  

Another implementation that is also working with list of objects, not just strings:

另一个实现也在使用对象列表,而不仅仅是字符串:

JS:

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

Assuming that 'selectedValues' is Array of Objects.

假设“selectedValues”是对象数组。

In the controller the parameter is a list of corresponding ViewModels.

在控制器中,参数是相应视图模型的列表。

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

#7


1  

As I discussed here ,

正如我在这里讨论的,

if you want to pass custom JSON object to MVC action then you can use this solution, it works like a charm.

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

The real benefit of this solution is that you don't require to define a new class for each combination of arguments and beside that, you can cast your objects to their original types easily.

这个解决方案的真正好处是,您不需要为每个参数组合定义一个新的类,除此之外,您可以轻松地将对象转换为它们的原始类型。

and you can use a helper method like this to facilitate your job

你可以使用像这样的辅助方法来帮助你的工作

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


0  

You can setup global parameter with

您可以设置全局参数

jQuery.ajaxSettings.traditional = true;

#9


-1  

The answer helped me a lot in my situation so thanks for that. However for future reference people should bind to a model and then validate. This post from Phil Haack describes this for MVC 2. http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

这个答案对我的处境有很大帮助,谢谢。但是,对于将来的引用,人们应该绑定到一个模型,然后进行验证。Phil Haack的这篇文章描述了MVC 2。http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

Hope this helps someone.

希望这可以帮助别人。