Alp Arselan
Alp Arselan

Reputation: 13

can't deserialize javascript object to c#

I want to pass a model from the controller action to the view.. so I sent the list of objects and converted it to javascript object to use it for displaying markers in google maps. Then I want when marker clicked, send the selected object (selected marker) to the controller action.

@model List<FleetDesignerMVC.ViewModel.VehicleFullInformations>

<body>
    <div style="width:100%; height:650px" id="map"></div>
</body>

<script>
function initMap() {
  var initialLatLang = {lat: 36.862499, lng: 10.195556};

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 8,
    center: initialLatLang,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });

    //CONVERT CONROLLER MODEL TO JAVASCRIPT OBJECT
    var model = @Html.Raw(Json.Encode(Model));

    var infowindow = new google.maps.InfoWindow;

    //CREATING MARKERS
    for (i = 0; i < model.length; i++) {
      marker = new google.maps.Marker({
          position: new google.maps.LatLng(model[i].VehicleCurrentPosition.Latitude, model[i].VehicleCurrentPosition.Longitude),
          map: map,
          icon: model[i].Vehicle.MarkerPicture
      });


      google.maps.event.addListener(marker, 'click', (function (marker, i) {
          return function () {
              infowindow.setContent('<table>'+
      '<tbody>'+
      '<tr>'+
          '<td><img src="' + model[i].Vehicle.VehiclePicture + '" alt="imageed" width="150" height="150" /></td>'+
          '<td>'+
              '<table>'+
                  '<tbody>'+
                      '<tr>'+
                          '<td><h5>' + model[i].Vehicle.Matricule + '</h5></td>'+
                      '</tr>'+
                  '<tr>' +
                  '<td>Date: ' + new Date(parseInt(model[i].VehicleCurrentPosition.TrackDate.substr(6))).getDate() + '/' + new Date(parseInt(model[i].VehicleCurrentPosition.TrackDate.substr(6))).getMonth() + '/' + new Date(parseInt(model[i].VehicleCurrentPosition.TrackDate.substr(6))).getFullYear() + '</td>' +
                  '</tr>' +
                  '<tr><td>Hour: ' + new Date(parseInt(model[i].VehicleCurrentPosition.TrackDate.substr(6))).getHours() + ':' + new Date(parseInt(model[i].VehicleCurrentPosition.TrackDate.substr(6))).getMinutes() + ':' + new Date(parseInt(model[i].VehicleCurrentPosition.TrackDate.substr(6))).getSeconds() + '</td></tr>' +
                  '<tr>'+
                      '<td>'+
                          '<p>Speed: ' + model[i].VehicleCurrentPosition.Speed + ' Km/H</p>'+
                      '</td>'+
                  '</tr>'+
                  '<tr><td> <button onclick="postData(\'' + model[i]+ '\')">Send</button> </td></tr>' +
                  '</tbody>'+
              '</table>'+
          '</td>'+
      '</tr>'+
      '</tbody >'+
      '</table >');
              infowindow.open(map, marker);
          }
      })(marker, i));
    }
}

function postData(model) {
    var f = {};
        f.type = "POST";
        f.url = '@Url.Action("Index", "VehicleDetails")';
        f.contentType = "application/json; charset=utf-8";
        f.data = JSON.stringify({model});
        f.dataType = "json";
        f.success = function (response) {
            alert("success");
        };
        f.error = function (response) {
            alert("failed");
        };
        $.ajax(f);
};
</script>

This is my model class

public class VehicleFullInformations
{
    public Vehicle Vehicle { get; set; }
    public Brand VehicleBrand { get; set; }
    public Model VehicleModel { get; set; }
    public VehicleType VehicleType { get; set; }
    public GpsTrack VehicleCurrentPosition { get; set; }
    public FuelType VehicleFuelType { get; set; }
}

The markers are displayed in the map but when I select one marker and click send button, The object sent is of type [object object], I tried to deserialize it but I got an error "Primitive JSON non valide : object"

This is my action method

[HttpPost]
public ActionResult Index(string model)
{
    var jss = new JavaScriptSerializer();
    var dataObject = jss.Deserialize<VehicleFullInformations>(model);
    Console.WriteLine(dataObject);
    // .. do something with data object 
    return Json("OK");
}

Any suggestions please ? thanks in advance and sorry about my poor english

Upvotes: 1

Views: 192

Answers (1)

mlibby
mlibby

Reputation: 6734

f.data = JSON.stringify({model}) seems suspicious. You are creating an object here with model inside it. The object looks like:

{
  model: {
    ... your actual model ...
  }
}

You probably just want f.data = JSON.stringify(model) which will not wrap your JS model in another object before sending it to the controller.

Also, in your debugger, you can set a breakpoint on the line var dataObject = jss.Deserialize<VehicleFullInformations>(model); and inspect model in C# to see if that contains what you expect.

UPDATE

<button onclick="postData(\'' + model[i]+ '\')">Send</button> is almost certainly not doing what you want it to. Once your page has loaded, inspect the button element in your dev tools and you'll see that it probably looks like <button onclick="postData('[object object]')">...

You probably want to do something like <button onclick="postData(' + i + ')">... and then:

function postData(modelIndex) {
   let postModel = model[modelIndex];
   ...
       f.data = JSON.stringify(postModel);
   ...
}

Upvotes: 1

Related Questions