I'm getting started with WebAPI and for the most part all is going well. I'm running into a problem with one particular function. This one differs from the other because it's only parameter is of type IEnumerable.
I've set a breakpoint on the first line of the Post() function and I'm hitting the function but the "values" parameter ALWAYS has a count of 0. I verified that the parameter going in on the client side does, in fact, contain an array of integers. If I remove the [FromUri] attribute, the 'values' parameter is NULL instead of a count of 0.
How do I get my array of integers to come through on my WebAPI function?
Here's the WebAPI function:
[System.Web.Mvc.HttpPost]
public void Post([FromUri] IEnumerable<int> values)
{
if (values == null || !values.Any()) return;
int sortorder = 1;
foreach (int photoId in values)
{
_horseRepository.UpdateSortOrder(photoId, sortorder);
sortorder++;
}
}
Here's the AJAX call (this is using the jQuery UI Sortable feature):
$(".sortable").sortable({
update: function (event, ui) {
var newArray = $(".sortable").sortable("toArray");
$.ajax({
url: '/api/photo',
type: 'POST',
contentType: 'application/json, charset=utf-8',
async: true,
dataType: 'json',
data: JSON.stringify(newArray),
complete: function (data) { }
});
}
});
contentType: 'application/json, charset=utf-8',
should become (the separator between the content type and the charset is a semicolon, not a comma):
contentType: 'application/json; charset=utf-8',
and:
public void Post([FromUri] IEnumerable<int> values)
should become (there are no Uri parameters in a POST request):
public void Post(IEnumerable<int> values)
Now you are good to go assuming that newArray (which you haven't shown here) is an array of integers:
newArray = [ 1, 2, 3 ]
Related
I have defined a webMethod in code behind as follows.
[System.Web.Services.WebMethod]
public static string testCall(int qid, String answerContent)
{
log.Debug("this is call from jquery" + qid.ToString() + answerContent);
return "true";
}
I am trying to call this method via ajax call in jquery as below.
<script>
$(".submitBtn").click(function (e) {
alert(this.id);
var qID = this.id;
$.ajax({
type: "POST",
url: '/default.aspx/testCall',
data: '{ "qid":' + qID + ', "answerContent":"test" }',
contentType: "application/json; charset=utf-8",
success: function () {
},
failure: function (response) {
alert("fail");
},
dataType: 'html'
});
});
</script>
But this is not working.
However is I pass hardcoded values for parameters as below, it works fine.
data: '{ "qid":"1234", "answerContent":"test" }'
But with var qID passing as parameter not working
Don't hand-assemble JSON. You will get bitten by characters you don't expect in strings, you'll miss out delimiters, etc.
Instead, use the JSON stringifier:
data: JSON.stringify({qid: qID, answerContent:"test"}),
If the ID value is really a number (you're receiving it as an int), you'll want to parse it (as this.id is a string):
data: JSON.stringify({qid: +qID, answerContent:"test"}),
// ------------------------^
...but your hardcoded example that you said works uses a string for the ID, so...
You should use this line as:
data: '{ "qid": "' + qID + '", "answerContent":"test" }'
I am running into some trouble with my ajax call. Here is the controller code:
[Route("RatingInfo/HandleRequest")]
[HttpPost]
public ActionResult HandleRequest(Dictionary<string, string> textBoxValues)
{
var result = CreateJson(textBoxValues); // This is a simplified example
return Json(result);
}
And here is my Jquery/ajax (Razor syntax):
function PassData () {
var data = {};
$('.divCell input').each(function (index, item) {
var id = $(item).attr('id');
var value = item.value;
data['dictionary[' + index + '].Key'] = id;
data['dictionary[' + index + '].Value'] = value;
});
$.ajax({
url: '#Url.Action("HandleRequest")',
type: 'POST',
dataType: 'JSON',
traditional: true,
data: data,
sucesss: function (result) {
alert('Success');
}
})
}
The idea here is to get the data from each textbox and pass it back to the server as a Dictionary with the id as the key and value as, well, the value.
Stepping through the Chrome debugger, the JS data object is built successfully.
From the debugger:
Local
data: Object
dictionary[0].Key: "Address"
dictionary[0].Value: "123 Main St"
dictionary[1].Key: "ZipCode"
dictionary[1].Value: "99999"
dictionary[2].Key: "Phone1"
dictionary[2].Value: "(555) 555-5555"
...
__proto__: Object
However, when the data is passed back to the controller, the values inside textBoxValues does not contain the passed data. Rather, it contains two key/value pairs with keys controller and action and values the names of the controller and action.
From the Visual Studio debugger:
textBoxValues = Count = 2
[0] = {[controller, RatingInfo]}
[1] = {[action, HandleRequest]}
How can I get Jquery to pass the data rather than the controller/action names? I am confused as to how this can even happen in the first place. Any help would be appreciated.
UPDATE
Sorry, I had put wrong code in.
The reason why this was not working is because the name of the parameter was incorrect, giving you a mismatch.
The below will work for you. Notice the name of dictionary is changed to your parameter textBoxValues:
function PassData() {
var data = {};
$('.divCell input').each(function (index, item) {
var id = $(item).attr('id');
var value = item.value;
data['textBoxValues[' + index + '].Key'] = id;
data['textBoxValues[' + index + '].Value'] = value;
});
$.ajax({
url: '#Url.Action("HandleRequest")',
type: 'POST',
traditional: true,
data: data,
sucesss: function (result) {
alert('Success');
}
})
}
I was trying to pass json data to .net mvc controller. it seems like mvc automatically converted id and lastdatetime to correct format, but not int[] currentIds, anyone know why?
var jsonData = {
"id": id,
"lastDataTime": lastDateTime,
"currentIds": [1, 2, 3, 4]
};
public void Process(int id, DateTime lastDateTime, int[] currentIds)
{
}
Please try this:
$.ajax({
type: "POST",
url:"#Url.Action("Index", "Home")" ,
data: {
"id": id,
"lastDataTime": lastDateTime,
"currentIds": [1, 2, 3, 4]
},
dataType: "json",
traditional: true,
success: function(msg){
alert(msg)
}
});
public ActionResult Index(int id, DateTime lastDateTime, int[] currentIds)
{
}
Simplify this problem and get the array working first, try this:
View
var myArray = ["1", "2", "3","4"];
$.ajax(
{
type: "POST",
url: '/ControllerName/ActionMethod/',
data: JSON.stringify(myArray),
cache: false,
//dataType: "html",
success: ///
})
Controller
public ActionResult Index(List<String> currentIds)
{
///
}
Debug this and check the list is populated then introduce the other objects.
I'm building a comma separated string and passing it to my WebAPI method like so:
var projectids="";
for (var i = 0; i < chk.length; i++) {
projectids += chk[i].VMIProjectId + ",";
}
//projectids = "1,2,3"
$.ajax({
type: 'POST',
url: "http://localhost:52555/device/6/AddProjectsToDevice",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(projectids),
success: function (msg) {
},
error: function (data) {
debugger;
}
});
I 'm reaching the WebApi method successfully, but my IEnumerable array projectIds is always null. Here's the method:
[HttpPost]
[Route("device/{deviceId}/AddProjectsToDevice")]
public IEnumerable<VMI_DeviceLinkedProject> AddProjectsToDevice([FromUri]long deviceId,[FromBody] IEnumerable<long> projectIds){}
How do i pass my comma separated list of ids to my WebAPI method? Thanks for reading
Right now your controller action is getting a comma separated string of numbers and not a JSON array ("[1,2,3,4]"), which is why the model binder isn't working:
var projectids = [];
for (var i = 0; i < chk.length; i++) {
projectids.push(chk[i].VMIProjectId);
}
And then the stringified array should bind to the IEnumerable<long> properly.
Instead of passing it as a csv value you can pass it as an array using the same code as below,
var projectIdList =[];
for (var i = 0; i < chk.length; i++) {
projectIdList.push(chk[i].VMIProjectId);
}
Similarly change the parameter name in api method also as projectIdList and pass it.
I have the following C# code in my API-controller:
public JsonResult GetProjects()
{
List<ProjectItem> list = ProjectItem.Get();
return new JsonResult() {Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet};;
}
I stepped through this code and found out that the list contains elements on this point. But in the Ajax-call I'm calling the code I try to iterate over the single elements with Jquery and try to use them. But the elements are always null.
Typescript Ajax-Call:
$.ajax({
url: "/api//MyControllerName",
type: "GET",
cache:false,
dataType: "json",
success: (result) => {
base.projects.removeAll();
$.each(result, (index: number, element: any) => {
//Here the element from the list should be used, but it is always null
});
});
}
});
What is wrong with this code?
Okay, found the solution to my problem myself:
I tried to iterate over the result, but I have to iterate over the Data-Property of the result.
With this code it works:
$.each(result.Data, (index: number, element: any) => {
//Element is defined
}