JSON、jQueryを使用して複雑なオブジェクトの配列をASP.NET MVCコントローラーに投稿する方法


92

現在のコードは次のようになります。配列をコントローラーに渡すにはどうすればよいですか?また、コントローラーアクションはどのような種類のパラメーターを受け入れる必要がありますか?

function getplaceholders() {
    var placeholders = $('.ui-sortable');
    var result = new Array();
    placeholders.each(function() {
        var ph = $(this).attr('id');
        var sections = $(this).find('.sort');
        var section;

        sections.each(function(i, item) {
            var sid = $(item).attr('id');

            result.push({ 'SectionId': sid, 'Placeholder': ph, 'Position': i });
        });
    });
    alert(result.toString());
    $.post(
        '/portal/Designer.mvc/SaveOrUpdate',
        result,
        function(data) {
            alert(data.Result);
        }, "json");
};

コントローラのアクションメソッドは次のようになります

public JsonResult SaveOrUpdate(IList<PageDesignWidget> widgets)

回答:


84

解決策を見つけました。私はSteve Gentile、jQuery、およびASP.NET MVCのソリューションを使用しています–アクションにJSONを送信する–再訪

私のASP.NET MVCビューコードは次のようになります。

function getplaceholders() {
        var placeholders = $('.ui-sortable');
        var results = new Array();
        placeholders.each(function() {
            var ph = $(this).attr('id');
            var sections = $(this).find('.sort');
            var section;

            sections.each(function(i, item) {
                var sid = $(item).attr('id');
                var o = { 'SectionId': sid, 'Placeholder': ph, 'Position': i };
                results.push(o);
            });
        });
        var postData = { widgets: results };
        var widgets = results;
        $.ajax({
            url: '/portal/Designer.mvc/SaveOrUpdate',
            type: 'POST',
            dataType: 'json',
            data: $.toJSON(widgets),
            contentType: 'application/json; charset=utf-8',
            success: function(result) {
                alert(result.Result);
            }
        });
    };

コントローラのアクションはカスタム属性で装飾されています

[JsonFilter(Param = "widgets", JsonDataType = typeof(List<PageDesignWidget>))]
public JsonResult SaveOrUpdate(List<PageDesignWidget> widgets

カスタム属性のコードはここにあります(リンクは壊れています)。

リンクが壊れているため、これはJsonFilterAttributeのコードです

public class JsonFilter : ActionFilterAttribute
{
    public string Param { get; set; }
    public Type JsonDataType { get; set; }
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
        {
            string inputContent;
            using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
            {
                inputContent = sr.ReadToEnd();
            }
            var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
            filterContext.ActionParameters[Param] = result;
        }
    }
}

JsonConvert.DeserializeObjectはJson.NETからのものです

リンク:Json.NETによるJSONのシリアライズとデシリアライズ


見栄えが良い-ブログ投稿とカスタム属性コードのリンクが機能しなくなった-再投稿できますか?
littlechris

4
このソリューションでは、クライアント側とサーバー側での変更が必要です。私はこれがずっと前に必要だったことを知っていますが、Javascriptオブジェクトをデフォルトのモデルバインダーが理解し、モデルがパラメーターにバインドする形式に変換できる単純なjQueryプラグインを使用する別のアプローチへのリンクを提供することもできます。フィルターは必要ありません。erraticdev.blogspot.com/2010/12/...私はあなたが検証エラーを解決したのか分からないが、私は同様にそのためのソリューションを持っている:erraticdev.blogspot.com/2010/11/...
ロバートKoritnik

3
JavaScriptConvert.DeserializeObjectのソース/オリジンを提供できますか?
Matthieu

これはNewtonsoft Jsonライブラリです。nugetパッケージマネージャーを開いてNewtonsoftで検索すると、表示されます(現在は2016年です)。これはおそらく明白ですが、誰かが疑問に思っている場合に備えて。
Robb Sadler

22

アクションフィルター、jquery stringify、bleh ...

ピーター、この機能はMVCにネイティブです。これは、MVCを非常に優れたものにする1つのことです。

$.post('SomeController/Batch', { 'ids': ['1', '2', '3']}, function (r) {
   ...
});

そしてアクションでは、

[HttpPost]
public ActionResult Batch(string[] ids)
{
}

魅力のように機能します:

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

jQuery 1.4+を使用している場合は、トラディショナルモードの設定を調べます。

jQuery.ajaxSettings.traditional = true;

ここで説明されているように:http : //www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters

これは複雑なオブジェクトでも機能します。興味がある場合は、モデルバインディングに関するMVCドキュメントを参照してください。http://msdn.microsoft.com/en-us/library/dd410405.aspx


1
あなたは正しいかもしれませんが、JSONモデルバインダーはMVC3にとって新しいものであり、サポートされていない2008年に質問されました。それはあなたの答えで言及する価値があります。
Piotr Owsiak

3
これは、複雑なオブジェクトの配列を渡す例ですか?
DuckMaestro

そうではありませんが、例はまだ適用されます(MVC 3+)。パラメータ名がモデルと一致している限り、問題は発生しません。
J.ミッチェル

ここで重要なのは、メソッドパラメータ名( "ids")でJSONオブジェクトを作成し、その中に複雑なオブジェクトの配列を配置することです。さらに、3番目のパラメーターを "true"にすると、従来のモードが処理されます。
redwards510 2017年

11

では.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)
{
....
}

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

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

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


8

JSONとプレーンXMLの両方を話すASP.NET MVCを使用したREST API作成の後半に向けて、引用します。

次に、HTTP POSTを介して配信されるJSONおよびXMLペイロードを受け入れる必要があります。場合によっては、クライアントがオブジェクトのコレクションを一括でアップロードするために、一度にアップロードしたいことがあります。したがって、JSON形式またはXML形式のいずれかを使用してオブジェクトをアップロードできます。ASP.NET MVCには、投稿されたJSONまたはXMLを自動的に解析し、アクションパラメーターに自動的にマッピングするネイティブサポートはありません。それで、私はそれをするフィルターを書きました。」

次に、JSONをC#オブジェクトにマップするアクションフィルターを実装し、コードを示します。


私は自分の答えを書いていました。とにかく私はそれを投稿します;-)
JSC

7

オブジェクトを文字列にシリアル化するのに役立つこのJavaScriptコードJSON2.jsを最初にダウンロードします。

私の例では、Ajaxを介してjqGridの行を投稿しています。

    var commissions = new Array();
    // Do several row data and do some push. In this example is just one push.
    var rowData = $(GRID_AGENTS).getRowData(ids[i]);
    commissions.push(rowData);
    $.ajax({
        type: "POST",
        traditional: true,
        url: '<%= Url.Content("~/") %>' + AREA + CONTROLLER + 'SubmitCommissions',
        async: true,
        data: JSON.stringify(commissions),
        dataType: "json",
        contentType: 'application/json; charset=utf-8',
        success: function (data) {
            if (data.Result) {
                jQuery(GRID_AGENTS).trigger('reloadGrid');
            }
            else {
                jAlert("A problem ocurred during updating", "Commissions Report");
            }
        }
    });

コントローラーで:

    [HttpPost]
    [JsonFilter(Param = "commissions", JsonDataType = typeof(List<CommissionsJs>))]
    public ActionResult SubmitCommissions(List<CommissionsJs> commissions)
    {
        var result = dosomething(commissions);
        var jsonData = new
        {
            Result = true,
            Message = "Success"
        };
        if (result < 1)
        {
            jsonData = new
            {
                Result = false,
                Message = "Problem"
            };
        }
        return Json(jsonData);
    }

JsonFilterクラスを作成します(JSC参照のおかげです)。

    public class JsonFilter : ActionFilterAttribute
    {
        public string Param { get; set; }
        public Type JsonDataType { get; set; }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
            {
                string inputContent;
                using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
                {
                    inputContent = sr.ReadToEnd();
                }
                var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
                filterContext.ActionParameters[Param] = result;
            }
        }
    }

別のクラスを作成して、フィルターがJSON文字列を実際の操作可能なオブジェクトに解析できるようにします。このクラスcomissionsJSは、jjGridのすべての行です。

    public class CommissionsJs
    {
        public string Amount { get; set; }

        public string CheckNumber { get; set; }

        public string Contract { get; set; }
        public string DatePayed { get; set; }
        public string DealerName { get; set; }
        public string ID { get; set; }
        public string IdAgentPayment { get; set; }
        public string Notes { get; set; }
        public string PaymentMethodName { get; set; }
        public string RowNumber { get; set; }
        public string AgentId { get; set; }
    }

この例が、複雑なオブジェクトの投稿方法を説明するのに役立つことを願っています。


0

何てことだ。特別なことをする必要はありません。あなたの投稿セクションでのみ、次のようにしてください:

    $.post(yourURL,{ '': results})(function(e){ ...}

サーバーではこれを使用します:

   public ActionResult MethodName(List<yourViewModel> model){...}

このリンクはあなたが行うのに役立ちます...


-1
    [HttpPost]
    public bool parseAllDocs([FromBody] IList<docObject> data)
    {
        // do stuff

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