1

I am fetching data from a SQL database table into an ASP.NET MVC Razor view but I have troubles getting changed input data into an Ajax post such as:

@model MyViewModel
    <div class="row">
        <div class="col-1">
            @Html.LabelFor(model => model.Id, "Id:", new {})
        </div>
        <div class="col-4">
            @Html.Label(Model.Id.ToString(), new { title = "" })
        </div>
    </div>

    <div class="row">
        <div class="col-1">
            @Html.LabelFor(model => model.Test, "Test:", new { })
        </div>
        <div class="col-9">
            @Html.TextBoxFor(model => model.Test, new { data_bind = "value: Test", @type = "text" })
        </div>
    </div>

    @section scripts {
        <script type="text/javascript">
                $("#save-click").click(function () {
                    var nr = @Model.Id;
                    var postData = @Html.Raw(Json.Encode(@Model));
                    //alert(postData.Test);

                    $.ajax({
                        type: "POST",
                        url: actions.test.createOrUpdate + "?id=" + nr,
                        dataType: "json",
                        traditional: true,
                        data: postData,
                        success: function (response) {
                            if (response.Code == 0) {
                                    else {
                                        window.location.reload(false);
                                    }
                            } else {
                                alert('err');
                            }
                        }
                    });
                });
            });
        </script>
    }

When I load the view everything is displayed correctly. The controller action is triggered correctly and the Id (which can not be altered) is passed properly too. However when input fields are changed not the changed values get passed to the controller but the original values that were fetched into the view.

The serialization seems to work, since the alert (postData.Test) returns a value - but always the unchanged one.

Any help would be appreciated.

Jerdine Sabio
  • 5,688
  • 2
  • 11
  • 23
Manu
  • 1,290
  • 5
  • 17
  • 32

1 Answers1

1
var postData = @Html.Raw(Json.Encode(@Model));

This line is the culprit. When Razor renders the script, it will assign the original/unchanged model to your postData variable.

If you use "Inspect Element" or dev tools to check the value of postData, you'll see that the values won't change because they're statically assigned.

You need to check for the new values every time you click the button by using

var postData = $("form").serialize();

And be sure to wrap your input fields inside a form tag. See code below:

<form>
   <div class="row">
        <div class="col-1">
            @Html.LabelFor(model => model.Id, "Id:", new {})
        </div>
        <div class="col-4">
            @Html.Label(Model.Id.ToString(), new { title = "" })
        </div>
    </div>

    <div class="row">
        <div class="col-1">
            @Html.LabelFor(model => model.Test, "Test:", new { })
        </div>
        <div class="col-9">
            @Html.TextBoxFor(model => model.Test, new { data_bind = "value: Test", @type = "text" })
        </div>
    </div>
</form>

@section scripts {
     <script type="text/javascript">
             $("#save-click").click(function () {
                 var nr = @Model.Id;

                 // use form.serialize or use the id/class of your form
                 var postData = $("form").serialize();

                 $.ajax({
                     type: "POST",
                     url: actions.test.createOrUpdate + "?id=" + nr,
                     dataType: "json",
                     traditional: true,
                     data: postData,
                     success: function (response) {
                         if (response.Code == 0) {
                                 else {
                                     window.location.reload(false);
                                 }
                         } else {
                             alert('err');
                         }
                     }
                 });
             });
         });
     </script>
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jerdine Sabio
  • 5,688
  • 2
  • 11
  • 23
  • Works perfect! However in addition, I would like to append a value pair ('__RequestVerificationToken', token) to postData. Everything I have tried (.concat, .append ...) did not work though. Any suggestions? – Manu Mar 14 '20 at 22:27
  • 1
    @Manu To add another value pair, just add `+PropertyName=Value` at the end of form serialize. `var postData = $("form").serialize()+"&__RequestVerificationToken="+token;` – Jerdine Sabio Mar 15 '20 at 00:21
  • tried it, no errors in script part but controller does not accept the token. When I add the form data directly into the data of the ajax call such as (data: {name: value, ...} everything works perfectly. However, my form has many input fields ... so I am looking for short way to serialize them. – Manu Mar 15 '20 at 09:07
  • 1
    This might help; https://stackoverflow.com/questions/14473597/include-antiforgerytoken-in-ajax-post-asp-net-mvc – Jerdine Sabio Mar 15 '20 at 09:45