question

NoPatch4HumanSociety-2419 avatar image
0 Votes"
NoPatch4HumanSociety-2419 asked AlbertKallal-4360 answered

Ajax call returns null data, but object is not null

Hi, I've a problem:
I've a javascript in a .cshtml which contains an ajax post call:

 var toExportInPDF = @Html.Raw(Json.Serialize(@Model.DetailsInfoToExport.ToList()));
 console.log(toExportInPDF); //this is not null (array with 2888 records)
         $.ajax({
             type: "POST",
             url: "@Url.Action(nameof(MyController.PostDetails), MvcUtils.GetControllerName(nameof(MyController)))",
             data: { list: toExportInPDF },
             dataType: "json"
         }).done(function (data) {
             const elements = JSON.parse(data);
             console.log(data); //this is null


in MyController.cs, I've:

  [HttpPost]
         public ActionResult PostDetails(List<InfoToExport> list)
         {
             var x = list;
             return new JsonResult(JsonConvert.SerializeObject(x));
         }

@Model.DetailsInfoToExport is a List<InfoToExport> and I'm sure that it is not null.

InfoToExport is:

 public class InfoToExport
     {
         public string Product { get; set; } = string.Empty;
         public string Version { get; set; } = string.Empty;
         public string Vendor { get; set; } = string.Empty;
     }


DetailAnalisysModel is:

 public class DetailAnalisysModel
      {
          public List<InfoToExport> DetailsInfoToExport { get; set; } = new List<InfoToExport>();
      }



But the ajax POST call, returns data null.

Can someone tell me why? I've tried so many ways, but data is still null.

Thank you

PS: my code works on other pages (in <script> section - Javascript), but not here.




dotnet-csharpdotnet-aspnet-generaldotnet-aspnet-core-mvc
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AgaveJoe avatar image
0 Votes"
AgaveJoe answered NoPatch4HumanSociety-2419 commented

Example

 namespace MvcBasic.Controllers
 {
     public class AjaxController : Controller
     {
         [HttpGet]
         public IActionResult Index()
         {
             var data = new DetailAnalisysModel()
             {
                 DetailsInfoToExport = new List<InfoToExport>()
                 {
                     new InfoToExport()
                     {
                         Product = "Widget 1",
                         Vendor = "Vendor 1",
                         Version = "1"
                     },
                     new InfoToExport()
                     {
                         Product = "Widget 2",
                         Vendor = "Vendor 2",
                         Version = "1"
                     }
                 }
         };
             return View(data);
         }
    
         [HttpPost]
         public IActionResult Index([FromBody] List<InfoToExport> list)
         {
             return Ok(list);
         }
     }
     public class DetailAnalisysModel
     {
         public List<InfoToExport> DetailsInfoToExport { get; set; } = new List<InfoToExport>();
     }
     public class InfoToExport
     {
          public string Product { get; set; } = String.Empty;
    
         public string Version { get; set; } = String.Empty;
    
         public string Vendor { get; set; } = String.Empty;
     }
    
 }


Script

     var toExportInPDF = @Html.Raw(Json.Serialize(@Model.DetailsInfoToExport.ToList()));
     console.log(JSON.stringify(toExportInPDF)); 
    
 $.ajax({
     type: "POST",
     url: "/Ajax/Index",
     data: JSON.stringify(toExportInPDF),
     contentType: 'application/json',
     dataType: "json"
 }).done(function(data) {
     console.log(data); 
 });
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@AgaveJoe I'm sorry if i'm inopportune but I love you so muuuch. Thank you, I've been working on it for days.

Thank you

0 Votes 0 ·
AgaveJoe avatar image
0 Votes"
AgaveJoe answered NoPatch4HumanSociety-2419 commented

The JSON format does not match the C# object model structure. The action expects a list of InfoToExport but the client passes the list within another object named list. You should be able to simply change the AJAX data property as below.

 data: toExportInPDF,

If you want to wrap the collection in an object then update the object model and action parameter.

 public class MyModel
 {
     public List<InfoToExport> InfoToExport {get; set;} 
 }
 public class InfoToExport
 {
     public string Product { get; set; } = string.Empty;
     public string Version { get; set; } = string.Empty;
     public string Vendor { get; set; } = string.Empty;
 }

...

 public ActionResult PostDetails(MyModel list)

· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@AgaveJoe Hi, thanks for your reply, but i've already a Model which contains the List<InfoToExport>.

  public class DetailAnalisysModel
     {
         public List<InfoToExport> DetailsInfoToExport { get; set; } = new List<InfoToExport>();
 }

0 Votes 0 ·
AgaveJoe avatar image AgaveJoe NoPatch4HumanSociety-2419 ·

Okay, but your defined the action parameter as a List<InfoToExport> which does not match the type DetailAnalisysModel. Change the action to match the object model.

 public ActionResult PostDetails(DetailAnalisysModel list)

I would pass the collection.


Again the JSON structure must match the action parameter structure.

0 Votes 0 ·

@AgaveJoe no, this is not working for me. I also use the same procedure elsewhere and it works.

0 Votes 0 ·
AlbertKallal-4360 avatar image
0 Votes"
AlbertKallal-4360 answered

When you call a web method, the result is data.d

This is a long time quirk of asp.net

So, this code:

const elements = JSON.parse(data);

should become this:

const elements = JSON.parse(data.d);

The returned "payload" does come back as data in above, but the actual result is data.d, and that .d is where the actual data from the web method will be found. This is even the case for a raw file or whatever.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.