ChatGPT解决这个技术问题 Extra ChatGPT

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

我正在创建一个小应用程序来自学 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[]"] 访问相同的数据

W
Web Developer

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

更新:我已更新 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 将它们接收到 List。谢谢
这里有两件重要的事情需要注意。 1)dataType:“json”2。)传统:true。没有它们,字符串数组不会传递给动作方法
请注意,dataType: 'JSON' 会导致 jQuery 尝试将响应解析为 JSON,如果它不是有效的 JSON,则会出错。
@Thanigainathan dataType: 'json' 用于返回类型,不需要将数组发送到操作。 contentType: "application/json; charset=utf-8",是其中之一,但在某些情况下,不需要这样。
@emzero 使用 var postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };
D
Dustin Davis

仅供参考: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&值[]=2&值[]=3
E
Evgenii

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

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

因为我使用的是 $.post() 而不是 $.ajax(),所以效果很好并且非常适合我。谢谢 !
A
Alastair Pitts

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

您不需要表格来执行此操作。您只需要一个键/值对列表,您可以将其包含在对 $.post 的调用中。


M
Matas Vaitkevicius

.NET4.5MVC 5

Javascript:

https://i.stack.imgur.com/5kTwZ.png

确实发布的机制。

    $('.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)
{
....
}

收到的对象:

https://i.stack.imgur.com/pgI2k.png

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


d
d.popov

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

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

M
Mickael Lherminez

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

m
mr_squall

您可以设置全局参数

jQuery.ajaxSettings.traditional = true;

D
DavidW

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

希望这可以帮助某人。