4

I'm working on an ASP.NET MVC 4 website and I've got some troubles with a functionality. I explain, I've to select entities displayed in a table with their linked checkbox :

Screenshot of my table where each row has a checkbox with the same Id as the entity

Console showing updates in the array

Inside my script I have been abled to store each checked Id's checkbox in an array and remove those if the checkbox is unchecked. But I can't pass the array to my controller's function to delete each selected entity in the database. I used $.ajax() from jquery to send through a POST request the array (as JSON) but I always get 500 error :

  • JSON primitive invalid
  • Null reference

Here's my function in my script (I don't know if my array's format is valid) :

 var sendDocsToDelete = function (docsArray) {
 $.ajax({
 type: 'POST',
 url: 'Main/DeleteDocuments',
 data: JSON.stringify(docsArray),
 contentType: 'application/json; charset=utf-8',
 datatype: 'json',
 success: function (result) {
 alert('Success ' + result.d);
 },
 error: function (result) {
 alert('Fail ' + result.d);
 }
 });
 }

Then, the POST call the following function in my controller :

 [Authorize]
 [WebMethod]
 public void DeleteDocuments(string docsToDelete)
 {
 int id; 
 string[] arrayDocs = JsonConvert.DeserializeObject<string[]>(docsToDelete);
 foreach (string docId in arrayDocs)
 {
 int.TryParse(docId, out id);
 dal.DeleteDocument(id); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
 }
 }

Update 2

 [Authorize]
 public ActionResult DeleteDocuments(int[] docsToDelete)
 {
 try{
 foreach (string docId in arrayDocs)
 {
 int.TryParse(docId, out id);
 dal.DeleteDocument(id); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
 }
 return Json("Success");
 } 
 catch 
 {
 return Json("Error");
 }
 }
 var sendDocsToDelete = function (docsArray) {
 $.ajax({
 type: 'POST',
 url: 'Main/DeleteDocuments',
 data: docsArray,
 contentType: 'application/json; charset=utf-8',
 datatype: 'json',
 success: function (result) {
 alert('Success ' + result.d);
 },
 error: function (result) {
 alert('Fail ' + result.d);
 }
 });
 }

Any ideas about this issue ? I hoped I was clear enough. Do not hesitate if you need more details.

asked May 19, 2016 at 13:51
6
  • 2
    why using a webMethod in MVC ? you can just use ActionResult Commented May 19, 2016 at 13:55
  • 1
    You don't need to stringify the data yourself, just pass the array as it is. And you don't need to deserialize it yourself either, just accept string[] docsToDelete and let the modelbinder handle that for you. Commented May 19, 2016 at 13:58
  • @Reddy I thought it was compulsory by this way because I wasn't expecting a view but an asynchronous update of the actual view. Commented May 19, 2016 at 14:08
  • @DavidHedlund I tried but it still fails to recognize my parameter... Commented May 19, 2016 at 14:09
  • @Loïc you can pass back string too from the ActionResult.. Commented May 19, 2016 at 14:11

4 Answers 4

5

If you are passing an integer array properly from $.ajax (i.e. your docsArray should be having value like [15,18,25,30,42,49]) then you should try :

[Authorize]
public ActionResult DeleteDocuments(int[] docsArray)
{
 //int id; 
 //string[] arrayDocs = JsonConvert.DeserializeObject<string[]>(docsToDelete);
 try {
 foreach (int docId in docsArray)
 {
 //int.TryParse(docId, out id);
 dal.DeleteDocument(docId); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
 }
 return "Success ";
 }
 catch {
 return "Error";
 }
}

Update :

Your javascript code should be :

var sendDocsToDelete = function (docsArray) {
 $.ajax({
 type: 'POST',
 url: 'Main/DeleteDocuments',
 data: JSON.stringify(docsArray),
 contentType: 'application/json; charset=utf-8',
 datatype: 'json',
 success: function (result) {
 alert('Success ');
 },
 error: function (result) {
 alert('Fail ');
 }
 });
}
answered May 19, 2016 at 14:01

5 Comments

It have to parse it because my Ids are "checkbox123"
"checkbox123" can not be parse in int, you have to pass integer ids like 123 only.. you can see this : stackoverflow.com/questions/2099164/…
I doubt that AJAX will even hit this method in the first place. Its not a ActionResult
Thanks @Reddy, added ActionResult
@Sachin @Reddy So, I change Ids to be integer (in my view and when I push values in array). But I get again the exception : System.ArgumentException - Primitive JSON invalid : undefined
0

Maybe the datatype in the JSON array is not a string? (This could happen if you have an array in the form of [45,64,34,6], or a mixed one like [345,"wef4"]).

To make sure something is a string in Javascript you can do this: var string = "".concat(otherVar);

answered May 19, 2016 at 13:57

1 Comment

Each element in my array are Id defined in my view such as "checkbox123" and in the console I print each value.
0

Try changing your ajax data to something like this..

 data : JSON.stringify({'docsToDelete':docsArray}),
answered May 19, 2016 at 14:00

Comments

0

Make these changes to your code.


In Jquery

data: docsArray, no need to stringify the array


In Controller

 [Authorize] //remove [WebMethod]
 public ActionResult DeleteDocuments(string[] docsToDelete) //Add ActionResult, Change parameter to accept array
 {
 int id; 
 string[] arrayDocs = docsToDelete; //no need of deserilization
 foreach (string docId in arrayDocs)
 {
 int.TryParse(docId, out id);
 dal.DeleteDocument(id); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
 }
 return Json(id); //return id back to ajax call...
 }
answered May 19, 2016 at 14:10

3 Comments

Am I maybe missing something but VS says that the ActionResult can't be an integer... Cast not working either.
@Loïc my bad it should be return Json(id);
Ok it makes sense, i'll try

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.