简体   繁体   中英

Passing json into MVC controller

I've seen many posts on SO considering this topic, though applying solutions didn't work for me and I am confused right now. Mb I'm missing sth?

Please consider I'm a noob at .js stuff.

So I get my values from dynamicly created form elements with this JS and attempt to post it:

EDIT 12:21: I got this script which should parse each element from form into custom made array resembling json. I still get null reference though. Got any idea how to get it?

 var getValues = function (myForm) {
        var array = [];
    var parser;

    $("formElement").each( function (i, elem) {

            parser.empty()
            parser = {
                Id: $(elem,"#Id ").val(),
                someOption: $(elem, "#someOption ").val(),
                someText: $(elem, "#someText ").val(),
                someNumber: $(elem, "#someNumber  ").val()
            }
            array.push(parser);

        });

    console.log(array);


    $.ajax({
        type: "POST",
        url: 'angus',
        traditional: true,
        data:  {json: array },
        success: function (data) {
            $("#getData").empty();
            $("#getData").append(array);
        }
    });            
    };

I get this in log: (objects of index like i,i+1,i+2,i+3 match the viewmodels - is it right? and I have mixed feelings about those proto and functions - what is it?) 在此处输入图片说明

In my controller action I get null exception:

 [HttpPost]
        public ActionResult angus(IEnumerable<TrashViewModel> json)
        {

            return View(json.ToList());
        }

I created my viewmodel:

  [Serializable]
public class TrashViewModel
{
    public int Id { get; set; }
    public string someOption { get; set; }
    public string someText { get; set; }
    public string someNumber { get; set; }

}

I had my forms HTML attributes names match those of viemodel class.

EDIT: html:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="formExample" ng-controller="ExampleController">

    <button class="btn btn-primary" ng-controller="addRow" ng-click="addLine()">Dodaj przycisk</button>

    <form novalidate class="simple-form">
        <div class="here">
            <div class="formElement row">

                  <input type="hidden" name="Id" value="1"/>
                <div class="col-md-2">
                    <select name="someOption" class="optns form-group col-md-12" ng-model="user.class">
                        <option selected value="1"> Rodzaj... </option>
                        <option value="test">2</option>
                        <option value="2">test</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        @*tutaj beda dodane opcje*@
                    </select>
                </div>
                <div class="col-md-1">
                    <input name="someNumber" class="form-group col-md-12" type="number" ng-model="user.number" value="" text="Ilość..." /><br />
                </div>
                <div class="col-md-9">
                    <input name="someText" class="form-group col-md-12" type="text" ng-model="user.text" value="" text="Uwagi..." /><br />
                </div>
            </div>
        </div>
        <input type="button" value="Reset" />
        <input type="submit" value="Save" />
    </form>
</div>

appended html:

 var strVar = "";
            strVar += "<div class=\"formElement row\">";
            strVar += "                  <input type=\"hidden\" name=\"Id\" value=\" "+ $scope.counter +"\"\/>";
            strVar += "                <div class=\"col-md-2\">";
            strVar += "                    <select name=\"someOption\" class=\"optns form-group col-md-12\" ng-model=\"user.class\">";
            strVar += "                        <option selected value=\"1\"> Rodzaj... <\/option>";
            strVar += "                        <option value=\"test\">2<\/option>";
            strVar += "                        <option value=\"2\">test<\/option>";
            strVar += "                        <option value=\"2\">2<\/option>";
            strVar += "                        <option value=\"3\">3<\/option>";
            strVar += "                        @*tutaj beda dodane opcje*@";
            strVar += "                    <\/select>";
            strVar += "                <\/div>";
            strVar += "                <div class=\"col-md-1\">";
            strVar += "                    <input name=\"someNumber\" class=\"form-group col-md-12\" type=\"number\" ng-model=\"user.number\" value=\"\" text=\"Ilość...\" \/><br \/>";
            strVar += "                <\/div>";
            strVar += "                <div class=\"col-md-9\">";
            strVar += "                    <input name=\"someText\" class=\"form-group col-md-12\" type=\"text\" ng-model=\"user.text\" value=\"\" text=\"Uwagi...\" \/><br \/>";
            strVar += "                <\/div>";
            strVar += "            <\/div>";

I end up with null exception which by what other posts suggest is because of viemodel class doesn't match the serialized objects. Don't know what to do at this point.

Thank you!

try replacing

 var parsed = $(myForm).serializeArray();

with

 var parameters = {
            Id : $("#Id ").val(),
            someOption : $("#someOption ").val(),
            someText : $("#someText ").val(),
             someNumber  : $("#someNumber  ").val()
       };

then pass it to the submit

JSON.stringify(parameters)

in your JavaScript code, 3 things jump out at me:

  1. you're using .serializeArray(), which creates an array of objects each with a name and value property. this does not match the structure of your TrashViewModel object
  2. you're wrapping the serialized object inside a new object with a single property called "json", which adds more structure to your data
  3. you're stringifying said object

all of that is unnecessary, since the .ajax() method will package the data in the correct format for you. you simply need to pass the serialized form as the data parameter.

data: $(myform).serialize()

on the controller, you should just set the parameter on the action to be your TrashViewModel object. please note that it's a single object, not an enumerable.

public ActionResult Angus(TrashViewModel form)
{
    // do something
}

if you were to use .serializeArray(), then you'd need to create a model object with Name and Value properties so that the model binder can properly resolve the params.

// JavaScript 
data: $(myform).serializeArray()

// Controller
public class NameValueModel
{
    public string Name { get; set; }
    public string Value { get; set; }
}

public ActionResult Angus(NameValueModel[] form)
{
    // do something
}

In order to POST your array, you need to stringify the data and set the contentType option. You ajax code needs to be

$.ajax({
    type: 'POST',
    url: '@Url.Action("angus")', // do not hard code url's
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify({ model: array }), 
    success: function (data) {

and the controller

[HttpPost]
public ActionResult angus(IEnumerable<TrashViewModel> model)

I'm not 100% happy about outcome, because I still have to parse json string at the end on server side. I think I'll soon do Q&A, so others won't have to fight a week to do sth like this. Thanks to:

  • @StephenMuecke
  • @Emil
  • @Jeff M

So actually what I did:

js to get inputs and push it custom style then do post ajax request:

        var array = [];
        var parser;

        $(".formElement").each( function (i, elem) {

                //parser.empty()
                parser = {
                    Id: $("#Id", $(this)).val(),
                    someOption: $("#someOption", $(this)).val(),
                    someText: $("#someText", $(this)).val(),
                    someNumber: $("#someNumber", $(this)).val()
                };
                console.log(parser);
                array.push(parser);

            });

        console.log(array);


        $.ajax({
            type: "POST",
            url: 'angus',
            traditional: true,
            data: { json: JSON.stringify(array) },
            success: function (data) {
                $("#getData").empty();
                $("#getData").append(array);
            }
        });

controller: (don't mind the logic, because it's useless here except it gave info during debugging)

the most important thing was to give string type as parameter; I'm 100% sure that my json bounced off of the complex type viewmodel

       [HttpPost]
        public ActionResult angus(string json)
        {

            var check = json.ToString() == null;

            return RedirectToAction("ErrorAction");
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM