首页 > 解决方案 > 无法将javascript对象反序列化为c#

问题描述

我想将模型从控制器操作传递给视图。所以我发送了对象列表并将其转换为 javascript 对象,以使用它在谷歌地图中显示标记。然后我想在单击标记时将选定对象(选定标记)发送到控制器操作。

@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>

这是我的模型课

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; }
}

标记显示在地图中,但是当我选择一个标记并单击发送按钮时,发送的对象是 [object object] 类型,我尝试对其进行反序列化,但出现错误“Primitive JSON non valide: object”

这是我的行动方法

[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");
}

请问有什么建议吗?在此先感谢,并为我糟糕的英语感到抱歉

标签: javascriptajaxasp.net-mvc

解决方案


f.data = JSON.stringify({model})似乎很可疑。您正在这里创建一个包含model在其中的对象。该对象看起来像:

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

您可能只是想要在将其发送到控制器之前f.data = JSON.stringify(model)不会将您的 JS 包装在另一个对象中。model

此外,在您的调试器中,您可以在该行上设置一个断点var dataObject = jss.Deserialize<VehicleFullInformations>(model);并在 C# 中检查model以查看它是否包含您期望的内容。

更新

<button onclick="postData(\'' + model[i]+ '\')">Send</button>几乎可以肯定没有做你想做的事。加载页面后,检查开发工具中的按钮元素,您会发现它可能看起来像<button onclick="postData('[object object]')">...

您可能想做类似的事情<button onclick="postData(' + i + ')">...,然后:

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

推荐阅读