jQuery Ajaxを使用してオブジェクトのリストをMVCコントローラーメソッドに渡す


113

jQueryのajax()関数を使用して、オブジェクトの配列をMVCコントローラーメソッドに渡そうとしています。PassThing()C#コントローラーメソッドに入ると、引数 "things"がnullです。引数にリストのタイプを使用してこれを試しましたが、それも機能しません。何が悪いのですか?

<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
データは文字列ですが、メソッドは配列を受け入れます。文字列を受け入れるようにメソッドを変更し、メソッド内で文字列を逆シリアル化します。
ボブ・ホーン

2
あなたのコードは正しいです。私はそれをテストし、MVC 4を使用して動作しました。それを理解するために、より多くのデータを提供してください。
ディエゴ

これは素晴らしいことですが、渡す文字列のリストだけでなく、文字列のリストに関連付けられた別のIDを含める必要がある場合はどうでしょうか。つまり、グループID、グループIDの下にあるグループのリストなどです。
Nathan McKaskle 2017

回答:


188

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

これから学んだことは2つあります。

  1. contentTypeおよびdataType設定は、ajax()関数で絶対に必要です。それらがない場合は機能しません。多くの試行錯誤の末、私はこれを発見しました。

  2. オブジェクトの配列をMVCコントローラーメソッドに渡すには、JSON.stringify({'things':things})形式を使用します。

これが他の誰かの役に立つことを願っています!


8
私は同じ問題を抱えていて、contentTypeを追加して修正しました。ありがとう!
ロシェルC

9
注意すべき2つのこと:JSON.stringifyと 'contentType'の指定。
dinesh ygv 2014年

クラッド。まだ私のために働いていません。私のリクエストURLはhttp://localhost:52459/Sales/completeSale?itemsInCart=[{"ItemId":1,"Quantity":"1","Price":3.5}]Sales.completeSaleありpublic ActionResult completeSale(ItemInCart[] itemsInCart)、として注釈が付けられていHttpGetます。
abalter 2015年

3
理由を問わず、私はただ使用しなければなりませんでしたdata: JSON.stringify(things),
Rob Scott

1
dataType必要ありません。省略した場合、ajax関数は返されたデータに基づいて処理します

32

あなたはこれを行うことができませんでしたか?

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

3
これが最良の答えです。この場合、JSON.stringifyは使用しないでください

これは私には機能しません。[HttpPost] public int SaveResults(List <ShortDetail> model){}および$ .post( "@ Url.Action(" SaveResults "、" Maps ")"、{model: dataItems}、関数(結果){});
Samra 2017

2
それは私のために働いた。絶対最良の答えです。Halcyonの実装が機能しなかった理由がわかりません。PassThings関数が呼び出されましたが、呼び出しの直前にJavaScriptに入力されていても、「things」入力変数は空でした。
Leonardo Daga

13

問題となる可能性のあるデータのフォーマット。次のいずれかを試してください。

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

または(文字列の配列をフォームなしでASP.NET MVCコントローラーに投稿するにどうすればよいですか?

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

コードは閉じていますが、機能しません。私はあなたの提案のおかげでコードを機能させることができました。上記の私の答えを参照してください。
Halcyon

12

私は.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();
    }

失敗には次のものがあります。

  • コンテンツに名前を付ける

    データ:{コンテンツ:ノード}、//サーバーエラー500

  • contentTypeがない=サーバーエラー500

ノート

  • dataType応答のデコードに使用されるため、いくつかの回答が言っているにもかかわらず、それは必要ありません(したがって、要求には関係ありません)ここで例に)。
  • List<Thing> コントローラメソッドでも機能します

10

私はこれすべてに完全な答えを持っています:私は最終的に自分自身を管理することができないように多くの解決策を試みました、以下の詳細な答えを見つけてください:

       $.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 Webサイトで推奨される方法はtrueです
DFTR

7

これを機能させる唯一の方法は、JSONを文字列として渡し、を使用してデシリアライズすることですJavaScriptSerializer.Deserialize<T>(string input)。これがMVC 4のデフォルトのデシリアライザーである場合、これはかなり奇妙です。

私のモデルにはオブジェクトのネストされたリストがあり、JSONデータを使用して取得できる最高のリストは、正しい数のアイテムを含む最上部のリストですが、アイテムのすべてのフィールドがnullでした。

この種のことはそれほど難しくないはずです。

    $.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呼び出しの形式に厳密に従ってください。
Graham Laight

4

これはクエリの作業コードです。使用できます。

コントローラー

    [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

オブジェクトのリストを、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; }
}

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

ajaxを使用してモデルオブジェクトのリストを渡すには、このコードを試してください。ModelはIList <Model>を表します。値を取得するには、コントローラーでIList <Model>を使用します。
Athul Nalupurakkal 2017年

0

ASP.NET Web APIを使用している場合は、単に渡す必要があり data: JSON.stringify(things)ます。

そして、コントローラーは次のようになります。

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

0

@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

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

Is属性:[ValidateAntiForgeryToken]MVCアクション用StartWorkflow

Ajax呼び出しの解決策:

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

オブジェクトのリストを送信するには、例のようにデータを形成する必要があります(リストオブジェクトにデータを入力する)。

データ:{モデル:リスト}、

タイプ:「投稿」、


0

これは私にとってそれがうまくいく方法です:

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

大文字の「C」で「ContentType」を使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.