How to use Html.Raw(Json.Encode(Model)) properly?

2019-05-19 01:11发布

问题:

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>
} 

回答1:

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.



回答2:

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));


回答3:

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); });