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

Posted

技术标签:

【中文标题】使用 jQuery Ajax 将对象列表传递给 MVC 控制器方法【英文标题】:Passing A List Of Objects Into An MVC Controller Method Using jQuery Ajax 【发布时间】:2012-10-25 21:31:59 【问题描述】:

我正在尝试将对象数组传递给 MVC 控制器方法,使用 jQuery 的 ajax() 函数。当我进入 PassThing() C# 控制器方法时, 参数“事物”为空。我已经尝试使用一种 List for 论点,但这也不起作用。我做错了什么?

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

【问题讨论】:

你可以试试JavaScriptSerializer.Deserialize Method (String, Type) 您的数据是一个字符串,但您的方法接受一个数组。改变你的方法来接受一个字符串,然后在方法中反序列化它。 您的代码是正确的。我对其进行了测试,它使用 MVC 4 工作。请提供更多数据来解决这个问题。 这是很棒的东西,但是如果您不仅需要要传递的字符串列表,还需要包含与字符串列表关联的单独 id 怎么办?就像,组 id,组 id 下的组列表。 【参考方案1】:

根据 NickW 的建议,我可以使用 things = JSON.stringify( 'things': things ); 来完成这项工作。这是完整的代码。

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

我从中学到了两点:

    在 ajax() 函数中,contentType 和 dataType 设置是绝对必要的。如果它们丢失,它将无法正常工作。经过多次试验和错误,我发现了这一点。

    要将对象数组传递给 MVC 控制器方法,只需使用 JSON.stringify( 'things': things ) 格式。

我希望这对其他人有帮助!

【讨论】:

我遇到了同样的问题,添加 contentType 解决了它。谢谢! 需要注意两点:JSON.stringify 和指定 'contentType'。 无论出于何种原因我不得不使用data: JSON.stringify(things), dataType 不是必需的。如果省略,ajax 函数将根据返回数据进行处理 对于 aspnetcore 2,记得在你的控制器函数中添加 [FromBody] 否则它将不起作用。【参考方案2】:

你不能这样做吗?

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

...并用

标记您的操作
[HttpPost]
public void PassThings(IEnumerable<Thing> things)

    // do stuff with things here...

【讨论】:

这应该是最好的答案。在这种情况下不应使用 JSON.stringify 这对我不起作用..我正在使用 [HttpPost] public int SaveResults(List model) 和 $.post("@Url.Action("SaveResults", " Maps")", model: dataItems, function (result) ); 它对我有用。绝对是最好的答案。我不知道为什么 Halcyon 实施不起作用。调用了 PassThings 函数,但“things”输入变量为空,即使在调用之前它已在 javascript 中填充。【参考方案3】:

我正在使用 .Net Core 2.1 Web 应用程序,但无法在此处获得单一答案。我要么得到一个空白参数(如果调用了该方法),要么得到一个 500 服务器错误。我开始尝试所有可能的答案组合,最后得到了一个可行的结果。

在我的情况下,解决方案如下:

脚本 - 将原始数组字符串化(不使用命名属性)

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

并且在控制器方法中,使用 [FromBody]

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

失败包括:

命名内容

data: content: nodes , // 服务器错误 500

没有 contentType = 服务器错误 500

注意事项

dataType 不是必需的,尽管有些答案说了什么,因为它用于 response 解码(因此与此处的 request 示例无关)。 List&lt;Thing&gt; 也适用于控制器方法

【讨论】:

【参考方案4】:

格式化可能是问题的数据。尝试以下任何一种:

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

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

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

【讨论】:

您的代码很接近,但它不起作用。由于您的建议,我能够使代码正常工作。见我上面的回答。【参考方案5】:

我对这一切都有完美的答案:我尝试了很多解决方案都无法让自己最终能够管理,请在下面找到详细答案:

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

控制器

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
  

【讨论】:

你应该有更多的赞成票:传统的:在 Jquery 网站上是推荐的方式【参考方案6】:

我可以让它工作的唯一方法是将 JSON 作为字符串传递,然后使用 JavaScriptSerializer.Deserialize&lt;T&gt;(string input) 对其进行反序列化,如果这是 MVC 4 的默认反序列化程序,这很奇怪。

我的模型有嵌套的对象列表,使用 JSON 数据我能得到的最好结果是最上面的列表中包含正确数量的项目,但项目中的所有字段都是空的。

这种事情应该没那么难。

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

【讨论】:

要完成这项工作,请严格遵循 Ajax 调用的格式。【参考方案7】:

这是您查询的有效代码,您可以使用它。

控制器

    [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");
   
   );

【讨论】:

【参考方案8】:

这对我来说很好用:

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

“ContentType”大写“C”。

【讨论】:

你拯救了我的一天【参考方案9】:

我可以确认,在 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)

【讨论】:

【参考方案10】:

用另一个对象包装您的对象列表,该对象包含与 MVC 控制器预期的参数名称匹配的属性。 重要的一点是对象列表的包装。

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

【讨论】:

【参考方案11】:
     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");
    
);

【讨论】:

尝试使用 ajax 传递模型对象列表的代码。模型表示 IList。在控制器中使用 IList 来获取值。【参考方案12】:

删除 contentType 刚刚在 asp.net core 3.1 中为我工作

所有其他方法都失败了

【讨论】:

【参考方案13】:

如果您使用的是 ASP.NET Web API,那么您只需传递 data: JSON.stringify(things)

你的控制器应该是这样的:

public class PassThingsController : ApiController

    public HttpResponseMessage Post(List<Thing> things)
    
        // code
    

【讨论】:

【参考方案14】:

来自@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
      

【讨论】:

【参考方案15】:

当我尝试将一些数据从 DataTable 中的几个选定行发送到 MVC 操作时,我做了什么:

HTML 在页面的开头:

@Html.AntiForgeryToken()

(只显示一行,从模型绑定):

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

启动 JavaScript 函数的按钮:

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

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 动作:

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

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; 
 

结论:

错误原因:

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

是属性:[ValidateAntiForgeryToken] 用于 MVC 操作 StartWorkflow

Ajax 调用中的解决方案:

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

要发送对象列表,您需要形成示例中的数据(填充列表对象)和:

数据:模型:列表,

类型:“帖子”,

【讨论】:

以上是关于使用 jQuery Ajax 将对象列表传递给 MVC 控制器方法的主要内容,如果未能解决你的问题,请参考以下文章

通过 AJAX 调用将 JSON 对象列表传递给控制器

如何将 JSON 对象内的 JSON 数组传递给 jQuery 自动完成

使用 ajax 导入 JS 数组以传递给 JQuery 中的函数/插件

从 Django 中的 JsonResponse 中提取字段值并将其传递给 Ajax Jquery

使用 Jquery/Ajax 将模型传递给控制器

Django:如何通过 AJAX 将 PKID 列表传递给下一个视图,然后重定向