0

I'm currently working on a ASP.net Web application with the MVC pattern. I have set up a page where people can add items to a gridstack section and drag them around (Gridstack is a plugin to create draggable boxes/objects). My goal is to send the final coordinates of these boxes to my controller:

function saveData() {
    var pagePositions = [];

    // Fill our array
    $('.grid-stack-item.ui-draggable').each(function () {
        var $this = $(this);
        pagePositions.push({
            x: $this.attr('data-gs-x'),
            y: $this.attr('data-gs-y'),
            w: $this.attr('data-gs-width'),
            h: $this.attr('data-gs-height'),
            content: $('.grid-stack-item-content', $this).html()
        });
    });

    // Convert array to object
    var pagePosData = toObject(pagePositions);

    alert(pagePosData);

    $.ajax({
        type: "POST",
        url: "savePage",
        data: { positions: JSON.stringify(pagePosData) }
    });

} function toObject(arr) {
    var rv = {};
    for (var i = 0; i < arr.length; ++i)
        if (arr[i] !== undefined) rv[i] = arr[i];
    return rv;
}

The code above fills the attributes of the given html elements and puts them into an array. I assumed, according to several topics on the internet, that sending the array was causing trouble so i inserted a function that converts the array to an javascript object (key value pairs). I send them to my controller with an AJAX call which results in a error code 500:

    [HttpPost]
    public string savePage(string positions)
    {
        //some code
        var json = positions;
        var test = "";
        CreatePagemodelJson obj = new JavaScriptSerializer().Deserialize<CreatePagemodelJson>(positions.ToString());
        //var jsonObject = JsonConvert.DeserializeObject<CreatePagemodel>(positionsJson.ToString());

        return "";
    }

I set up breakpoints inside the controller to read the value i get from the parameter positions, but it doesn't even get to that point. I tried setting up models for the Json file but the problem here is that the post calls return a dynamic json format.

Update: I managed to get it working with below posts. With below structure, i get the results as an array according to my model.

function saveData() {
    var pagePositions = [];

    // Fill our array
    $('.grid-stack-item.ui-draggable').each(function () {
        var $this = $(this);
        pagePositions.push({
            x: $this.attr('data-gs-x'),
            y: $this.attr('data-gs-y'),
            w: $this.attr('data-gs-width'),
            h: $this.attr('data-gs-height'),
            content: $('.grid-stack-item-content', $this).html()
        });
    });

    alert(pagePositions);

    $.ajax({
        type: "POST",
        url: "savePage",
        contentType: 'application/json',
        data: JSON.stringify(pagePositions)
    });
}

public class Position
{
    public string x { get; set; }
    public string y { get; set; }
    public string w { get; set; }
    public string h { get; set; }
    public string content { get; set; }
}

[HttpPost]
public ActionResult savePage(IEnumerable<Position> positions)
{
    //some code
    return View("SomeView");
}

The parameter positions succesfully returns the array of pagePositions send with the post: Succesfull transfer

I tried sending the data without the JSON.stringify(pagePositions) and ContentType: 'application/json' option but i got a null return in my parameter on the controller.

Tob
  • 31
  • 5
  • Why are you toString'ing a string? Also have you tried adding breakpoints and debugging step by step to see where the error happens? – Taplar May 23 '18 at 19:15
  • 1
    It need to be `data: JSON.stringify(positions) }` and add the `contentType: 'application/json'` option. And then change your method to `public ActionResult savePage(IEnumerable positions)` where `XX` is a model containing properties `x`, `y`, etc (and delete your `toObject()` function) –  May 24 '18 at 01:15
  • @StephenMuecke Thank you, this worked! I managed to get the results into the controller as an array. I tried the answer below and the only thing that was missing was the JSON.stringify(pagePositions). – Tob May 24 '18 at 09:59
  • 1
    And the `contentType: 'application/json'` option :) –  May 24 '18 at 10:03

1 Answers1

0

There a number of things to point out here.

With your current question.

  • The data you are sending isn't a string. data: { positions: JSON.stringify(pagePosData) } is creating a JavaScript object with a property of positions whose value is the serialized version of your object.
  • You should be able to create a c# class and accept that as your controller methods parameter and get closer to the results you are expecting. That would look as follows:

    public class Foo { public string Positions { get; set; } }

    public string savePage(Foo positions)

  • Alternatively you could update your method to get the request body as a string as shown in this SO answer

More importantly though, it would seem as though you came across some misinformation. There shouldn't be any issue passing an array back to your controller. Again, you will need a c# class that models your expected data type(s). You don't list those in your question, so it is hard to say for sure how you need to update your code, but I would suggest something more like the following:

function saveData() {
    var pagePositions = [];

    // Fill our array
    $('.grid-stack-item.ui-draggable').each(function () {
        var $this = $(this);
        pagePositions.push({
            x: $this.attr('data-gs-x'),
            y: $this.attr('data-gs-y'),
            w: $this.attr('data-gs-width'),
            h: $this.attr('data-gs-height'),
            content: $('.grid-stack-item-content', $this).html()
        });
    });

    $.ajax({
        type: "POST",
        url: "savePage",
        data: JSON.stringify(pagePositions),
        contentType: "application/json"
    });
}


public class Position
{
  public int X { get; set; }
  public int Y { get; set; }
  public int W { get; set; }
  public int H { get; set; }
  public string Content { get; set; }
}

[HttpPost]
public string savePage(Position[] positions)
{
    //some code
    return "";
}

If this doesn't work, please provide more details about what doesn't work, what error you are receiving and what version of asp.net mvc you are using.

peinearydevelopment
  • 11,042
  • 5
  • 48
  • 76
  • This indeed solves the POST error, as i am now able to POST to the controller without getting the 500 error. I do however get a null result in the parameter. I got it working with the comment above, adding JSON.stringify(pagePositions) and the contentType: 'application/json' option to the call. – Tob May 24 '18 at 10:18