简体   繁体   English

使用 jQuery Ajax 将对象列表传递给 MVC 控制器方法

[英]Passing A List Of Objects Into An MVC Controller Method Using jQuery Ajax

I'm trying to pass an array of objects into an MVC controller method using jQuery's ajax() function.我正在尝试使用 jQuery 的 ajax() 函数将对象数组传递到 MVC 控制器方法中。 When I get into the PassThing() C# controller method, the argument "things" is null.当我进入 PassThing() C# 控制器方法时,参数“things”为空。 I've tried this using a type of List for the argument, but that doesn't work either.我已经尝试使用 List 类型作为参数,但这也不起作用。 What am I doing wrong?我究竟做错了什么?

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

Using NickW's suggestion, I was able to get this working using things = JSON.stringify({ 'things': things });使用 NickW 的建议,我能够使用things = JSON.stringify({ 'things': things }); Here is the complete code.这是完整的代码。

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

There are two things I learned from this:我从中学到了两点:

  1. The contentType and dataType settings are absolutely necessary in the ajax() function. contentType 和 dataType 设置在 ajax() 函数中是绝对必要的。 It won't work if they are missing.如果它们丢失,它将无法正常工作。 I found this out after much trial and error.经过多次试验和错误,我发现了这一点。

  2. To pass in an array of objects to an MVC controller method, simply use the JSON.stringify({ 'things': things }) format.要将对象数组传递给 MVC 控制器方法,只需使用 JSON.stringify({ 'things': things }) 格式。

I hope this helps someone else!我希望这对其他人有帮助!

Couldn't you just do this?你就不能这样做吗?

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

...and mark your action with ...并用

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

I am using a .Net Core 2.1 Web Application and could not get a single answer here to work.我正在使用 .Net Core 2.1 Web 应用程序,但无法在此处获得单一答案。 I either got a blank parameter (if the method was called at all) or a 500 server error.我要么得到一个空白参数(如果调用了该方法),要么得到一个 500 服务器错误。 I started playing with every possible combination of answers and finally got a working result.我开始尝试所有可能的答案组合,最后得到了一个有效的结果。

In my case the solution was as follows:在我的情况下,解决方案如下:

Script - stringify the original array (without using a named property)脚本 - 对原始数组进行字符串化(不使用命名属性)

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

And in the controller method, use [FromBody]在控制器方法中,使用 [FromBody]

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

Failures include:失败包括:

  • Naming the content命名内容

    data: { content: nodes }, // Server error 500 data: { content: nodes }, // 服务器错误 500

  • Not having the contentType = Server error 500没有 contentType = 服务器错误 500

Notes笔记

  • dataType is not needed, despite what some answers say, as that is used for the response decoding (so not relevant to the request examples here).尽管有些答案说了什么,但不需要dataType ,因为它用于响应解码(因此与此处的请求示例无关)。
  • List<Thing> also works in the controller method List<Thing>也适用于控制器方法

Formatting your data that may be the problem.格式化可能是问题的数据。 Try either of these:尝试以下任何一种:

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

Or (from How can I post an array of string to ASP.NET MVC Controller without a form? )或者(来自How can I post a array of string to ASP.NET MVC Controller without a form?

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

I have perfect answer for all this : I tried so many solution not able to get finally myself able to manage , please find detail answer below:我对这一切都有完美的答案:我尝试了很多解决方案,最终无法让自己能够管理,请在下面找到详细答案:

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

Controler控制器

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
  }

The only way I could get this to work is to pass the JSON as a string and then deserialise it using JavaScriptSerializer.Deserialize<T>(string input) , which is pretty strange if that's the default deserializer for MVC 4.我可以让它工作的唯一方法是将 JSON 作为字符串传递,然后使用JavaScriptSerializer.Deserialize<T>(string input)对其进行反序列化,如果这是 MVC 4 的默认反序列化器,这很奇怪。

My model has nested lists of objects and the best I could get using JSON data is the uppermost list to have the correct number of items in it, but all the fields in the items were null.我的模型有嵌套的对象列表,使用 JSON 数据我能得到的最好的结果是最上面的列表,其中包含正确数量的项目,但项目中的所有字段都是空的。

This kind of thing should not be so hard.这种事情不应该那么难。

    $.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);

This is working code for your query,you can use it.这是您查询的工作代码,您可以使用它。

Controler控制器

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

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

This is how it works fine to me:这对我来说效果很好:

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

With "ContentType" in capital "C".使用大写“C”中的“ContentType”。

I can confirm that on asp.net core 2.1, removing the content type made my ajax call work.我可以确认在 asp.net core 2.1 上,删除内容类型使我的 ajax 调用工作。

function PostData() {
    var answer = [];

    for (let i = 0; i < @questionCount; i++) {
        answer[i] = $(`#FeedbackAnswer${i}`).dxForm("instance").option("formData");
    }

    var answerList = { answers: answer }

    $.ajax({
        type: "POST",
        url: "/FeedbackUserAnswer/SubmitForm",
        data: answerList ,
        dataType: 'json',
        error: function (xhr, status, error) { },
        success: function (response) { }
    });
}
[HttpPost]
public IActionResult SubmitForm(List<Feedback_Question> answers)
{}

Wrapping your list of objects with another object containing a property that matches the name of the parameter which is expected by the MVC controller works.使用包含与 MVC 控制器预期的参数名称匹配的属性的另一个对象包装您的对象列表。 The important bit being the wrapper around the object list.重要的一点是对象列表的包装器。

$(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; }
}
     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");
    }
});

Removing contentType just worked for me in asp.net core 3.1在 asp.net core 3.1 中删除contentType对我有用

All other methods failed所有其他方法均失败

If you are using ASP.NET Web API then you should just pass data: JSON.stringify(things) .如果您使用的是 ASP.NET Web API,那么您应该只传递data: JSON.stringify(things)

And your controller should look something like this:你的控制器应该是这样的:

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

Modification from @veeresh i来自@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
      }

What I did when trying to send some data from several selected rows in DataTable to MVC action:我在尝试将一些数据从 DataTable 中的几个选定行发送到 MVC 操作时做了什么:

HTML At the beginning of a page: HTML 在页面的开头:

@Html.AntiForgeryToken()

(just a row is shown, bind from model): (只显示一行,从模型绑定):

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

Button which starts the JavaScript function:启动 JavaScript 函数的按钮:

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

JavaScript function: 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();
                    }
                });
            }
        }

MVC action: MVC 动作:

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

And MODEL in C#:和 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; }
 }

CONCLUSION:结论:

The reason for ERROR:错误的原因:

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

Is attribute: [ValidateAntiForgeryToken] for the MVC action StartWorkflow是属性:MVC 操作StartWorkflow[ValidateAntiForgeryToken]

Solution in Ajax call: Ajax 调用中的解决方案:

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

To send List of objects you need to form data like in example (populating list object) and:要发送对象列表,您需要形成示例中的数据(填充列表对象),并且:

data: { model: list },数据:{模型:列表},

type: "post",类型:“帖子”,

Nothing worked for me in asp.net core 3.1.在 asp.net core 3.1 中没有什么对我有用。 Tried all the above approaches.尝试了以上所有方法。 If nothing is working and someone is reading the rows from table and wanted to pass it to Action method try below approach... This will definitely work...如果没有任何工作,并且有人正在读取表中的行并想将其传递给 Action 方法,请尝试以下方法......这肯定会工作......

<script type="text/javascript">
    $(document).ready(function () {

        var data = new Array();
      var things = {};

      // make sure id and color properties match with model (Thing) properties
      things.id = 1;
      things.color = 'green';

      data.push(things);

      Try the same thing for dynamic data as well that is coming from table.

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

        $.ajax({
            contentType: 'application/json;',
            type: 'POST',
            url: 'your url goes here',
            data: JSON.stringify(things)
        });
    });
</script>

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用jQuery Ajax将对象列表传递到ActionResult MVC控制器方法 - Passing A List Of Objects Into An ActionResult MVC Controller Method Using jQuery Ajax 使用jQuery Ajax将单个对象传递到MVC控制器方法 - Passing A Single Objects Into An MVC Controller Method Using jQuery Ajax 使用ajax调用在控制器中传递对象列表 - passing list of objects in controller using ajax call 使用Ajax调用的MVC - 不将对象传递给控制器​​方法 - MVC with Ajax call - not passing object to controller method 通过查询字符串将对象列表传递给 MVC Controller - Passing List of objects via querystring to MVC Controller 数据未从jquery ajax调用传递到我的mvc4控制器中的actionresult方法中 - Data not passing into actionresult method in my mvc4 controller from a jquery ajax call JQuery函数Ajax方法不在MVC中调用控制器 - JQuery Function Ajax method not calling controller in MVC 使用window.location在AJAX成功中将对象传递给MVC控制器方法 - Passing an object to MVC controller method in AJAX success using window.location 使用 Html.BeginForm() ASP.NET MVC 将对象列表从控制器传递到视图时出错 - Error when passing list of objects from Controller to View using Html.BeginForm() ASP.NET MVC 将对象列表传递给 Controller - Passing List of Objects to Controller
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM