0

I'm passing two objects to my controller:

[HttpPost]
public ActionResult GetSelectedQuote(CarQuoteRequestViewModel carModel, QuoteViewModel quoteModel)
 {
      return PartialView("_QuoteSelected", quoteModel);
 }

The AJAX call is the following (I've hardcoded the JSON string so you can see what it looks like, but normally I would use the ser $.ajax("getSelectedQuote", {

            //data: ko.toJSON({ model: self.selectedQuote, model1: $("#etape").serializeArray() }),
            data:  ko.toJSON({"quoteModel":{"ProductName":"Classic","MonthPrice":98.19,"QuarterPrice":291.64,"BiannualPrice":577.37,"YearPrice":1142.94,
    "CoverQuotesViewModel":[
    {"ProductName":"Classic","Label":"Responsabilité Civile","IsVisible":false,"IsMandatory":false,"IsSelected":false,"YearPrice":338.17,"BiannualPrice":170.83,"QuarterPrice":86.29,"MonthPrice":29.05},        
    {"ProductName":"Classic","Label":"Première Assistance 24h/24 (GRATUITE)","IsVisible":false,"IsMandatory":false,"IsSelected":false,"YearPrice":0,"BiannualPrice":0,"QuarterPrice":0,"MonthPrice":0},
    {"ProductName":"Classic","Label":"Dommage (DM TCC 0%)","IsVisible":false,"IsMandatory":false,"IsSelected":false,"YearPrice":717.47,"BiannualPrice":362.44,"QuarterPrice":183.07,"MonthPrice":61.64},
    {"ProductName":"Classic","Label":"Individuelle Circulation","IsVisible":false,"IsMandatory":false,"IsSelected":false,"YearPrice":67.9,"BiannualPrice":34.3,"QuarterPrice":17.33,"MonthPrice":5.83},
    {"ProductName":"Classic","Label":"Protection Juridique","IsVisible":false,"IsMandatory":false,"IsSelected":false,"YearPrice":19.4,"BiannualPrice":9.8,"QuarterPrice":4.95,"MonthPrice":1.67}
    ]},

"carModel": [
        {"name":"DriverInfoViewModel.DriverInfo.NoClaimsDegree","value":"1"},
            {"name":"DriverInfoViewModel.DriverInfo.DrivingLicenceDate","value":"2013-03-02"},
            {"name":"DriverInfoViewModel.DriverInfo.DisasterHistory","value":"MoreThanTwoDisasters"},
            {"name":"CarInfoViewModel.CarInfo.CarValue","value":"15000"},
            {"name":"CarInfoViewModel.CarInfo.AudioValue","value":"1000"},
            {"name":"CarInfoViewModel.CarInfo.EngineCapacity","value":"1500"},
            {"name":"CarInfoViewModel.CarInfo.AdditionalSeats","value":"1"},
            {"name":"CarInfoViewModel.CarInfo.FirstRegistration","value":"2013-03-02"}
       ]}),
            type: "post", contentType: "application/json",
            success: function (result) {
                $("#custom").html(result);
                $("#etape").formwizard("show", "customize");
            }
        });

The strange thing, is that the QuoteViewModel is perfectly rebuild when the controller is hit. However the CarQuoteRequestViewModel object is not. The properties are empty.

The ViewModel objects are the following:

public class CarQuoteRequestViewModel : QuoteRequestViewModel
{       
    public CarInfoViewModel CarInfoViewModel { get; set; }
    public DriverInfoViewModel DriverInfoViewModel { get; set; }

    public CarQuoteRequestViewModel()
    {
        CarInfoViewModel = new CarInfoViewModel();
        DriverInfoViewModel = new DriverInfoViewModel();
    }
}


public class QuoteViewModel
{
    public string ProductName { get; set; }
    public decimal MonthPrice { get; set; }
    public decimal QuarterPrice { get; set; }
    public decimal BiannualPrice { get; set; }
    public decimal YearPrice { get; set; }

    public List<CoverQuoteViewModel> CoverQuotesViewModel { get; set; }
}

I'm not posting all the nested objects for now, because it works fine for the QuoteViewModel. Do you have any idea what might be wrong with the CarQuoteRequestViewModel mapping from JSON ?

EDIT

As per Darin recommendation I've changed the JSON to:

  data: ko.toJSON({ "model": { "ProductName": "Classic", "MonthPrice": 98.19, "QuarterPrice": 291.64, "BiannualPrice": 577.37, "YearPrice": 1142.94,
                "CoverQuotesViewModel": [
    { "ProductName": "Classic", "Label": "Responsabilité Civile", "IsVisible": false, "IsMandatory": false, "IsSelected": false, "YearPrice": 338.17, "BiannualPrice": 170.83, "QuarterPrice": 86.29, "MonthPrice": 29.05 },
    { "ProductName": "Classic", "Label": "Première Assistance 24h/24 (GRATUITE)", "IsVisible": false, "IsMandatory": false, "IsSelected": false, "YearPrice": 0, "BiannualPrice": 0, "QuarterPrice": 0, "MonthPrice": 0 },
    { "ProductName": "Classic", "Label": "Dommage (DM TCC 0%)", "IsVisible": false, "IsMandatory": false, "IsSelected": false, "YearPrice": 717.47, "BiannualPrice": 362.44, "QuarterPrice": 183.07, "MonthPrice": 61.64 },
    { "ProductName": "Classic", "Label": "Individuelle Circulation", "IsVisible": false, "IsMandatory": false, "IsSelected": false, "YearPrice": 67.9, "BiannualPrice": 34.3, "QuarterPrice": 17.33, "MonthPrice": 5.83 },
    { "ProductName": "Classic", "Label": "Protection Juridique", "IsVisible": false, "IsMandatory": false, "IsSelected": false, "YearPrice": 19.4, "BiannualPrice": 9.8, "QuarterPrice": 4.95, "MonthPrice": 1.67 }
    ]
            },

                "model1":
        { "DriverInfoViewModel.DriverInfo.NoClaimsDegree" : "1",
            "DriverInfoViewModel.DriverInfo.DrivingLicenceDate" : "2013-03-02",
             "DriverInfoViewModel.DriverInfo.DisasterHistory" : "MoreThanTwoDisasters",
            "CarInfoViewModel.CarInfo.CarValue": "15000",
            "CarInfoViewModel.CarInfo.AudioValue" : "1000",
            "CarInfoViewModel.CarInfo.EngineCapacity" : "1500",
            "CarInfoViewModel.CarInfo.AdditionalSeats" : "1",
            "CarInfoViewModel.CarInfo.FirstRegistration" : "2013-03-02"
        }
            }),
Sam
  • 13,934
  • 26
  • 108
  • 194

1 Answers1

1

In your JSON you are passing a collection (notice the square brackets) of an object with properties Name and Value:

"carModel": [ ... ]

but your controller action expects a single CarQuoteRequestViewModel.

So either fix your JSON request or if you want to send multiple cars make sure that you use the proper type on your controller action.

I don't see any Name and Value properties on your CarQuoteRequestViewModel, so even if you change your controller action to take a collection of CarQuoteRequestViewModel it is unlikely that this is going to work. The JSON you are passing must conform to your model.

If you want to keep your CarQuoteRequestViewModel you should fix your JSON:

"carModel": {
    "carInfoViewModel": {
        ...
    },
    "driverInfoViewModel": {
        ...
    }
}

UPDATE:

It looks like you are attempting to serialize some form element ($('#etape')) to JSON. You should not use the serializeArray method because this method generates incorrect JSON as I have already explained. You get a name/value collection. You could use the serializeObject method shown in this post.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • the json I've posted was generated by the following code: data: ko.toJSON({ model: self.selectedQuote, model1: $("#etape").serializeArray() }). I do not want to pass an array indeed. Then what should the JSON look like (so I can test if it works) and then how do I generate the correct JSON (I've tried serialize instead of SerializeArray, but that gives me a string and it fails to convert both objects) – Sam Mar 08 '13 at 15:26
  • Thanks, yes you are right, the JSON was incorrect. Now it works with the JSON i've added to my original post. But the question remains : How do I generate that JSON string ???? If I use form.serializeArray I get the incorrect JSON string. – Sam Mar 08 '13 at 15:34
  • Use the `serializeObject` method from this post: http://stackoverflow.com/a/1186309/29407 I have updated my answer accordingly. – Darin Dimitrov Mar 08 '13 at 15:52
  • yes, I've been using the serializeObject method from https://github.com/macek/jquery-serialize-object, and it works great ! – Sam Mar 08 '13 at 16:08