Làm cách nào tôi có thể đăng một mảng chuỗi lên ASP.NET MVC Controller mà không cần biểu mẫu?


185

Tôi đang tạo một ứng dụng nhỏ để tự dạy mình ASP.NET MVC và JQuery, và một trong những trang là danh sách các mục trong đó một số mục có thể được chọn. Sau đó, tôi muốn nhấn một nút và gửi Danh sách (hoặc một cái gì đó tương đương) đến bộ điều khiển của tôi có chứa id của các mục đã được chọn, sử dụng chức năng Đăng của JQuery.

Tôi quản lý để có được một mảng với id của các yếu tố đã được chọn, và bây giờ tôi muốn đăng nó. Một cách tôi có thể làm điều này là có một hình thức giả trong trang của mình, với một giá trị ẩn, sau đó đặt giá trị ẩn với các mục đã chọn và đăng biểu mẫu đó; Điều này có vẻ tồi tệ, mặc dù.

Có cách nào sạch hơn để đạt được điều này, bằng cách gửi mảng trực tiếp đến bộ điều khiển? Tôi đã thử một vài thứ khác nhau nhưng có vẻ như bộ điều khiển không thể ánh xạ dữ liệu mà nó nhận được. Đây là mã cho đến nay:

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

Và sau đó, Trình điều khiển của tôi trông như thế này

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

Tất cả những gì tôi quản lý để có được là "null" trong tham số bộ điều khiển ...

Bất cứ lời khuyên?


Mặc dù, bạn có thể truy cập cùng một dữ liệu bằng cách sử dụngRequest["values[]"]
Tocco

Câu trả lời:


246

Tôi đã sửa đổi phản hồi của mình để bao gồm mã cho một ứng dụng thử nghiệm mà tôi đã làm.

Cập nhật: Tôi đã cập nhật jQuery để đặt cài đặt 'truyền thống' thành true để điều này sẽ hoạt động trở lại (theo câu trả lời của @DustinDavis).

Đầu tiên là 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
    });
}

Và đây là mã trong lớp trình điều khiển của tôi:

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

Khi tôi gọi chức năng javascript đó, tôi nhận được thông báo "Mục đầu tiên trong danh sách: 'item1'". Hi vọng điêu nay co ich!


3
Thật tốt khi tôi tìm thấy câu trả lời này, bây giờ tôi có thể gửi một loạt Guid's và Action nhận chúng vào Danh sách <Guid>. Cảm ơn
Tx3

43
Có hai điều quan trọng cần lưu ý ở đây. . 1) datatype: "json" 2) truyền thống: true .Without chúng mảng chuỗi wont được truyền cho phương pháp hành động
Thanigainathan

1
Lưu ý rằng dataType: 'JSON'khiến jQuery cố phân tích phản hồi dưới dạng JSON và sẽ báo lỗi nếu đó không phải là JSON hợp lệ.
sennett

8
@Thanigainathan dataType: 'json'là dành cho kiểu trả về và không bắt buộc phải gửi mảng tới Action. contentType: "application/json; charset=utf-8", là một, nhưng trong một số trường hợp như thế này là không bắt buộc.
Ruchan

1
@emzero sử dụngvar postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };
Nick M

108

FYI: JQuery đã thay đổi cách họ tuần tự hóa dữ liệu bài đăng.

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

Bạn phải đặt cài đặt 'Truyền thống' thành đúng, khôn ngoan khác

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

sẽ đi ra như

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

thay vì

Values=1&Values=2&Values=3

8
Đây là một cái gì đó khiến tôi phải suy nghĩ một lúc. thiết lập $.ajax({ ..., traditional: true});sẽ giúp hoàn nguyên về tuần tự hóa truyền thống.
juhan_h

Tôi cần điều này để một tuyến ASP.NET MVC tiêu thụ đúng một mảng js đơn giản của các giá trị chuỗi.
BrandonG

Câu trả lời của bạn thực sự hữu ích. Tôi có hoàn cảnh tương tự nhưng nó là với ints. Khi tôi sử dụng traditional: true, nó hoạt động, câu trả lời và liên kết của bạn giải thích lý do tại sao của nó. Nó cũng hoạt động khi tôi sử dụng type: "POST", mà không sử dụng traditional: true. Tại sao vậy? Bạn có thể vui lòng giải thích. FYI Tôi đang sử dụng Asp.Net Mvc.
barnes

Có cách nào trong ASP.NET để phân tích một mảng ẩn danh như thế này mà không có chỉ mục không? Giá trị [] = 1 & Giá trị [] = 2 & Giá trị [] = 3
Charles Owen

24

Cảm ơn mọi người vì câu trả lời. Một giải pháp nhanh khác sẽ là sử dụng phương thức jQuery.param với tham số truyền thống được đặt thành true để chuyển đổi đối tượng JSON thành chuỗi:

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

Hoạt động tốt và hoàn toàn phù hợp với tôi khi tôi đang sử dụng $ .post () thay vì $ .ajax (). Cảm ơn bạn !
Thu hút

9

Đừng đăng dữ liệu dưới dạng một mảng. Để liên kết với một danh sách, các cặp khóa / giá trị phải được gửi với cùng một giá trị cho mỗi khóa.

Bạn không cần một hình thức để làm điều này. Bạn chỉ cần một danh sách các cặp khóa / giá trị mà bạn có thể đưa vào lệnh gọi đến $ .post.



6

Trong .NET4.5,MVC 5

Javascript:

đối tượng trong JS: nhập mô tả hình ảnh ở đây

cơ chế nào đăng bài.

    $('.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ác đối tượng:

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

Điều khiển:

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

Đối tượng nhận được:

nhập mô tả hình ảnh ở đây

Hy vọng điều này sẽ giúp bạn tiết kiệm thời gian.


4

Một triển khai khác cũng đang làm việc với danh sách các đối tượng, không chỉ các chuỗi:

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

Giả sử rằng 'Giá trị được chọn' là Mảng đối tượng.

Trong bộ điều khiển tham số là một danh sách các ViewModels tương ứng.

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

1

Như tôi đã thảo luận ở đây ,

Nếu bạn muốn chuyển đối tượng JSON tùy chỉnh sang hành động MVC thì bạn có thể sử dụng giải pháp này, nó hoạt động như một nét quyến rũ.

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

Lợi ích thực sự của giải pháp này là bạn không yêu cầu xác định một lớp mới cho mỗi kết hợp các đối số và bên cạnh đó, bạn có thể chuyển các đối tượng của mình thành các kiểu ban đầu của chúng một cách dễ dàng.

Bạn có thể sử dụng một phương thức trợ giúp như thế này để tạo thuận lợi cho công việc của bạn:

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

Bạn có thể thiết lập tham số toàn cầu với

jQuery.ajaxSettings.traditional = true;

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.