Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass two viewmodels to action

I work around e-commerce`s cart. I have two view models.

First for customers info:

public class CartViewModel
    {
      public string FirstName{get;set;}
      public string Email{get;set;}
      //... other fields
}

And second for customers cart:

 public class ProductsCart
    {
        public Guid Id { get; set; }
        public decimal Price { get; set; }
        public int ItemsOrdered { get; set; }
     }

The main thing is that cart storing in users localStorage and I should pass it from localStorage with customers info via jquery to MVC`s action:

[HttpPost]
public ActionResult ConfirmOrder(CartViewModel model, IEnumerable<ProductsCart> cart)
    {
        // validate and save to database 
    }

And I have javascript method to send data to my action:

function ConfirmOrder() {
    var serverCart = LocalCartToSercerCart(); //see first screnshot 
    var customerData = $("#FORM_WITH_CUSTOMERS_VIEW_MODEL").serialize();   

    $.ajax({
        method: "POST",
        url: "/Cart/ConfirmOrder",
        data: {model: customerData, cart: serverCart  }
    })
    .done(function () {
      //do something
    });

}

But I always getting null value for my CartViewModel (screenshot 2)

I also attached files with my debug info.

If I write javascript function like this:

function ConfirmOrder() {    
  var customerData = $("#cartForm").serialize();

$.ajax({
   method: "POST",
   url: "/Cart/ConfirmOrder",
   data: customerData
  })
 .done(function () {   
   //some code
    });    
}

I getting only model data (see screenshot 3)

enter image description here

enter image description here

enter image description here

EDIT: I wrote code using Igor`s answer, but still getting null in action parameter enter image description here

like image 765
dantey89 Avatar asked May 12 '16 10:05

dantey89


People also ask

Can you pass two models to a view?

Introduction. In MVC we cannot pass multiple models from a controller to the single view. This article provides a workaround for multiple models in a single view in MVC.

Can Viewmodels have methods?

Defines a class used to provide values and methods to the component's view.

What is @model in Cshtml?

The @model directive allows access to the list of movies that the controller passed to the view by using a Model object that's strongly typed. For example, in the Index.cshtml view, the code loops through the movies with a foreach statement over the strongly typed Model object: CSHTML Copy.


2 Answers

The reason you are receiving a null value is because the data is not being converted to JSON before it is sent to the server. The JQUERY ajax call does not do this automatically for you. You can easily convert it using JSON.stringify like so.

$.ajax({
    method: "POST",
    url: "/Cart/ConfirmOrder",
    data: JSON.stringify({model: customerData, cart: serverCart }),
    contentType: 'json' // added to tell the server the format of the data being sent
})
.done(function () {
  //do something
});

JSON.stringify converts your object to properly formatted JSON which is then sent to the server. From the documentation.

The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified, or optionally including only the specified properties if a replacer array is specified.

Note This edit was based on @StephenMuecke comment below. My previous answer was not correct, the only change that was necessary was to your javascript ajax call, not your c# code.

like image 144
Igor Avatar answered Oct 14 '22 09:10

Igor


After many tries I finaly found solution. For me it was this javascript code:

function ConfirmOrder() {

    var serverCart = LocalCartToSercerCart();   
    var customerData = $('#cartForm').serialize();

    var paramObj = {};
    $.each($('#cartForm').serializeArray(), function (_, kv) {
        paramObj[kv.name] = kv.value;
    });

    var Data = {
        model: paramObj,
        cart: serverCart
    }


    $.ajax({
        method: "POST",
        url: "/Cart/ConfirmOrder",
        contentType: 'application/json',
        data: JSON.stringify(Data)

    })
    .done(function () {

    });

}

And this action in MVC :

 [HttpPost]
  public ActionResult ConfirmOrder(CartViewModel model, IEnumerable<ProductsCart> cart)
    {
    // operations with data
    }

The kye was right transformation form data to javacript object. As I understand, Serialize() method convert form to WebForm data and it is not valid to be send as a ONE OF THE PARAMETERS. Serialize() must be whole object... Maybe I'm wrong, you can write your suggetions in comments, I'll be glad to read it.

Special thanks to Igor and StephenMuecke

like image 1
dantey89 Avatar answered Oct 14 '22 10:10

dantey89