0

I want to pass js array from View via post to controller, then process the data and return the data to another view.

enter image description here

Problems that I've experienced:

-can't use ajax to post data, because I won't be able to return another view

When you use $.post it calls your action then gets back a bunch of HTML. And then you do nothing with it, so the browser just throws it away. If you want to just go to the new page, do a regular post and don't use ajax. Ajax is more for if you need to call your server to get some information to UPDATE the current page, not go to a new one.

(i guess it's the same for $http.post as well?)

-can't use regular post (@Html.Beginform) I think becaue I won't be able to pass the js array?

How should I deal with it?

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Denis Wasilew
  • 503
  • 3
  • 9
  • 29
  • 1
    You can do a regular post if your form contains inputs containing the values in the array –  Nov 10 '17 at 23:01
  • That's an idea, but isn't that a bit primitive? (just curious) – Denis Wasilew Nov 10 '17 at 23:02
  • 2
    The standard way of submitting a form is primitive? And you can also make an ajax call but rather that return a view which you don't use, just return a simple `JsonResult` indicating success ot otherwise, and if successful, use `location.href` to redirect in the `success` callback –  Nov 10 '17 at 23:05
  • So you mean after I process the data I should return JsonResult instead of the view with processed data. But how do I get the processed data again after I redirect the page with 'location.href'? (now I won't be able to pass it to the view) – Denis Wasilew Nov 10 '17 at 23:17
  • No I mean you save your data in the POST method, and then just return `true` in indicate success, and perhaps an ID value that identifies your data and then use `location.href` to redirect (and pass that ID to the GET method if you need it (just as you would use `RedirectToAction()` in the POST method for a normal submit) –  Nov 10 '17 at 23:48

4 Answers4

1

If you absolutely want to do a normal form submit(non-ajax) with data in your js variable, you may build some form input elements for the data you have in your js variable and then you can use javascript to submit this form. As long as the name of the elements match with your action method parameter, model binding will work.

Here is a simple example to send a list of strings on a button click event, using jQuery.

$(function() {

    var flags = ["aa", "bb", "cc"];
    var targetUrl="@Url.Action("Summary","Home")";

    $("#SubmitButton").click(function(e) {

        //First build a form element and set the action attribute value
        var $f = $("<form></form>").attr("action",targetUrl).attr("method","post");

        //Loop throug the string and create an input element for each item
        $.each(flags, function(a, b) {

            var $el = $("<input type='hidden' name='flagsChecked' />").attr("value",b);

            //Add the input element to the form
            $f.append($el);

        });

        //Add the form to the page and submit the form
        $f.appendTo("body").submit();

    });

});

and in your http post action method , you can return a view.

[HttpPost]
public ActionResult Summary(List<string> flagsChecked)
{
    return View("Summary");
}

If your code is to udpate some data, i strongly suggest you to follow the P-R-G pattern and return a redirect response.

[HttpPost]
public ActionResult Summary(List<string> flagsChecked)
{
    return RedirectToAction("Summary");
}
Shyju
  • 214,206
  • 104
  • 411
  • 497
0

You can pass multiple values in a regular post with @Html.BeginForm. The values will then be encoded like that: key=foo&key=bar&key=baz. Check out the following post if you need more information: https://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

Thomas Gassmann
  • 737
  • 1
  • 13
  • 27
0

Pass js array to mvc controller

Well you have two separate issues. First you have to bind either a application/x-www-form-urlencoded or multipart/form-data or json to your object/array.

Phil Haacked - Model Binding To A List

Excerpt:

start

<form method="post" action="/Home/UpdateInts">
  <input type="text" name="ints" value="1" />
  <input type="text" name="ints" value="4" />
  <input type="text" name="ints" value="2" />
  <input type="text" name="ints" value="8" />
  <input type="submit" />
</form>

you were to take fiddler and look at what data actually gets posted when clicking the submit button, you’d see the following.

ints=1&ints=4&ints=2&ints=8

The default model binder sees all these name/value pairs with the same name and converts that to a collection with the key ints, which is then matched up with the ints parameter to your action method. Pretty simple!

end

then return another view

Well you have pretty much two options.

First, you use a standard <form> element with a url and a way to submit the form (submit button, jQuery etc). Pros: its been around litteraly forever and very simple to use. Cons: if there is network outage or something, your user experience is very poor (browser, url cannot be found, so I hit refresh do I resubmit... I don't know.. etc)

Second, you use an Ajax request and send the data. When the response is successful, you window.location your user to the next screen. Pros: fantastic user experience, if the network fails, you can retry or give the user a way to retry. Cons: definitely more work to implement.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
0

Does it have to be a post?

one javascript example of doing this with a get request:

var url = "/Controller/Action?";
var myArray = {id1: 100, id2: 200, "id3": 300};

for (var key in myArray) {
url += key+"="+myArray[key] + "&"
}

window.top.location.href = url

otherwise just make a post:

var form = $('<form></form>');
var url = "/Controller/Action";
form.attr("method", "post");
form.attr("action", url);
var myArray = {id1: 100, id2: 200, "id3": 300};

for (var key in myArray) {
    var field = $('<input></input>');

    field.attr("type", "hidden");
    field.attr("name", key);
    field.attr("value", myArray[key]);

    form.append(field);
});

$(document.body).append(form);
form.submit();
Harry
  • 3,930
  • 2
  • 14
  • 31