Chuyển danh sách các đối tượng vào một phương pháp điều khiển MVC bằng jQuery Ajax


113

Tôi đang cố gắng chuyển một mảng đối tượng vào phương thức bộ điều khiển MVC bằng cách sử dụng hàm ajax () của jQuery. Khi tôi truy cập vào phương thức bộ điều khiển PassThing () C #, đối số "things" là rỗng. Tôi đã thử điều này bằng cách sử dụng một loại Danh sách cho đối số, nhưng điều đó cũng không hoạt động. Tôi đang làm gì sai?

<script type="text/javascript">
    $(document).ready(function () {
        var things = [
            { id: 1, color: 'yellow' },
            { id: 2, color: 'blue' },
            { id: 3, color: 'red' }
        ];

        $.ajax({
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            type: 'POST',
            url: '/Xhr/ThingController/PassThing',
            data: JSON.stringify(things)
        });
    });
</script>

public class ThingController : Controller
{
    public void PassThing(Thing[] things)
    {
        // do stuff with things here...
    }

    public class Thing
    {
        public int id { get; set; }
        public string color { get; set; }
    }
}


3
Dữ liệu của bạn là một chuỗi, nhưng phương thức của bạn chấp nhận một mảng. Thay đổi phương thức của bạn để chấp nhận một chuỗi, sau đó giải mã hóa nó trong phương thức.
Bob Horn

2
Mã của bạn là chính xác. Tôi đã thử nghiệm nó và nó hoạt động bằng cách sử dụng MVC 4. Vui lòng cung cấp thêm dữ liệu để tìm ra.
Diego

Đây là một công cụ tuyệt vời nhưng nếu bạn không chỉ cần một danh sách các chuỗi để vượt qua mà cần bao gồm một id riêng được liên kết với danh sách các chuỗi? Vì vậy, như, id nhóm, danh sách các nhóm dưới id nhóm.
Nathan McKaskle

Câu trả lời:


188

Sử dụng gợi ý của NickW, tôi có thể làm cho điều này hoạt động bằng cách sử dụng things = JSON.stringify({ 'things': things });Đây là mã hoàn chỉnh.

$(document).ready(function () {
    var things = [
        { id: 1, color: 'yellow' },
        { id: 2, color: 'blue' },
        { id: 3, color: 'red' }
    ];      

    things = JSON.stringify({ 'things': things });

    $.ajax({
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: 'POST',
        url: '/Home/PassThings',
        data: things,
        success: function () {          
            $('#result').html('"PassThings()" successfully called.');
        },
        failure: function (response) {          
            $('#result').html(response);
        }
    }); 
});


public void PassThings(List<Thing> things)
{
    var t = things;
}

public class Thing
{
    public int Id { get; set; }
    public string Color { get; set; }
}

Có hai điều tôi học được từ điều này:

  1. Cài đặt contentType và dataType là hoàn toàn cần thiết trong hàm ajax (). Nó sẽ không hoạt động nếu chúng bị thiếu. Tôi đã tìm ra điều này sau nhiều lần thử và sai.

  2. Để chuyển một mảng đối tượng vào phương thức bộ điều khiển MVC, chỉ cần sử dụng định dạng JSON.stringify ({'things': things}).

Tôi mong điều này giúp được người nào khác!


8
Tôi cũng gặp sự cố tương tự và việc thêm contentType đã khắc phục được sự cố đó. Cảm ơn!
Rochelle C

9
Hai điều cần lưu ý: JSON.stringify và chỉ định 'contentType'.
dinesh ygv

Thô thiển. Vẫn không làm việc cho tôi. URL yêu cầu của tôi là http://localhost:52459/Sales/completeSale?itemsInCart=[{"ItemId":1,"Quantity":"1","Price":3.5}]Sales.completeSaleđược public ActionResult completeSale(ItemInCart[] itemsInCart), được chú thích là HttpGet.
abalter

3
vì lý do gì tôi phải chỉ sử dụngdata: JSON.stringify(things),
Rob Scott

1
dataTypekhông cần thiết. Nếu bỏ qua nó, chức năng ajax sẽ làm việc nó ra dựa trên các dữ liệu trở lại

32

Bạn không thể chỉ làm điều này?

var things = [
    { id: 1, color: 'yellow' },
    { id: 2, color: 'blue' },
    { id: 3, color: 'red' }
];
$.post('@Url.Action("PassThings")', { things: things },
   function () {
        $('#result').html('"PassThings()" successfully called.');
   });

... và đánh dấu hành động của bạn bằng

[HttpPost]
public void PassThings(IEnumerable<Thing> things)
{
    // do stuff with things here...
}

3
Đây sẽ là câu trả lời tốt nhất. Các JSON.stringify không nên được sử dụng trong trường hợp này

Điều này không hiệu quả với tôi..Tôi đang sử dụng [HttpPost] public int SaveResults (List <ShortDetail> model) {} và $ .post ("@ Url.Action (" SaveResults "," Maps ")", {model: dataItems}, function (kết quả) {});
Samra

2
Nó đã làm việc cho tôi. Hoàn toàn là câu trả lời tốt nhất. Tôi không biết tại sao việc triển khai Halcyon không hoạt động. Hàm PassThings đã được gọi nhưng biến đầu vào 'things' lại trống ngay cả khi nó được điền vào javascript ngay trước lệnh gọi.
Leonardo Daga

13

Định dạng dữ liệu của bạn có thể là vấn đề. Hãy thử một trong hai cách sau:

data: '{ "things":' + JSON.stringify(things) + '}',

Hoặc (từ Làm cách nào để đăng một mảng chuỗi lên Bộ điều khiển ASP.NET MVC mà không có biểu mẫu? )

var postData = { things: things };
...
data = postData

Mã của bạn đã đóng, nhưng nó không hoạt động. Tôi đã có thể làm cho mã hoạt động nhờ đề xuất của bạn. Xem câu trả lời của tôi ở trên.
Halcyon

12

Tôi đang sử dụng Ứng dụng web .Net Core 2.1 và không thể nhận được câu trả lời nào ở đây để hoạt động. Tôi nhận được một tham số trống (nếu phương thức được gọi) hoặc lỗi máy chủ 500. Tôi bắt đầu chơi với mọi sự kết hợp có thể có của các câu trả lời và cuối cùng đã có kết quả.

Trong trường hợp của tôi, giải pháp như sau:

Tập lệnh - xâu chuỗi mảng ban đầu (không sử dụng thuộc tính được đặt tên)

    $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        url: mycontrolleraction,
        data: JSON.stringify(things)
    });

Và trong phương thức bộ điều khiển, hãy sử dụng [FromBody]

    [HttpPost]
    public IActionResult NewBranch([FromBody]IEnumerable<Thing> things)
    {
        return Ok();
    }

Các lỗi bao gồm:

  • Đặt tên cho nội dung

    data: {content: node}, // Lỗi máy chủ 500

  • Không có contentType = Lỗi máy chủ 500

Ghi chú

  • dataTypelà không cần thiết, mặc dù một số câu trả lời nói gì, vì điều đó được sử dụng để giải mã phản hồi (vì vậy không liên quan đến yêu cầu ví dụ ở đây).
  • List<Thing> cũng hoạt động trong phương thức bộ điều khiển

10

Tôi có câu trả lời hoàn hảo cho tất cả điều này: Tôi đã thử rất nhiều giải pháp mà cuối cùng vẫn không thể xoay sở được, vui lòng tìm câu trả lời chi tiết bên dưới:

       $.ajax({
            traditional: true,
            url: "/Conroller/MethodTest",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data:JSON.stringify( 
               [
                { id: 1, color: 'yellow' },
                { id: 2, color: 'blue' },
                { id: 3, color: 'red' }
                ]),
            success: function (data) {
                $scope.DisplayError(data.requestStatus);
            }
        });

Bộ điều khiển

public class Thing
{
    public int id { get; set; }
    public string color { get; set; }
}

public JsonResult MethodTest(IEnumerable<Thing> datav)
    {
   //now  datav is having all your values
  }

Bạn nên có nhiều upvotes: truyền thống: đúng là cách khuyến cáo trên trang web Jquery
DFTR

7

Cách duy nhất tôi có thể làm cho điều này hoạt động là chuyển JSON dưới dạng một chuỗi và sau đó sử dụng deserialise nó JavaScriptSerializer.Deserialize<T>(string input), điều này khá lạ nếu đó là trình giải mã mặc định cho MVC 4.

Mô hình của tôi có danh sách các đối tượng lồng nhau và điều tốt nhất tôi có thể nhận được bằng cách sử dụng dữ liệu JSON là danh sách trên cùng để có số mục chính xác trong đó, nhưng tất cả các trường trong các mục đều rỗng.

Kiểu này chắc không khó lắm đâu.

    $.ajax({
        type: 'POST',
        url: '/Agri/Map/SaveSelfValuation',
        data: { json: JSON.stringify(model) },
        dataType: 'text',
        success: function (data) {

    [HttpPost]
    public JsonResult DoSomething(string json)
    {
        var model = new JavaScriptSerializer().Deserialize<Valuation>(json);

Để làm cho việc này hoạt động, hãy tuân thủ chặt chẽ định dạng của lệnh gọi Ajax.
Graham Laight

4

Đây là mã làm việc cho truy vấn của bạn, bạn có thể sử dụng nó.

Bộ điều khiển

    [HttpPost]
    public ActionResult save(List<ListName> listObject)
    {
    //operation return
    Json(new { istObject }, JsonRequestBehavior.AllowGet); }
    }

javascript

  $("#btnSubmit").click(function () {
    var myColumnDefs = [];
    $('input[type=checkbox]').each(function () {
        if (this.checked) {
            myColumnDefs.push({ 'Status': true, 'ID': $(this).data('id') })
        } else {
            myColumnDefs.push({ 'Status': false, 'ID': $(this).data('id') })
        }
    });
   var data1 = { 'listObject': myColumnDefs};
   var data = JSON.stringify(data1)
   $.ajax({
   type: 'post',
   url: '/Controller/action',
   data:data ,
   contentType: 'application/json; charset=utf-8',
   success: function (response) {
    //do your actions
   },
   error: function (response) {
    alert("error occured");
   }
   });

2

Bao bọc danh sách các đối tượng của bạn bằng một đối tượng khác có chứa thuộc tính khớp với tên của tham số được mong đợi bởi bộ điều khiển MVC. Bit quan trọng là trình bao bọc xung quanh danh sách đối tượng.

$(document).ready(function () {
    var employeeList = [
        { id: 1, name: 'Bob' },
        { id: 2, name: 'John' },
        { id: 3, name: 'Tom' }
    ];      

    var Employees = {
      EmployeeList: employeeList
    }

    $.ajax({
        dataType: 'json',
        type: 'POST',
        url: '/Employees/Process',
        data: Employees,
        success: function () {          
            $('#InfoPanel').html('It worked!');
        },
        failure: function (response) {          
            $('#InfoPanel').html(response);
        }
    }); 
});


public void Process(List<Employee> EmployeeList)
{
    var emps = EmployeeList;
}

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}

1
     var List = @Html.Raw(Json.Encode(Model));
$.ajax({
    type: 'post',
    url: '/Controller/action',
    data:JSON.stringify({ 'item': List}),
    contentType: 'application/json; charset=utf-8',
    success: function (response) {
        //do your actions
    },
    error: function (response) {
        alert("error occured");
    }
});

Hãy thử mã này để chuyển Danh sách các đối tượng mô hình bằng ajax. Mô hình đại diện cho IList <Model>. Sử dụng IList <Model> trong bộ điều khiển để nhận các giá trị.
Athul Nalupurakkal

0

Nếu bạn đang sử dụng ASP.NET Web API thì bạn chỉ cần vượt qua data: JSON.stringify(things).

Và bộ điều khiển của bạn sẽ trông giống như sau:

public class PassThingsController : ApiController
{
    public HttpResponseMessage Post(List<Thing> things)
    {
        // code
    }
}

0

Sửa đổi từ @veeresh i

 var data=[

                        { id: 1, color: 'yellow' },
                        { id: 2, color: 'blue' },
                        { id: 3, color: 'red' }
                        ]; //parameter
        var para={};
        para.datav=data;   //datav from View


        $.ajax({
                    traditional: true,
                    url: "/Conroller/MethodTest",
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    data:para,
                    success: function (data) {
                        $scope.DisplayError(data.requestStatus);
                    }
                });

In MVC



public class Thing
    {
        public int id { get; set; }
        public string color { get; set; }
    }

    public JsonResult MethodTest(IEnumerable<Thing> datav)
        {
       //now  datav is having all your values
      }

0

Những gì tôi đã làm khi cố gắng gửi một số dữ liệu từ một số hàng đã chọn trong DataTable sang hành động MVC:

HTML Ở đầu trang:

@Html.AntiForgeryToken()

(chỉ một hàng được hiển thị, liên kết từ mô hình):

 @foreach (var item in Model.ListOrderLines)
                {
                    <tr data-orderid="@item.OrderId" data-orderlineid="@item.OrderLineId" data-iscustom="@item.IsCustom">
                        <td>@item.OrderId</td>
                        <td>@item.OrderDate</td>
                        <td>@item.RequestedDeliveryDate</td>
                        <td>@item.ProductName</td>
                        <td>@item.Ident</td>
                        <td>@item.CompanyName</td>
                        <td>@item.DepartmentName</td>
                        <td>@item.ProdAlias</td>
                        <td>@item.ProducerName</td>
                        <td>@item.ProductionInfo</td>
                    </tr>
                }

Nút khởi động hàm JavaScript:

 <button class="btn waves-effect waves-light btn-success" onclick="ProcessMultipleRows();">Start</button>

Hàm JavaScript:

  function ProcessMultipleRows() {
            if ($(".dataTables_scrollBody>tr.selected").length > 0) {
                var list = [];
                $(".dataTables_scrollBody>tr.selected").each(function (e) {
                    var element = $(this);
                    var orderid = element.data("orderid");
                    var iscustom = element.data("iscustom");
                    var orderlineid = element.data("orderlineid");
                    var folderPath = "";
                    var fileName = "";

                    list.push({ orderId: orderid, isCustomOrderLine: iscustom, orderLineId: orderlineid, folderPath: folderPath, fileName : fileName});
                });

                $.ajax({
                    url: '@Url.Action("StartWorkflow","OrderLines")',
                    type: "post", //<------------- this is important
                    data: { model: list }, //<------------- this is important
                    beforeSend: function (xhr) {//<--- This is important
                      xhr.setRequestHeader("RequestVerificationToken",
                      $('input:hidden[name="__RequestVerificationToken"]').val());
                      showPreloader();
                    },
                    success: function (data) {

                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {

                    },
                     complete: function () {
                         hidePreloader();
                    }
                });
            }
        }

Hành động MVC:

[HttpPost]
[ValidateAntiForgeryToken] //<--- This is important
public async Task<IActionResult> StartWorkflow(IEnumerable<WorkflowModel> model)

Và MODEL trong C #:

public class WorkflowModel
 {
        public int OrderId { get; set; }
        public int OrderLineId { get; set; }
        public bool IsCustomOrderLine { get; set; }
        public string FolderPath { get; set; }
        public string FileName { get; set; }
 }

PHẦN KẾT LUẬN:

Lý do cho LỖI:

"Failed to load resource: the server responded with a status of 400 (Bad Request)"

Thuộc tính Is: [ValidateAntiForgeryToken]cho hành động MVCStartWorkflow

Giải pháp trong cuộc gọi Ajax:

  beforeSend: function (xhr) {//<--- This is important
                      xhr.setRequestHeader("RequestVerificationToken",
                      $('input:hidden[name="__RequestVerificationToken"]').val());
                    },

Để gửi Danh sách các đối tượng, bạn cần tạo dữ liệu như trong ví dụ (điền đối tượng danh sách) và:

dữ liệu: {model: list},

gõ: "đăng",


0

Đây là cách nó hoạt động tốt với tôi:

var things = [
    { id: 1, color: 'yellow' },
    { id: 2, color: 'blue' },
    { id: 3, color: 'red' }
];

$.ajax({
    ContentType: 'application/json; charset=utf-8',
    dataType: 'json',
    type: 'POST',
    url: '/Controller/action',
    data: { "things": things },
    success: function () {
        $('#result').html('"PassThings()" successfully called.');
    },
    error: function (response) {
        $('#result').html(response);
    }
});

Với "ContentType" viết hoa "C".

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.