web-dev-qa-db-ja.com

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

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"だけです...

任意のヒント?

175
rodbv

応答を変更して、実行したテストアプリのコードを含めました。

更新: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'」というアラートが表示されます。お役に立てれば!

239
MrDustpan

参考までに、JQueryは投稿データをシリアル化する方法を変更しました。

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

「トラディショナル」設定をtrueに設定する必要があります。

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

として出てきます

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

の代わりに

Values=1&Values=2&Values=3
105
Dustin Davis

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

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

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

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

8
Craig Stuntz

.NET4.5で、MVC 5

Javascript:

jSのオブジェクト: enter image description here

投稿するメカニズム。

    $('.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)
{
....
}

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

enter image description here

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

6

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

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) 
    });
}
4
d.popov

here で説明したように、

カスタム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);
}
1
Mohsen Afshin

でグローバルパラメータを設定できます

jQuery.ajaxSettings.traditional = true;
0
mr_squall