简体   繁体   中英

How do I send a view model to the controller via ajax which includes form data but not by clicking the submit button

I am working on an ASP.NET Core 2.1 Web App which quotes for products. I am trying to send the view model to the controller via ajax, which will return a view model with a calculated quote total and display it in the partial view.

I am able to send the model to the controller but the model only contains the default values that were loaded into the view and none of the form input values. I feel like i'm missing something really simple here. I've tried a lot of options including serialising the form, which gets the values into the controller but misses the rest of the model.

The code below sends the model to the controller when the function is called (which is what I want) but does not include the values inputted into the form. Is there a way to achieve this or does the whole thing need reworking?

Help me Stack Overflow, you are my only hope.

Controller

   [HttpPost]
    public ActionResult CalculateItemQuote(string jsonString)
    {

        BifoldItemViewModel bifoldItemViewModel = JsonConvert.DeserializeObject<BifoldItemViewModel>(jsonString);

        // Do calculations and return view model to partial view.

        return PartialView("~/Views/Shared/_BifoldItemHeader.cshtml", bifoldItemViewModel);
    }

Script

function RefreshHeaderValue() {

    var serModel =  '@Html.Raw(Json.Serialize(@Model))';
          console.log(serModel);
      $.ajax({
            url: '@Url.Action("CalculateItemQuote", "Quote")',
            type: 'POST',
            data: { jsonString: serModel },
          dataType: 'json',
          traditional: true,
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
            success: function (data) {
                $("#bifoldHeaderPartial").html(data);
                $('#bifoldHeaderPartial').show();
            }
        });
    };

View

                <div class="form-group col-md-6">
                    <label asp-for="thisBifoldItem.Width"></label>
                    <input asp-for="thisBifoldItem.Width" class="form-control" autocomplete="nay" />
                    <span asp-validation-for="thisBifoldItem.Width" class="text-danger"></span>
                </div>

                <div class="form-group col-md-6">
                    <label asp-for="thisBifoldItem.Height"></label>
                    <input asp-for="thisBifoldItem.Height" class="form-control" autocomplete="nay" />
                    <span asp-validation-for="thisBifoldItem.Height" class="text-danger"></span>
                </div>


                <div class="form-group col-md-4">
                    <label asp-for="DoorQuantityOptions" class="control-label">How Many Doors?</label>
                    <select asp-for="SelectedDoorQuantity" id="DoorQuantityOptions" class="form-control" asp-items="@Model.DoorQuantityOptions">
                        <option value="" selected disabled>-- Select --</option>
                    </select>
                </div>

========== UPDATED SOLUTION==========

Thanks to kbaccouche for pushing me in the right direction. The following now works

Controller


[HttpPost] public ActionResult CalculateItemQuote(BifoldItemViewModel bifoldItemViewModel) {

        //Do stuff here

        return PartialView("~/Views/Shared/_BifoldItemHeader.cshtml", bifoldItemViewModel);
    }

Script


function RefreshHeaderValue() {

      $.ajax({
            url: '@Url.Action("CalculateItemQuote", "Quote")',
            type: 'POST',
          data: $("#myForm").serialize(),
          dataType: 'json',
          traditional: true,
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
            success: function (data) {
                $("#bifoldHeaderPartial").html(data);
                $('#bifoldHeaderPartial').show();
            }
        });
    };

I tried to create a sample application using your code, and I got it to work using standard MVC model binding. Here is the code

Controller

public class QuoteController : Controller
{
    // POST: Quote/Create
    [HttpPost]
    public ActionResult CalculateItemQuote(ProductForm model)
    {
        var bifoldItemViewModel = new BifoldItemViewModel();
        return PartialView("~/Views/Shared/_BifoldItemHeader.cshtml", bifoldItemViewModel);
    }
}

public class ProductForm
{
    public string ProductId { get; set; }
    public string Quantity { get; set; }
}

public class BifoldItemViewModel
{

}

HTML + Javascript

@{
   ViewData["Title"] = "Home Page";
 }

<form>
  <input id="ProductId" name="ProductId" type="text" />
  <input id="Quantity" name="Quantity" type="text" />
  <a id="submitForm" class="btn">Submit</a>
</form>

<div class="text-center">
  <h1 class="display-4">Welcome</h1>
  <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<div id="bifoldHeaderPartial">

</div>

@section Scripts{
  <script type="text/javascript">
    $('a#submitForm').click(function () {
    $.ajax({
        url: '@Url.Action("CalculateItemQuote", "Quote")',
        type: 'POST',
        data: {
            'ProductId': $('#ProductId').val(),
            'Quantity': $('#Quantity').val()
        },
      dataType: 'json',
      traditional: true,
        contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
        success: function (data) {
            $("#bifoldHeaderPartial").html(data);
            $('#bifoldHeaderPartial').show();
        }
    });
  });
 </script>
}

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