简体   繁体   中英

How to POST object using AJAX and get with ASP.NET Core MVC controller?

I have a single page with ASP.NET Core and wanna save the model, Product , with an AJAX form. My problem arises when I click the submit button to post the data with AJAX, I get a null model in the controller.

my problem in the controller

This model Product :

public class Product
{
    [Key]
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public string Model { get; set; }
    public uint price { get; set; }
    public string Descriprion { get; set; }
}

This is the AJAX code:

<script type="text/javascript">
    $(document).on('click', '#submitdate', function (evt) {
        evt.preventDefault();
        var data = new FormData();

        $('input').each(function (index,filds) {
            data.append($(filds).attr('name'), $(filds).val());
        });
        
        $.ajax({
            type: "POST",
            url: '@Url.Action("Index","Home")',
            data: data
        });
    });
</script>

This is the Controller :

[HttpPost]
public IActionResult Index(Product model)
{
    _context.products.Add(model);
    _context.SaveChanges();

    return Json(new { status = "success", message = "successfully save new product" });
}

This is Form in View :

<form method="post" enctype="multipart/form-data">
                <div class="modal-body form-horizontal">
                    <div class="row">
                    
                        <div class="form-group">
                            <label asp-for="ProductName" class="col-lg-2 col-sm-2 control-label"></label>
                            <div class="col-lg-6">
                                <input asp-for="ProductName" name="ProductName" class="form-control" />
                            </div>
                        </div>

                        <div class="form-group">
                            <label asp-for="Model" class="col-lg-2 col-sm-2 control-label"></label>
                            <div class="col-lg-6">
                                <input asp-for="Model" name="Model" class="form-control" />
                            </div>
                        </div>
                        <div class="form-group">
                            <label asp-for="price" class="col-lg-2 col-sm-2 control-label"></label>
                            <div class="col-lg-6">
                                <input asp-for="price" name="price" class="form-control" />
                            </div>
                        </div>

                        <div class="form-group">
                            <label asp-for="Descriprion" class="col-lg-2 col-sm-2 control-label"></label>
                            <div class="col-lg-6">
                                <input asp-for="Descriprion" name="Descriprion" class="form-control" />
                            </div>
                        </div>  
                    </div>
                </div>
                <input type="button" id="submitdate" class="btn btn-submit" value="save" />    
            </form>

where am I mistake? and how to solve it?

You can try this code:

 <script type="text/javascript"> $(document).ready(function(){ $("#submitdate").click(function(evt){ evt.preventDefault(); $.post('@Url.Action("Index","Home")', $("form").serialize(), function(data, status){ if(status == "success") { //add code } }) }) }) </script>
 <form method="post" enctype="multipart/form-data"> <div class="modal-body form-horizontal"> <div class="row"> <div class="form-group"> <label asp-for="ProductName" class="col-lg-2 col-sm-2 control-label"></label> <div class="col-lg-6"> <input asp-for="ProductName" name="ProductName" class="form-control" /> </div> </div> <div class="form-group"> <label asp-for="Model" class="col-lg-2 col-sm-2 control-label"></label> <div class="col-lg-6"> <input asp-for="Model" name="Model" class="form-control" /> </div> </div> <div class="form-group"> <label asp-for="price" class="col-lg-2 col-sm-2 control-label"></label> <div class="col-lg-6"> <input asp-for="price" name="price" class="form-control" /> </div> </div> <div class="form-group"> <label asp-for="Descriprion" class="col-lg-2 col-sm-2 control-label"></label> <div class="col-lg-6"> <input asp-for="Descriprion" name="Descriprion" class="form-control" /> </div> </div> </div> </div> <input type="button" id="submitdate" class="btn btn-submit" value="save" /> </form>

I wasn't able to find a way to make it work with the FormData approach that you have tried. However I was able to get it to work sending the data as JSON instead.

To do this method you need to make the following changes.

Change the jQuery to this

<script type="text/javascript">
    $(document).on('click', '#submitdate', function (evt) {         
        evt.preventDefault();           
        var data = {}; 
        $('input').each(function (index, filds) {

            var $filds = $(filds);

            if ($filds.attr('name')) {                  
                var val = $filds.val();
                if ($filds.hasClass("js-is-int")) {
                    val = parseInt(val);
                }
                data[$filds.attr('name')] = val;      
            }              
        });
            
            $.ajax({
                type: "POST",
                url: '@Url.Action("Index","Home")',
                data: JSON.stringify(data),   
                contentType: "application/json; charset=utf-8"
            });
        });
</script>

and change the form to this

<form method="post">
    <div class="modal-body form-horizontal">
        <div class="row">
            <div class="form-group">
                <label asp-for="ProductName" class="col-lg-2 col-sm-2 control-label"></label>
                <div class="col-lg-6">
                    <input asp-for="ProductName" name="ProductName" class="form-control" />
                </div>
            </div>
            <div class="form-group">
                <label asp-for="Model" class="col-lg-2 col-sm-2 control-label"></label>
                <div class="col-lg-6">
                    <input asp-for="Model" name="Model" class="form-control" />
                </div>
            </div>
            <div class="form-group">
                <label asp-for="price" class="col-lg-2 col-sm-2 control-label"></label>
                <div class="col-lg-6">
                    <input asp-for="price" name="price" class="form-control js-is-int"/>
                </div>
            </div>
            <div class="form-group">
                <label asp-for="Descriprion" class="col-lg-2 col-sm-2 control-label"></label>
                <div class="col-lg-6">
                    <input asp-for="Descriprion" name="Descriprion" class="form-control" />
                </div>
            </div>
        </div>
    </div>
    <input type="button" id="submitdate" class="btn btn-submit" value="save" />
</form>

Note that enctype="multipart/form-data" is not needed.
I've added the class js-is-int to the price input. This is because its value on the server is a uint. If this is sent as a string the model binding doesn't work. So I've added the class so that when the data is created parseInt is used to cast it to an integer.

Finally the controller logic becomes this

[HttpPost]
public IActionResult Index([FromBody]Product model)
{
    _context.products.Add(model);
    _context.SaveChanges();

    return Json(new { status = "success", message = "successfully save new product" });
}  

Note the use of [FromBody] which is needed when you are model binding a JSON post.

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