Übergeben einer Liste von Objekten an eine MVC-Controller-Methode mit jQuery Ajax

113

Ich versuche, ein Array von Objekten mit der Funktion ajax () von jQuery an eine MVC-Controller-Methode zu übergeben. Wenn ich in die PassThing () C # -Controllermethode komme, ist das Argument "things" null. Ich habe versucht, dies mit einer Art Liste für das Argument zu tun, aber das funktioniert auch nicht. Was mache ich falsch?

<script type="text/javascript">
    $(document).ready(function () {
        var things = [
            { id: 1, color: 'yellow' },
            { id: 2, color: 'blue' },
            { id: 3, color: 'red' }
        ];

        $.ajax({
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            type: 'POST',
            url: '/Xhr/ThingController/PassThing',
            data: JSON.stringify(things)
        });
    });
</script>

public class ThingController : Controller
{
    public void PassThing(Thing[] things)
    {
        // do stuff with things here...
    }

    public class Thing
    {
        public int id { get; set; }
        public string color { get; set; }
    }
}
Halcyon
quelle
3
Ihre Daten sind eine Zeichenfolge, Ihre Methode akzeptiert jedoch ein Array. Ändern Sie Ihre Methode, um eine Zeichenfolge zu akzeptieren, und deserialisieren Sie sie dann innerhalb der Methode.
Bob Horn
2
Ihr Code ist korrekt. Ich habe es getestet und es hat mit MVC 4 funktioniert. Bitte geben Sie weitere Daten an, um es herauszufinden.
Diego
Das ist großartig, aber was ist, wenn Sie nicht nur eine Liste von Zeichenfolgen zum Übergeben benötigen, sondern auch eine separate ID, die der Liste der Zeichenfolgen zugeordnet ist? Also wie, Gruppen-ID, Liste der Gruppen unter Gruppen-ID.
Nathan McKaskle

Antworten:

188

Mit dem Vorschlag von NickW konnte ich dies zum Laufen bringen. things = JSON.stringify({ 'things': things });Hier ist der vollständige Code.

$(document).ready(function () {
    var things = [
        { id: 1, color: 'yellow' },
        { id: 2, color: 'blue' },
        { id: 3, color: 'red' }
    ];      

    things = JSON.stringify({ 'things': things });

    $.ajax({
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: 'POST',
        url: '/Home/PassThings',
        data: things,
        success: function () {          
            $('#result').html('"PassThings()" successfully called.');
        },
        failure: function (response) {          
            $('#result').html(response);
        }
    }); 
});


public void PassThings(List<Thing> things)
{
    var t = things;
}

public class Thing
{
    public int Id { get; set; }
    public string Color { get; set; }
}

Daraus habe ich zwei Dinge gelernt:

  1. Die Einstellungen contentType und dataType sind in der Funktion ajax () unbedingt erforderlich. Es wird nicht funktionieren, wenn sie fehlen. Ich fand dies nach langem Ausprobieren heraus.

  2. Verwenden Sie einfach das Format JSON.stringify ({'things': things}), um ein Array von Objekten an eine MVC-Controller-Methode zu übergeben.

Ich hoffe das hilft jemand anderem!

Halcyon
quelle
8
Ich hatte das gleiche Problem und das Hinzufügen des contentType hat es behoben. Vielen Dank!
Rochelle C
9
Zwei Dinge zu beachten: JSON.stringify und Angabe von 'contentType'.
Dinesh Ygv
Roh. Ich arbeite immer noch nicht für mich. Meine Anforderungs-URL ist http://localhost:52459/Sales/completeSale?itemsInCart=[{"ItemId":1,"Quantity":"1","Price":3.5}]und Sales.completeSaleist public ActionResult completeSale(ItemInCart[] itemsInCart)als HttpGet.
Abalter
3
aus irgendeinem Grund musste ich nur verwendendata: JSON.stringify(things),
Rob Scott
1
dataTypeist nicht nötig. Wenn es weggelassen wird, wird es von der
32

Könntest du das nicht einfach machen?

var things = [
    { id: 1, color: 'yellow' },
    { id: 2, color: 'blue' },
    { id: 3, color: 'red' }
];
$.post('@Url.Action("PassThings")', { things: things },
   function () {
        $('#result').html('"PassThings()" successfully called.');
   });

... und markieren Sie Ihre Aktion mit

[HttpPost]
public void PassThings(IEnumerable<Thing> things)
{
    // do stuff with things here...
}
Laternenmarsch
quelle
3
Dies sollte die beste Antwort sein. Die JSON.stringify sollte in diesem Fall nicht verwendet werden
Dies funktioniert bei mir nicht. Ich verwende [HttpPost] public int SaveResults (List <ShortDetail> -Modell) {} und $ .post ("@ Url.Action (" SaveResults "," Maps ")", {model: dataItems}, function (result) {});
Samra
2
Es hat bei mir funktioniert. Absolut die beste Antwort. Ich weiß nicht, warum die Halcyon-Implementierung nicht funktioniert hat. Die PassThings-Funktion wurde aufgerufen, aber die Eingabevariable 'things' war leer, selbst wenn sie kurz vor dem Aufruf in das Javascript eingetragen wurde.
Leonardo Daga
12

Ich verwende eine .Net Core 2.1-Webanwendung und konnte hier keine einzige Antwort zum Arbeiten erhalten. Ich habe entweder einen leeren Parameter (wenn die Methode überhaupt aufgerufen wurde) oder einen 500-Server-Fehler. Ich begann mit jeder möglichen Kombination von Antworten zu spielen und bekam schließlich ein funktionierendes Ergebnis.

In meinem Fall war die Lösung wie folgt:

Skript - Stringifizieren des ursprünglichen Arrays (ohne Verwendung einer benannten Eigenschaft)

    $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        url: mycontrolleraction,
        data: JSON.stringify(things)
    });

Verwenden Sie in der Controller-Methode [FromBody].

    [HttpPost]
    public IActionResult NewBranch([FromBody]IEnumerable<Thing> things)
    {
        return Ok();
    }

Zu den Fehlern gehören:

  • Den Inhalt benennen

    Daten: {Inhalt: Knoten}, // Serverfehler 500

  • Der contentType = Server-Fehler 500 ist nicht vorhanden

Anmerkungen

  • dataTypewird trotz einiger Antworten nicht benötigt, da dies für die Antwortdecodierung verwendet wird (daher für die Anforderung nicht relevant) hier ).
  • List<Thing> funktioniert auch in der Controller-Methode
Codierung weg
quelle
10

Ich habe die perfekte Antwort auf all das: Ich habe so viele Lösungen ausprobiert, die nicht in der Lage sind, mich selbst endgültig zu verwalten. Eine detaillierte Antwort finden Sie unten:

       $.ajax({
            traditional: true,
            url: "/Conroller/MethodTest",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data:JSON.stringify( 
               [
                { id: 1, color: 'yellow' },
                { id: 2, color: 'blue' },
                { id: 3, color: 'red' }
                ]),
            success: function (data) {
                $scope.DisplayError(data.requestStatus);
            }
        });

Controler

public class Thing
{
    public int id { get; set; }
    public string color { get; set; }
}

public JsonResult MethodTest(IEnumerable<Thing> datav)
    {
   //now  datav is having all your values
  }
Veera Induvasi
quelle
Sie sollten mehr Upvotes haben: traditionell: wahr ist der empfohlene Weg auf der Jquery-Website
DFTR
7

Die einzige Möglichkeit, dies zum Laufen zu bringen, besteht darin, den JSON als String zu übergeben und ihn dann mit zu deserialisieren JavaScriptSerializer.Deserialize<T>(string input), was ziemlich seltsam ist, wenn dies der Standard-Deserializer für MVC 4 ist.

Mein Modell verfügt über verschachtelte Objektlisten. Das Beste, was ich mit JSON-Daten erreichen kann, ist die oberste Liste mit der richtigen Anzahl von Elementen, aber alle Felder in den Elementen waren null.

So etwas sollte nicht so schwer sein.

    $.ajax({
        type: 'POST',
        url: '/Agri/Map/SaveSelfValuation',
        data: { json: JSON.stringify(model) },
        dataType: 'text',
        success: function (data) {

    [HttpPost]
    public JsonResult DoSomething(string json)
    {
        var model = new JavaScriptSerializer().Deserialize<Valuation>(json);
dringenderer Scherz
quelle
Befolgen Sie dazu das Format des Ajax-Aufrufs genau.
Graham Laight
4

Dies ist Arbeitscode für Ihre Abfrage, Sie können ihn verwenden.

Controler

    [HttpPost]
    public ActionResult save(List<ListName> listObject)
    {
    //operation return
    Json(new { istObject }, JsonRequestBehavior.AllowGet); }
    }

Javascript

  $("#btnSubmit").click(function () {
    var myColumnDefs = [];
    $('input[type=checkbox]').each(function () {
        if (this.checked) {
            myColumnDefs.push({ 'Status': true, 'ID': $(this).data('id') })
        } else {
            myColumnDefs.push({ 'Status': false, 'ID': $(this).data('id') })
        }
    });
   var data1 = { 'listObject': myColumnDefs};
   var data = JSON.stringify(data1)
   $.ajax({
   type: 'post',
   url: '/Controller/action',
   data:data ,
   contentType: 'application/json; charset=utf-8',
   success: function (response) {
    //do your actions
   },
   error: function (response) {
    alert("error occured");
   }
   });
sach4all
quelle
2

Das Umschließen Ihrer Objektliste mit einem anderen Objekt, das eine Eigenschaft enthält, die dem Namen des Parameters entspricht, der vom MVC-Controller erwartet wird, funktioniert. Das wichtige Bit ist der Wrapper um die Objektliste.

$(document).ready(function () {
    var employeeList = [
        { id: 1, name: 'Bob' },
        { id: 2, name: 'John' },
        { id: 3, name: 'Tom' }
    ];      

    var Employees = {
      EmployeeList: employeeList
    }

    $.ajax({
        dataType: 'json',
        type: 'POST',
        url: '/Employees/Process',
        data: Employees,
        success: function () {          
            $('#InfoPanel').html('It worked!');
        },
        failure: function (response) {          
            $('#InfoPanel').html(response);
        }
    }); 
});


public void Process(List<Employee> EmployeeList)
{
    var emps = EmployeeList;
}

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Ganove
quelle
1
     var List = @Html.Raw(Json.Encode(Model));
$.ajax({
    type: 'post',
    url: '/Controller/action',
    data:JSON.stringify({ 'item': List}),
    contentType: 'application/json; charset=utf-8',
    success: function (response) {
        //do your actions
    },
    error: function (response) {
        alert("error occured");
    }
});
Athul Nalupurakkal
quelle
Versuchen Sie diesen Code, um die Liste der Modellobjekte mit Ajax zu übergeben. Das Modell repräsentiert die IList <Modell>. Verwenden Sie IList <Modell> im Controller, um die Werte abzurufen.
Athul Nalupurakkal
0

Wenn Sie die ASP.NET-Web-API verwenden, sollten Sie nur übergeben data: JSON.stringify(things).

Und Ihr Controller sollte ungefähr so ​​aussehen:

public class PassThingsController : ApiController
{
    public HttpResponseMessage Post(List<Thing> things)
    {
        // code
    }
}
FleGMan
quelle
0

Änderung von @veeresh i

 var data=[

                        { id: 1, color: 'yellow' },
                        { id: 2, color: 'blue' },
                        { id: 3, color: 'red' }
                        ]; //parameter
        var para={};
        para.datav=data;   //datav from View


        $.ajax({
                    traditional: true,
                    url: "/Conroller/MethodTest",
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    data:para,
                    success: function (data) {
                        $scope.DisplayError(data.requestStatus);
                    }
                });

In MVC



public class Thing
    {
        public int id { get; set; }
        public string color { get; set; }
    }

    public JsonResult MethodTest(IEnumerable<Thing> datav)
        {
       //now  datav is having all your values
      }
Minhajul Islam
quelle
0

Was ich getan habe, als ich versucht habe, einige Daten aus mehreren ausgewählten Zeilen in DataTable an die MVC-Aktion zu senden:

HTML Am Anfang einer Seite:

@Html.AntiForgeryToken()

(Es wird nur eine Zeile angezeigt, vom Modell binden):

 @foreach (var item in Model.ListOrderLines)
                {
                    <tr data-orderid="@item.OrderId" data-orderlineid="@item.OrderLineId" data-iscustom="@item.IsCustom">
                        <td>@item.OrderId</td>
                        <td>@item.OrderDate</td>
                        <td>@item.RequestedDeliveryDate</td>
                        <td>@item.ProductName</td>
                        <td>@item.Ident</td>
                        <td>@item.CompanyName</td>
                        <td>@item.DepartmentName</td>
                        <td>@item.ProdAlias</td>
                        <td>@item.ProducerName</td>
                        <td>@item.ProductionInfo</td>
                    </tr>
                }

Schaltfläche zum Starten der JavaScript-Funktion:

 <button class="btn waves-effect waves-light btn-success" onclick="ProcessMultipleRows();">Start</button>

JavaScript-Funktion:

  function ProcessMultipleRows() {
            if ($(".dataTables_scrollBody>tr.selected").length > 0) {
                var list = [];
                $(".dataTables_scrollBody>tr.selected").each(function (e) {
                    var element = $(this);
                    var orderid = element.data("orderid");
                    var iscustom = element.data("iscustom");
                    var orderlineid = element.data("orderlineid");
                    var folderPath = "";
                    var fileName = "";

                    list.push({ orderId: orderid, isCustomOrderLine: iscustom, orderLineId: orderlineid, folderPath: folderPath, fileName : fileName});
                });

                $.ajax({
                    url: '@Url.Action("StartWorkflow","OrderLines")',
                    type: "post", //<------------- this is important
                    data: { model: list }, //<------------- this is important
                    beforeSend: function (xhr) {//<--- This is important
                      xhr.setRequestHeader("RequestVerificationToken",
                      $('input:hidden[name="__RequestVerificationToken"]').val());
                      showPreloader();
                    },
                    success: function (data) {

                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {

                    },
                     complete: function () {
                         hidePreloader();
                    }
                });
            }
        }

MVC-Aktion:

[HttpPost]
[ValidateAntiForgeryToken] //<--- This is important
public async Task<IActionResult> StartWorkflow(IEnumerable<WorkflowModel> model)

Und MODELL in C #:

public class WorkflowModel
 {
        public int OrderId { get; set; }
        public int OrderLineId { get; set; }
        public bool IsCustomOrderLine { get; set; }
        public string FolderPath { get; set; }
        public string FileName { get; set; }
 }

FAZIT:

Der Grund für ERROR:

"Failed to load resource: the server responded with a status of 400 (Bad Request)"

Ist Attribut: [ValidateAntiForgeryToken]für die MVC-AktionStartWorkflow

Lösung in Ajax-Aufruf:

  beforeSend: function (xhr) {//<--- This is important
                      xhr.setRequestHeader("RequestVerificationToken",
                      $('input:hidden[name="__RequestVerificationToken"]').val());
                    },

Um eine Liste von Objekten zu senden, müssen Sie Daten wie im Beispiel (Auffüllen eines Listenobjekts) und:

Daten: {Modell: Liste},

Typ: "Post",

kitzlig
quelle
0

So funktioniert es gut für mich:

var things = [
    { id: 1, color: 'yellow' },
    { id: 2, color: 'blue' },
    { id: 3, color: 'red' }
];

$.ajax({
    ContentType: 'application/json; charset=utf-8',
    dataType: 'json',
    type: 'POST',
    url: '/Controller/action',
    data: { "things": things },
    success: function () {
        $('#result').html('"PassThings()" successfully called.');
    },
    error: function (response) {
        $('#result').html(response);
    }
});

Mit "ContentType" in Großbuchstaben "C".

Myxomatose
quelle