AJAX経由で配列をmvcアクションに渡す


123

AJAXを介してMVCアクションに整数の配列(またはIEnumerable)を渡そうとしていますが、少し助けが必要です。

JavaScriptは

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...

コントローラのアクションは

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

現時点では、リクエストは次のようにフォーマットされています

controller/MyAction?_=1301503418429&arrayOfValues[]=491&arrayOfValues[]=368&arrayOfValues[]=235&arrayOfValues[]=437

だから私はほとんどそこにいます、角括弧を外すと正しい応答が得られます。コントローラがそれが何であるかを認識できるように、その配列をgetにどのように渡す必要がありますか?

ご協力いただき誠にありがとうございます

デイブ

回答:


149

getを呼び出す前に、従来のプロパティをtrueに設定します。つまり:

jQuery.ajaxSettings.traditional = true

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {... 

3
ありがとうございました!従来のajaxと非従来のajaxの違いを概説できますか?アプリケーションの残りの部分に対して行っていることをよりよく理解したいと思います。
トム・ブナ

5
単一の通話に従来の設定を追加することもできます。その後、残りの部分には影響しません
Gluip 2013

1
この答えは正しいですが、1回の呼び出しに「従来」を設定する場合は、@ RionWilliamsの答えを確認してください。両方に投票します。ありがとう!
kzfabi 2013年

@Tom Beech jQuery 1.4以降、$。param()メソッドはディープオブジェクトを再帰的にシリアル化して、PHPやRuby on Railsなどの最新のスクリプト言語やフレームワークに対応します。この機能をグローバルに無効にするには、jQuery.ajaxSettings.traditional = true;を設定します。
Alexey Shevelyov 2015年

これらの回答はどれもうまくいきませんでした(おそらく私のコントローラーがAPIコントローラーだったためでしょうか?)、しかし私は次のSOの回答で私の解決策を見つけました:stackoverflow.com/a/11100414/1751792
Lopsided

119

過去にPOSTを実行しようとしたときに問題が発生しました(それが実際に行っていることかどうかはわかりませんが、配列を渡すときは、従来の設定をtrueに設定する必要があることを思い出します)

 var arrayOfValues = new Array();

 //Populate arrayOfValues 
 $.ajax({ 
      type: "POST",
      url: "<%= Url.Action("MyAction","Controller")%>",
      traditional: true,
      data: { 'arrayOfValues': arrayOfValues }              
 });

4
これは、一部の人々が示唆するように、単にweb.configファイルでグローバルに設定するよりもはるかに優れています。もう1つには独自の良い機会がありますが、デフォルトの解決策はあなたのものです。
Panzercrisis 2015

これはパラメータとしてActionResultにデータを送信するだけです。ActionResult内のコードを呼び出しますか?たとえば、arrayofvaluesをデータベースに挿入するコードがある場合、そのコードは実行されますか?
Saurabh

これは私が必要とするものを正確に解決しました。これを追加して、次のようにコントローラーで取得するまで、私の配列はコントローラーでnullとして戻ってきました:IEnumerable <string> array
SeanMC

52

かなり遅いですが、すでにここにあるものに対する異なる答え:

$.ajax速記関数$.getまたはを使用する代わりに、次のように$.post配列を渡すことができます。


短縮GET

var array = [1, 2, 3, 4, 5];
$.get('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
public void MyAction(List<int> data)
{
    // do stuff here
}

略記POST

var array = [1, 2, 3, 4, 5];
$.post('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
[HttpPost]
public void MyAction(List<int> data)
{
    // do stuff here
}


ノート:

  • のブールパラメータ$.paramtraditionalプロパティ用で あり、これが機能するtrueために必要です

2
伝統的な財産についてのヒントをありがとう。C#のパラメーターがnullである理由を理解できませんでした。タイプ「int []」もC#アクションメソッドで機能することがわかりました。
Dan Randolph

9

あなたはこれをうまく行うことができるはずです:

$.ajax({
   url: 'controller/myaction',
   data: JSON.stringify({
      myKey: myArray
   }),
   success: function(data) { /* Whatever */ }
});

次に、アクションメソッドは次のようになります。

public ActionResult(List<int> myKey)
{
    // Do Stuff
}

あなたにとっては、あなたはあなたの値を文字列化する必要があるように見えます。MVCのJSONValueProviderは、それをIEnumerableに変換し直します。


回答ありがとうございます。traditionalをtrueに設定する必要があるようです。これもうまくいくと思うので賛成票を投じました。
デイブ

9

「従来の」オプションを使用する答えは正しいです。詳細を知りたい人のために、背景情報をもう少し提供しています。

jQueryドキュメントから:

jQuery 1.8以降、$。param()メソッドはデフォルト設定としてjQuery.ajaxSettings.traditionalを使用せず、デフォルトでfalseになります。

詳細については、こちらもご覧ください。http//michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers および http://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

HTH


2

他のすべてが失敗した場合...

ここの他の答えはどれも私の問題を解決しませんでした。JavaScriptからMVC Web APIコントローラーにGETメソッド呼び出しを行い、整数の配列をその要求内のパラメーターとして送信しようとしました。私はここですべての解決策を試しましたが、それでも私のコントローラーのパラメーターはNULL(またはVBユーザーにとっては何も)になりませんでした。

私は最終的に別のSOポストで解決策を見つけましたが、それは実際には非常に簡単でした:[FromUri]コントローラーの配列パラメーターの前に注釈を追加するだけです(ブラケットの注釈を避けるために、「従来の」AJAX設定を使用して呼び出しを行わなければなりませんでした)。アプリケーションで使用した実際のコードについては、以下を参照してください。


コントローラーの署名:

コントローラの署名 注:C#の注釈は [FromUri]


JavaScript:

$.get('/api/InventoryApi/GetBalanceField', $.param({productIds: [42], inventoryFormId: 5493, inventoryBalanceType: 'Beginning'},true)).done(function(data) {console.log(data);});

実際のURL文字列:

http://randomhostname/api/InventoryApi/GetBalanceField?productIds=42&inventoryFormId=5493&inventoryBalanceType=Beginning

2

ここでは少し遅れますが、SNagのソリューションをさらに$ .ajax()に使用できます。誰かを助ける場合のコードは次のとおりです。

var array = [1, 2, 3, 4, 5];

$.ajax({
    type: "GET",
    url: '/controller/MyAction',
    data: $.param({ data: array}, true),
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
    },
    error: function (x, y, z) {
    }
});

// Action Method
public void MyAction(List<int> data)
{
    // do stuff here
}

1

私のように.Net Framework MVCからASP.NET Core MVCに移行する場合、状況は少し異なります。ajax呼び出しは、そのデータを渡すの{ vals: arrayOfValues }ではなくJSON.stringify(arrayOfValues)、次のように、stringifyを使用してrawオブジェクト上で行う必要があります。

$.ajax({
   url: 'controller/myaction',
   data: JSON.stringify(arrayOfValues),
   success: function(data) { /* Whatever */ }
});

ASP.NET Coreで行われたもう1つの変更は、クロスサイトリクエストフォージェリを防止することです。そのため、ajaxメソッドからMVCアクションへの呼び出しの場合、[FromBody]次のように属性をアクションパラメーターに適用する必要があります。

public ActionResult MyAction([FromBody] IEnumerable<int> arrayOfValues )

これは、データを送信する方法の他のすべての順列が失敗した後、信じられないほど役に立ちました!
NibblyPig

0

ASP.NET Core MVCを使用していて、角括弧を処理する必要がある場合(jQueryの「従来の」オプションを使用するのではなく)、私が見つけた唯一のオプションIEnumerableは、コントローラーメソッドで手動でを構築することです。

string arrayKey = "p[]=";
var pArray = HttpContext.Request.QueryString.Value
    .Split('&')
    .Where(s => s.Contains(arrayKey))
    .Select(s => s.Substring(arrayKey.Length));

0

私はasp.netコア2.2とjqueryを使用して、ビューから複雑なオブジェクト(「メインクラス」)を、単純なデータフィールドといくつかの配列を持つコントローラーに送信する必要があります。
c#の「メインクラス」定義に配列を追加し(以下を参照)、ajax(post)を介して(正しく入力された)配列を送信するとすぐに、コントローラー内のオブジェクト全体がnullになりました。
最初に、私のajax呼び出しに対する「伝統的:真」の欠落が理由であると私は思ったが、これはそうではない。
私の場合、その理由はC#の「メインクラス」での定義でした。
「メインクラス」では、私は持っていました:

public List<EreignisTagNeu> oEreignistageNeu { get; set; }

EreignisTagNeuは次のように定義されました。

public class EreignisTagNeu
{
 public int iHME_Key { get; set; } 
}

「メインクラス」の定義を次のように変更する必要がありました。

 public List<int> oEreignistageNeu { get; set; }

今では動作します。
だから...私にとっては、配列のリストが「メインクラス」で完全に定義されていない場合、asp.netコアに問題があるようです(投稿に問題があります)。
注:私の場合、これはajx呼び出しに対して「traditional:true」の有無にかかわらず機能します。


-3

配列を文字列に変換する必要があります:

//arrayOfValues = [1, 2, 3];  
$.get('/controller/MyAction', { arrayOfValues: "1, 2, 3" }, function (data) {...

これは、int、long、またはstringの形式でも機能します

public ActionResult MyAction(int[] arrayOfValues )

これは、サーバーに配列を送信するための正しい構文ではありません。オブジェクトを渡して、それが配列であると想定しているだけです。これは、提供された文字列では当てはまりません。
Twister1002
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.