Bagaimana cara memposting array objek kompleks dengan JSON, jQuery ke ASP.NET MVC Controller?

92

Kode saya saat ini terlihat seperti berikut. Bagaimana saya bisa meneruskan array saya ke controller dan jenis parameter apa yang harus saya terima?

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

Metode tindakan pengontrol saya terlihat seperti

public JsonResult SaveOrUpdate(IList<PageDesignWidget> widgets)
JSC
sumber

Jawaban:

84

Saya telah menemukan solusi. Saya menggunakan solusi Steve Gentile, jQuery dan ASP.NET MVC - mengirim JSON ke Action - Revisited .

Kode tampilan ASP.NET MVC saya terlihat seperti:

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

dan tindakan pengontrol saya dihiasi dengan atribut khusus

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

Kode untuk atribut khusus dapat ditemukan di sini (tautan rusak sekarang).

Karena tautannya rusak, ini adalah kode untuk 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 berasal dari Json.NET

Tautan: Serialisasi dan Deserialisasi JSON dengan Json.NET

JSC
sumber
Tampak hebat - Tautan entri blog dan kode atribut khusus tidak berfungsi lagi - dapatkah Anda mengirim ulang?
littlechris
4
Solusi ini membutuhkan perubahan di sisi klien dan server. Saya tahu Anda membutuhkan ini sejak lama, tetapi saya mungkin juga memberikan tautan ke pendekatan yang berbeda, yang menggunakan plugin jQuery sederhana yang memungkinkan untuk mengubah objek Javascript apa pun menjadi bentuk yang dipahami oleh pengikat model default dan model mengikat ke parameter. Tidak perlu filter. erraticdev.blogspot.com/2010/12/… Saya tidak tahu bagaimana Anda memecahkan kesalahan validasi tetapi saya juga memiliki solusi untuk itu: erraticdev.blogspot.com/2010/11/…
Robert Koritnik
3
Dapatkah Anda memberikan sumber / asal JavaScriptConvert.DeserializeObject?
Matthieu
Ini adalah perpustakaan Newtonsoft Json - jika Anda membuka manajer paket nuget dan mencari di Newtonsoft, itu akan muncul untuk Anda (sekarang sudah 2016). Mungkin ini sekarang sudah jelas, tetapi siapa tahu ada yang bertanya-tanya.
Robb Sadler
22

Filter Tindakan, jquery stringify, bleh ...

Peter, fungsi ini asli dari MVC. Itulah salah satu hal yang membuat MVC begitu hebat.

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

Dan dalam aksinya,

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

Bekerja seperti pesona:

masukkan deskripsi gambar di sini

Jika Anda menggunakan jQuery 1.4+, maka Anda ingin melihat pengaturan mode tradisional:

jQuery.ajaxSettings.traditional = true;

Seperti dijelaskan di sini: http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters

Ini bahkan berfungsi untuk objek yang kompleks. Jika Anda tertarik, Anda harus melihat dokumentasi MVC tentang Pengikatan Model: http://msdn.microsoft.com/en-us/library/dd410405.aspx

Levitikon
sumber
1
Anda mungkin benar, tetapi pengikat model JSON baru mengenal MVC3 dan pertanyaannya ditanyakan pada tahun 2008 ketika ini tidak didukung. Layak disebutkan dalam jawaban Anda.
Piotr Owsiak
3
Bagaimana ini contoh pengoperan array objek yang kompleks ?
DuckMaestro
Bukan tapi contoh masih berlaku (MVC 3+). Selama nama parameter Anda sesuai dengan model yang Anda harapkan, Anda tidak akan mengalami masalah apa pun.
J. Mitchell
Kuncinya di sini adalah membuat objek JSON dengan nama parameter metode ("ids") dan kemudian meletakkan larik objek kompleks di dalamnya. Selain itu, buat parameter ketiga "benar" dan Anda akan menggunakan mode tradisional.
redwards510
11

Di .NET4.5, MVC 5tidak perlu widget.

Javascript:

objek di JS: masukkan deskripsi gambar di sini

mekanisme yang memposting.

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

C #

Objek:

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

Pengontrol:

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

Objek diterima:

masukkan deskripsi gambar di sini

Semoga ini menghemat waktu Anda.

Matas Vaitkevicius
sumber
8

Menjelang paruh kedua dari Buat REST API menggunakan ASP.NET MVC yang menggunakan JSON dan XML biasa , mengutip:

Sekarang kita perlu menerima payload JSON dan XML, yang dikirimkan melalui HTTP POST. Terkadang klien Anda mungkin ingin mengupload koleksi objek dalam satu kesempatan untuk pemrosesan batch. Jadi, mereka dapat mengunggah objek menggunakan format JSON atau XML. Tidak ada dukungan asli di ASP.NET MVC untuk secara otomatis mengurai JSON atau XML yang diposting dan secara otomatis memetakan ke parameter Tindakan. Jadi, saya menulis filter yang melakukannya. "

Dia kemudian mengimplementasikan filter tindakan yang memetakan JSON ke objek C # dengan kode yang ditampilkan.

anonim
sumber
Saya baru saja menulis jawaban saya. Tapi saya akan tetap mempostingnya ;-)
JSC
7

Pertama unduh kode JavaScript ini, JSON2.js , yang akan membantu kami membuat serial objek menjadi string.

Dalam contoh saya, saya memposting baris jqGrid melalui Ajax:

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

Sekarang di pengontrol:

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

Buat Kelas JsonFilter (berkat referensi 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;
            }
        }
    }

Buat kelas lain sehingga filter dapat mengurai string JSON ke objek aktual yang dapat dimanipulasi: Kelas comissionsJS ini adalah semua baris jqGrid saya.

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

Saya harap contoh ini membantu mengilustrasikan cara memposting objek yang kompleks.

Sanchitos
sumber
0

Ya Tuhan. tidak perlu melakukan sesuatu yang khusus. hanya di bagian posting Anda lakukan sebagai berikut:

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

Di server gunakan ini:

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

tautan ini membantu Anda menyelesaikan ...

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

    }
JsonW
sumber