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


185

私はASP.NET MVCとJQueryを教えるための小さなアプリを作成しています。ページの1つは、いくつかを選択できるアイテムのリストです。次に、ボタンを押して、JQueryのPost関数を使用して、選択された項目のIDを含むリスト(または同等のもの)をコントローラーに送信します。

選択された要素のIDを含む配列をなんとか取得し、それを投稿したいと思います。これを行う方法の1つは、非表示の値を使用してページにダミーのフォームを作成し、選択したアイテムで非表示の値を設定して、そのフォームを投稿することです。しかし、これは粗末に見えます。

アレイをコントローラーに直接送信することで、これを実現するためのより明確な方法はありますか?いくつかのことを試しましたが、コントローラーが受信データをマップできないようです。これまでのコードは次のとおりです。

function generateList(selectedValues) {
   var s = {
      values: selectedValues //selectedValues is an array of string
   };
   $.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}

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

public ActionResult GenerateList(List<string> values)
{
    //do something
}

私が何とかして得たのは、コントローラーパラメーターの「null」だけです...

任意のヒント?


ただし、次を使用して同じデータにアクセスできますRequest["values[]"]
Tocco

回答:


247

私が行ったテストアプリのコードを含めるように応答を変更しました。

更新:jQueryを更新して 'traditional'設定をtrueに設定し、これが再び機能するようにします(@DustinDavisの回答に従って)。

まず、JavaScript:

function test()
{
    var stringArray = new Array();
    stringArray[0] = "item1";
    stringArray[1] = "item2";
    stringArray[2] = "item3";
    var postData = { values: stringArray };

    $.ajax({
        type: "POST",
        url: "/Home/SaveList",
        data: postData,
        success: function(data){
            alert(data.Result);
        },
        dataType: "json",
        traditional: true
    });
}

そして、これが私のコントローラクラスのコードです:

public JsonResult SaveList(List<String> values)
{
    return Json(new { Result = String.Format("Fist item in list: '{0}'", values[0]) });
}

そのJavaScript関数を呼び出すと、「リストの最初の項目: 'item1'」という警告が表示されます。お役に立てれば!


3
この回答を見つけてよかったです。Guidの配列を送信でき、ActionがそれらをList <Guid>に受信します。おかげで
Tx3の

43
ここで注意すべき重要なことが2つあります。1)dataType: "json" 2。)トラディショナル:true。これらがないと、文字列配列はアクションメソッドに渡されません
Thanigainathan

1
dataType: 'JSON'jQueryは応答をJSONとして解析しようとし、それが有効なJSONでない場合はエラーになることに注意してください。
Sennett 2013年

8
@ThanigainathanはdataType: 'json'戻り値の型であり、配列をActionに送信する必要はありません。contentType: "application/json; charset=utf-8"がその1つですが、このような必要がない場合もあります。
Ruchan 2014年

1
@emzeroの使用var postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };
Nick M

108

参考:jQueryは投稿データのシリアル化方法を変更しました。

http://forum.jquery.com/topic/nested-param-serialization

'Traditional'設定をtrueに設定する必要があります。それ以外の場合は

{ Values : ["1", "2", "3"] }

として出てきます

Values[]=1&Values[]=2&Values[]=3

の代わりに

Values=1&Values=2&Values=3

8
これは、しばらく頭を痛めつけたものです。設定$.ajax({ ..., traditional: true});は、従来のシリアル化に戻すのに役立ちます。
juhan_h 2011年

ASP.NET MVCルートが文字列値の単純なjs配列を適切に消費するために、これが必要でした。
BrandonG 2016年

あなたの答えは本当に役に立ちます。私も同じ状況ですが、ですints。私がを使用するtraditional: trueとうまくいきます。あなたの答えとリンクがその理由を説明しています。を使用type: "POST"せずにを使用した場合にも機能しtraditional: trueます。何故ですか?詳しく説明してください。参考までに、Asp.Net Mvcを使用しています。
バーンズ2016

ASP.NETで、インデックスなしでこのような匿名配列を解析する方法はありますか?値[] = 1&値[] = 2&値[] = 3
チャールズオーウェン

24

答えてくれてありがとう。別の簡単な解決策は、jQuery.paramメソッドを使用して従来のパラメーターをtrueに設定し、JSONオブジェクトを文字列に変換することです

$.post("/your/url", $.param(yourJsonObject,true));

$ .ajax()の代わりに$ .post()を使用しているため、うまく機能し、完全に適合します。ありがとうございました !
AFract、2013

9

データを配列として投稿しないでください。 リストにバインドするには、キーと値のペアを各キーに同じ値で送信する必要があります。

これを行うためのフォームは必要ありません。必要なのは、キーと値のペアのリストだけです。これは、$。postの呼び出しに含めることができます。


3
ありがとう。更新されたURLは次のとおり
Wiebe Tijsma

6

.NET4.5MVC 5

JavaScript:

JSのオブジェクト: ここに画像の説明を入力してください

投稿するメカニズム。

    $('.button-green-large').click(function() {
        $.ajax({
            url: 'Quote',
            type: "POST",
            dataType: "json",
            data: JSON.stringify(document.selectedProduct),
            contentType: 'application/json; charset=utf-8',
        });
    });

C#

オブジェクト:

public class WillsQuoteViewModel
{
    public string Product { get; set; }

    public List<ClaimedFee> ClaimedFees { get; set; }
}

public partial class ClaimedFee //Generated by EF6
{
    public long Id { get; set; }
    public long JourneyId { get; set; }
    public string Title { get; set; }
    public decimal Net { get; set; }
    public decimal Vat { get; set; }
    public string Type { get; set; }

    public virtual Journey Journey { get; set; }
}

コントローラ:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}

受け取ったオブジェクト:

ここに画像の説明を入力してください

これにより時間を節約できることを願っています。


4

文字列だけでなく、オブジェクトのリストでも機能する別の実装:

JS:

var postData = {};
postData[values] = selectedValues ;

$.ajax({
    url: "/Home/SaveList",
    type: "POST",
    data: JSON.stringify(postData),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(data){
        alert(data.Result);
    }
});

「selectedValues」がオブジェクトの配列であると仮定します。

コントローラーでは、パラメーターは対応するViewModelのリストです。

public JsonResult SaveList(List<ViewModel> values)
{    
    return Json(new { 
          Result = String.Format("Fist item in list: '{0}'", values[0].Name) 
    });
}

1

ここで説明したように

カスタムJSONオブジェクトをMVCアクションに渡したい場合は、このソリューションを使用できます。これは魅力のように機能します。

public string GetData() {
  // InputStream contains the JSON object you've sent
  String jsonString = new StreamReader(this.Request.InputStream).ReadToEnd();

  // Deserialize it to a dictionary
  var dic =
    Newtonsoft.Json.JsonConvert.DeserializeObject < Dictionary < String,
    dynamic >> (jsonString);

  string result = "";

  result += dic["firstname"] + dic["lastname"];

  // You can even cast your object to their original type because of 'dynamic' keyword
  result += ", Age: " + (int) dic["age"];

  if ((bool) dic["married"])
    result += ", Married";

  return result;
}

このソリューションの本当の利点は、引数の組み合わせごとに新しいクラスを定義する必要がなく、さらに、オブジェクトを元の型に簡単にキャストできることです。

次のようなヘルパーメソッドを使用して、作業を容易にすることができます。

public static Dictionary < string, dynamic > GetDic(HttpRequestBase request) {
  String jsonString = new StreamReader(request.InputStream).ReadToEnd();
  return Newtonsoft.Json.JsonConvert.DeserializeObject < Dictionary < string, dynamic >> (jsonString);
}

0

あなたはグローバルパラメータを設定することができます

jQuery.ajaxSettings.traditional = true;

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