Truyền mảng cho mvc Action qua AJAX


123

Tôi đang cố gắng chuyển một mảng (hoặc IEnumerable) của các int từ thông qua AJAX sang một hành động MVC và tôi cần một chút trợ giúp.

javascript là

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...

và hành động của bộ điều khiển là

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

Tại thời điểm yêu cầu được định dạng là

controller/MyAction?_=1301503418429&arrayOfValues[]=491&arrayOfValues[]=368&arrayOfValues[]=235&arrayOfValues[]=437

Vì vậy, tôi gần như ở đó, nếu tôi bỏ dấu ngoặc vuông tôi sẽ nhận được phản hồi chính xác. Làm thế nào tôi nên chuyển mảng đó vào get của tôi để bộ điều khiển có thể nhận ra nó là gì?

Rất cảm ơn vì sự giúp đỡ của bạn

Dave

Câu trả lời:


149

Đặt thuộc tính truyền thống thành true trước khi thực hiện cuộc gọi. I E:

jQuery.ajaxSettings.traditional = true

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {... 

3
cảm ơn bạn! bạn có thể vui lòng phác thảo sự khác biệt giữa ajax truyền thống và không truyền thống? Tôi muốn hiểu rõ hơn những gì tôi đang làm với phần còn lại của ứng dụng.
Tom Beech

5
bạn cũng có thể thêm cài đặt truyền thống vào một cuộc gọi. Sau đó, nó sẽ không ảnh hưởng đến phần còn lại
Glamip

1
Câu trả lời này là chính xác, nhưng nếu bạn muốn đặt "truyền thống" cho một câu trả lời kiểm tra cuộc gọi @RionWilliams. Bỏ phiếu lên cả hai. Cảm ơn!
kzfabi

@Tom Beech Kể từ jQuery 1.4, phương thức $ .param () tuần tự hóa các đối tượng sâu theo cách đệ quy để phù hợp với các ngôn ngữ và khung công tác kịch bản hiện đại như PHP và Ruby on Rails. Bạn có thể vô hiệu hóa chức năng này trên toàn cầu bằng cách đặt jQuery.ajaxSinstall.traditable = true;
Alexey Shevelyov 04/11/2015

Không có câu trả lời nào trong số này trả lời cho tôi (có thể vì bộ điều khiển của tôi là bộ điều khiển API?), Nhưng tôi đã tìm thấy giải pháp của mình trong câu trả lời SO sau: stackoverflow.com/a/11100414/1751792
Lopsided 10/8/2016

119

Tôi đã có vấn đề trong quá khứ khi cố gắng thực hiện POST (không chắc đó có phải là chính xác những gì bạn đang làm hay không, nhưng tôi nhớ lại khi truyền một mảng vào, truyền thống phải được đặt thành đúng .

 var arrayOfValues = new Array();

 //Populate arrayOfValues 
 $.ajax({ 
      type: "POST",
      url: "<%= Url.Action("MyAction","Controller")%>",
      traditional: true,
      data: { 'arrayOfValues': arrayOfValues }              
 });

4
Điều này tốt hơn nhiều so với việc cài đặt nó một cách mù quáng trên toàn cầu trong tệp web.config, như một số người đề xuất. Khác có tập hợp các dịp tốt của riêng mình, nhưng của bạn nên là giải pháp mặc định.
Panzercrisis

Đây chỉ là gửi dữ liệu dưới dạng tham số đến ActionResult, nó sẽ gọi mã Inside ActionResult chứ? Ví dụ: nếu có một số mã để chèn mảng giá trị vào cơ sở dữ liệu, mã đó có chạy không?
Saurabh

Điều này giải quyết chính xác những gì tôi cần. Các mảng của tôi tiếp tục trở lại là null trong bộ điều khiển của tôi cho đến khi tôi thêm nó và nhận chúng trong bộ điều khiển của tôi như: mảng <chuỗi> IEnumerable
SeanMC

52

Một câu trả lời muộn, nhưng khác với những câu đã có ở đây:

Nếu thay vì $.ajaxbạn muốn sử dụng các hàm tốc ký $.gethoặc $.post, bạn có thể chuyển các mảng theo cách này:


Tốc ký

var array = [1, 2, 3, 4, 5];
$.get('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
public void MyAction(List<int> data)
{
    // do stuff here
}

BÀI VIẾT

var array = [1, 2, 3, 4, 5];
$.post('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
[HttpPost]
public void MyAction(List<int> data)
{
    // do stuff here
}


Ghi chú:

  • Tham số boolean trong $.paramlà dành cho thuộc traditionaltính, PHẢI trueđể nó hoạt động .

2
Cảm ơn các mẹo về tài sản truyền thống. Tôi không thể hiểu tại sao C # param của tôi là null. Tôi thấy rằng loại "int []" cũng sẽ hoạt động trong phương thức C # Action.
Dan Randolph

9

Bạn sẽ có thể làm điều này tốt

$.ajax({
   url: 'controller/myaction',
   data: JSON.stringify({
      myKey: myArray
   }),
   success: function(data) { /* Whatever */ }
});

Sau đó, phương thức hành động của bạn sẽ như vậy:

public ActionResult(List<int> myKey)
{
    // Do Stuff
}

Đối với bạn, có vẻ như bạn chỉ cần xâu chuỗi các giá trị của mình. JSONValueProvider trong MVC sẽ chuyển đổi trở lại thành một IEnumerable cho bạn.


Cảm ơn câu trả lời nhưng tôi nghĩ có vẻ như tôi cần đặt truyền thống thành đúng. Đã nâng cao như tôi nghĩ rằng điều này sẽ làm việc quá.
Dave

9

Câu trả lời để sử dụng tùy chọn 'truyền thống' là chính xác. Tôi chỉ cung cấp thêm một số thông tin cơ bản cho người muốn tìm hiểu thêm.

Từ tài liệu jQuery:

Kể từ jQuery 1.8, phương thức $ .param () không còn sử dụng jQuery.ajaxSinstall.traditable làm cài đặt mặc định của nó và sẽ mặc định là false.

Bạn cũng có thể đọc thêm tại đây: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answershttp://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

HTH


2

NẾU TẤT CẢ CÁC FAILS ...

Không có câu trả lời nào khác ở đây giải quyết vấn đề của tôi. Tôi đã cố gắng thực hiện cuộc gọi phương thức GET từ JavaScript đến bộ điều khiển API Web MVC và gửi một mảng số nguyên dưới dạng tham số trong yêu cầu đó. Tôi đã thử tất cả các giải pháp ở đây, nhưng vẫn còn tham số trên bộ điều khiển của tôi sắp xuất hiện NULL (hoặc Không có gì cho người dùng VB).

Cuối cùng tôi đã tìm thấy giải pháp của mình trong một bài viết SO khác và nó thực sự rất đơn giản: Chỉ cần thêm [FromUri]chú thích trước tham số mảng trong bộ điều khiển ( Tôi cũng phải thực hiện cuộc gọi bằng cách sử dụng cài đặt AJAX "truyền thống" để tránh chú thích khung ). Xem bên dưới để biết mã thực tế tôi đã sử dụng trong ứng dụng của mình.


Chữ ký điều khiển:

Chữ ký điều khiển LƯU Ý: Chú thích trong C # sẽ là [FromUri]


JavaScript:

$.get('/api/InventoryApi/GetBalanceField', $.param({productIds: [42], inventoryFormId: 5493, inventoryBalanceType: 'Beginning'},true)).done(function(data) {console.log(data);});

Chuỗi URL thực tế:

http://randomhostname/api/InventoryApi/GetBalanceField?productIds=42&inventoryFormId=5493&inventoryBalanceType=Beginning

2

Ở đây hơi muộn, nhưng tôi có thể sử dụng giải pháp của SNag hơn nữa vào $ .ajax (). Đây là mã nếu nó sẽ giúp bất cứ ai:

var array = [1, 2, 3, 4, 5];

$.ajax({
    type: "GET",
    url: '/controller/MyAction',
    data: $.param({ data: array}, true),
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
    },
    error: function (x, y, z) {
    }
});

// Action Method
public void MyAction(List<int> data)
{
    // do stuff here
}

1

Nếu bạn đang chuyển sang ASP.NET Core MVC từ .Net Framework MVC như tôi, mọi thứ đã thay đổi một chút. Cuộc gọi ajax phải ở trên đối tượng thô bằng cách sử dụng chuỗi, vì vậy thay vì truyền dữ liệu của { vals: arrayOfValues }nó sẽ JSON.stringify(arrayOfValues)như sau:

$.ajax({
   url: 'controller/myaction',
   data: JSON.stringify(arrayOfValues),
   success: function(data) { /* Whatever */ }
});

Một thay đổi khác đã được thực hiện trong ASP.NET Core là ngăn chặn giả mạo yêu cầu giữa các trang web để các cuộc gọi đến một hành động MVC từ phương thức ajax, [FromBody]thuộc tính phải được áp dụng cho tham số hành động như sau:

public ActionResult MyAction([FromBody] IEnumerable<int> arrayOfValues )

Cảm ơn bạn điều này là vô cùng hữu ích sau mỗi lần hoán vị khác để gửi dữ liệu không thành công!
NibblyPig

0

Nếu bạn đang sử dụng ASP.NET Core MVC và cần xử lý dấu ngoặc vuông (thay vì sử dụng tùy chọn "truyền thống" của jQuery), thì tùy chọn duy nhất tôi tìm thấy là xây dựng thủ công IEnumerabletrong phương thức contoller.

string arrayKey = "p[]=";
var pArray = HttpContext.Request.QueryString.Value
    .Split('&')
    .Where(s => s.Contains(arrayKey))
    .Select(s => s.Substring(arrayKey.Length));

0

Tôi làm việc với asp.net core 2.2 và jquery và phải gửi một đối tượng phức tạp ('lớp chính') từ chế độ xem đến bộ điều khiển với các trường dữ liệu đơn giản và một số mảng.
Ngay sau khi tôi đã thêm mảng trong định nghĩa c # 'lớp chính' (xem bên dưới) và gửi mảng (điền chính xác) qua ajax (bài), toàn bộ đối tượng là null trong bộ điều khiển.
Đầu tiên, tôi nghĩ, "truyền thống: đúng" bị thiếu đối với cuộc gọi ajax của tôi là lý do, nhưng đây không phải là trường hợp.
Trong trường hợp của tôi, lý do là định nghĩa trong c # 'lớp chính'.
Trong 'lớp chính', tôi đã có:

public List<EreignisTagNeu> oEreignistageNeu { get; set; }

và EreignisTagNeu được định nghĩa là:

public class EreignisTagNeu
{
 public int iHME_Key { get; set; } 
}

Tôi đã phải thay đổi định nghĩa trong 'lớp chính' thành:

 public List<int> oEreignistageNeu { get; set; }

Bây giờ nó hoạt động.
Vì vậy, ... đối với tôi có vẻ như lõi asp.net có vấn đề (với bài đăng), nếu danh sách cho một mảng không được xác định hoàn toàn trong 'lớp chính'.
Lưu ý: Trong trường hợp của tôi, điều này hoạt động có hoặc không có "truyền thống: true" đối với cuộc gọi ajax


-3

Bạn cần chuyển đổi Array thành chuỗi:

//arrayOfValues = [1, 2, 3];  
$.get('/controller/MyAction', { arrayOfValues: "1, 2, 3" }, function (data) {...

cái này hoạt động ngay cả ở dạng int, long hoặc chuỗi

public ActionResult MyAction(int[] arrayOfValues )

Đây thậm chí không đúng cú pháp để gửi một mảng đến máy chủ. Bạn chỉ cần truyền một đối tượng và giả sử đó là một mảng, điều này sẽ không bao giờ xảy ra với những gì bạn đã cung cấp, đó là một chuỗi.
Twister1002
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.