4

I'm trying to Encode my MVC Model with the following code but the alert message gives me a null value. I'm not sure why it's giving me a null value because this is a create form. I'm trying to create a model from this and my html Code has the following look:

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Customer</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" id="submit" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    <script type="text/javascript">
        $(document).ready(function () {
            $('#submit').click(function () {
                var JsonModel = '@Html.Raw(Json.Encode(@Model))';

                alert(JsonModel); // json as string

                var model = JSON.parse(JsonModel); // will give json
                alert(model);

                $.ajax({
                    type: "POST",
                    url: "../Home/Index",
                    data: {"cus" :  model},
                    success: function(data){
                        alert("done");
                    },
                    error:function(){
                        alert("Error!!!!");
                    }
                });
            });
        });
    </script>
} 
Luis Gouveia
  • 8,334
  • 9
  • 46
  • 68
Dayan
  • 711
  • 5
  • 16
  • 27
  • This process is a pain in the ass and can be easily avoided using [this method](http://stackoverflow.com/questions/27267942/submitting-partial-view-data-from-parent-view/27292486#27292486) which will encode your form in a way that MVC understands, so it can implicitly convert back to your model type. – Inspector Squirrel Feb 24 '15 at 16:38
  • thanks !!! i'll have a look..... – Dayan Feb 24 '15 at 16:41

4 Answers4

8

It's returning null because it is null. The data that the user will eventually enter into the form is not available at the time the page is rendering (and your call to Json.Encode(Model) runs). Things like JavaScript run client-side, while all the Razor stuff runs server-side before it's sent down to the client. If you want to get the user-entered data from the form for use in your AJAX call, then you need to do as @Sippy suggests and retrieve it via JavaScript:

$('form').serializeObject();

Also, in case you do need to actually encode the model when rendering (for maybe use with something like Knockout), you don't need to set it as a string and then parse the string. Just set it as a regular JavaScript object. That's all JSON is anyways:

var model = @Html.Raw(Json.Encode(Model));
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • While unintuitive, using JSON.parse will be faster here. For example, `var obj= JSON.parse('@Html.Raw(Json.Encode(Model))');` Source: https://www.youtube.com/watch?v=ff4fgQxPaO0 – Onosa Dec 09 '19 at 21:21
0

My answer here shows (in the JQuery section) how you can get around using Json.Encode altogether.

The basic idea behind it is that by using a jQuery function you can build a JSON object, one that MVC will be able to parse into a data model, out of any form.

The function is as follows:

$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

In your case, your AJAX would become

 $.ajax({
     type: "POST",
     url: "../Home/Index",
     data: { cus : JSON.stringify($('form').serializeObject()) },
     success: function(data){
         alert("done");
     },
     error:function(){
         alert("Error!!!!");
     }
 });

If you have trouble getting $('form') working, possibly if you have numerous forms on the same page, use classes or IDs to uniquely identify your forms.

Community
  • 1
  • 1
Inspector Squirrel
  • 2,548
  • 2
  • 27
  • 38
0

This sample, encode a model (that is a List<My>) and POST it to an action as a Json object named model.

var jsonModel = '@Html.Raw(Json.Encode(Model))';
    var id = rowid;
    $.ajax({
        url: 'DeleteRows',
        contentType: 'application/json; charset=utf-8',
        type: 'POST',
        dataType: 'html',
        data: '{ "model": { "rows":' + jsonModel + '}}'
    })
    .success(function (result) { $("#grdRows").empty(); $("#grdRows").html(result); })
    .error(function (xhr, ajaxOptions, thrownError) { alert(xhr.status + ' - ' + ajaxOptions + ' - ' + thrownError); alert(xhr.responseText); });
Luca
  • 1,588
  • 2
  • 22
  • 26
0

For those who want to pass a model to an action method (HttpGet) with an Url.Action Helper

  @model AddViewModel

   <script type="text/javascript">

        $(document).ready(function () {
            openDoc();
        });

        function openDoc() {

            var model = '@Html.Raw(Json.Serialize(Model))';
            var obj = JSON.parse(model);
            var params = $.param(obj);
            var url = '@Url.Action("GetPdf", "Declaration")?' + params;

            window.open(url);
        }

    </script>
Romain
  • 1
  • 2