Send array to MVC controller via JSON? - c#

I am trying, and struggling, to send an array via JSON to a MVC controller action.
Here is what I have and what i've tried...
//Get checked records
var $checkedRecords = $(':checked'); //e.g. 3 rows selected = [input 4, input 5, input 6]
//Have tried following:
sendingVar: $checkedRecords.serializeArray(); // gives array of 0's
sendingVar: JSON.stringify($checkedRecords); // gives "{\"length\":1,\"prevObject\":{\"0\":{\"jQuery1313717591466\":1,\"jQuery1313717591653\":13},\"context\":{\"jQuery1313717591466\":1,\"jQuery1313717591653\":13},\"length\":1},\"context\":{\"jQuery1313717591466\":1,\"jQuery1313717591653\":13},\"selector\":\":checked\",\"0\":{}}"...wtf
//Post
$.post(url, { sendingVar: sendingVar }, function(data) {alert(data); });
How do I do it ?
edit: to those that suggest sending $checkedRecords "as is" from the top line - that is not working. I get a strange exception somewhere in the jquery framework :(
uncaught exception: [Exception... "Could not convert JavaScript argument" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: http://.../.../.../jquery-1.4.4.min.js :: <TOP_LEVEL> :: line 141" data: no]
which I think means it is attempting to assign null to something it cannot.
Edit: i'm using MVC2 not 3
Edit2: After #Monday's answer- the problem is due to how I have built the array like [input 4, input 5, input 6] and not [4,5,6] - any ideas how I can just get the values in the array instead ?
Edit3: Stop voting up duplicate when it's not. Did you actually read my problem or read the problems linked? this is a different issue
#Daveo:
I don't want to build in an overriding custom attribute just to send an array from JSON, that is rediculous as we've already covered in this question-it is not necessary.
MVC3 - irrelevant

Here is my demo,use mvc2,hope some helps~
The key to success is traditional
set the traditional parameter to true
$(function(){
var a = [1, 2];
$.ajax({
type: "POST",
url: "<%= ResolveUrl("~/Home/PostArray/") %>",
data: {orderedIds: a},
dataType: "json",
traditional: true,
success: function(msg){alert(msg)}
});
})
Since jquery 1.4 this parameter exists because the mechanism to serialize objects into query parameters has changed.
and action is~
[HttpPost]
public ActionResult PostArray(int[] orderedIds)
{
return Content(orderedIds.Length.ToString());
}

you can also use JSON.stringyfy to sent the data as a string then use JavaScriptSerializer class to retrive the data.
In C# code, to get the data, will look like this:
JavaScriptSerializer js = new JavaScriptSerializer();
js.Deserialize<T>(string paramiter);

use this simple code
var url = '/sampleController/sampleAction'
var params = {sendingVar: [1,2]}
$.post(url, params , function (data) {
$("#lblResult").html(' : ' + data);
}).fail(function (e) {
alert(e);
});

Related

C# - Jquery : Pass regular params and list<KeyPairValue<string, string>> with $.post from view to controller

I try to pass 'regular' parameters type from an ajax call ($.post) from a view to a controller which is supposed to receive those parameters plus a List>.
I need this List cause those parameters will be different from model.types, and the method in the controller dispatch all params in a switch case to private methods.
I tried several jquery objects builds, JSON.stringify, the array with indexes in the string (I know I can't name columns explicitly... part of my question) which always ends in the List> to null in the backend method.
The 'params' are visible in xhr debug, but the parameter _options is always null (ref controller method).
Here is my vars and my ajax call :
function initDocumentsPreviewsActions() {
$('.documents-list-preview-action').on('click', function () {
if (xhrPreviewLoad != undefined)
xhrPreviewLoad.abort();
$('#documents-preview').html('<div class="general-form-message-loader"></div>');
documentCurrentIndex = $(this).data('btnindex');
setDatatableRowActive();
var documentType = $(this).data('documenttype');
var adherentRessourceId = $(this).data('adherentressourceid');
var annee = $(this).data('annee');
var echeancier = $(this).data('echeancier');
var destinataireid = $(this).data('destinataireid');
var destinatairetypeid = $(this).data('destinatairetypeid');
var emetteurid = $(this).data('emetteurid');
var emetteurmandatid = $(this).data('emetteurmandatid');
var trimestres = $(this).data('trimestres');
var params = [
{ '_annee': '' + annee + '', '_echeancier': '' + echeancier + '', '_trimestres': '' + trimestres + '' }
];
xhrPreviewLoad = $.ajax({
url: '/Documents/PreviewDocumentSingle',
data: {
_documentType: documentType,
_adherentRessourceId: adherentRessourceId,
_annee: annee,
_destinataireId: destinataireid,
_destinataireType: destinatairetypeid,
_emetteurId: emetteurid,
_emetteurMandatId: emetteurmandatid,
_echeancier: echeancier,
_options: JSON.stringify(params)
},
dataType: 'json',
type: 'POST'
}).done(function (documentPartialView) {
$('#documents-preview').html('<img src="' + documentPartialView.src + '"/>');
xhrPreviewLoad = undefined;
});
});
}
xhd Parameters in Firefox debugger :
_documentType AppelCotisation
_adherentRessourceId 836
_annee 2018
_destinataireId 11
_destinataireType Syndicat
_emetteurId 16289
_emetteurMandatId 5986
_echeancier False
_options [{"_annee":"2018","_echeancier":"False","_trimestres":"undefined"}]
Controller method :
[HttpPost]
public JsonResult PreviewDocumentSingle(string _documentType, int _adherentRessourceId, int _destinataireId, string _destinataireType, int _emetteurId, int _emetteurMandatId, List<KeyValuePair<string, string>> _options)
{
//(_options = null)
//some code
return JsonResult
}
I already have done this a long time ago but I cannot put a hand or my brain on it. I'm sure it's a little thing.
I expect to get ALL my parameters correctly or being suggested to declare another List of a different type in the backend (and how to formalize it in front), or Array... well... any help is good to come.
But I'd really like to keep mus ctor in the backend as it is.
I finally findout myself how to solve this simple problem by changing to a Dictionnaray instead of a List> in my controller's method parameters and build a simple js object like this :
var options = {};
options['_annee'] = annee;
options['_echeancier'] = echeancier;
options['_trimestres'] = trimestres;

Ajax call to action with a List of KeyValuePairs as parameter

I wish to simply do an AJAX call to a method expecting a List of Key and value pairs, but I have no idea how to do this. I tried the following:
Server method:
UpdateBranches(List<KeyValuePair<string, string>> brancheItems)
data to be send:
var brancheItems = [];
businessActivities.forEach(f =>
brancheItems.push({
Key: f.sbiCode,
Value: f.sbiCodeDescription
})
This seemed to give me an array of objects with key and value properties. (network tab showed it), but it did not work. I also tried to make an array of objects with one property (propertyname is the key, value is the value):
for (var itemIndex in items[index].businessActivities) {
var key = items[index].businessActivities[itemIndex].sbiCode;
brancheItems.push({
key: items[index].businessActivities[itemIndex].sbiCodeDescription
});
}
Note that on the server I seem to receive an array/list of 3 items with two properties, but the properties are always empty. Does anyone know the correct format for the data to be send
I think you can simply create your object like this:
var ParamtersContainer = new Object();
ParamtersContainer = {
"PatientName": 'Alameer',
"ServiceDate": '12/12/2017',
"ProviderName": 'ahmed'
};
Then make it as data parameter in your ajax request, receive it as a dictionary in your c# action.
Use something like this.
$.ajax({
type: 'POST',
url: url,
contentType: "application/json",
data:JSON.stringify( {brancheItems: brancheItems}),
success: function (data) {
alert("Succeded");
}
});
And use the bracket notation:
Instead of brancheItems.push({ key : value });
use
var object = {};
object[key] = value;
brancheItems.push(object);

Ajax call is passing controller name and method name instead of data

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

Pass JSON file to Javascript ASP.NET MVC4

My problem is currently : How to pass a JSON Object (As it is or as a C# object deserialized with Newtonsoft.Json) to a javascript file.
I tried the following method :
Response.Write(string.Concat("<input id='data' type='hidden' value='", json_file, "' />"));
but when the json file is rendered in HTML (as a html attribute) it stops on the quote character, i tried to escape it but it's not working either.
So when in my javascript file i use JSON.parse() the syntax is not valid.
Problem Solved :
- Declared a javascript variable Data in my .cshtml file, put the jsonfile as a #ViewBag element inside.
- got it in my javascript by window.Data
- parsing it as json, using it, magic done.
(Thanks for those who answered)
If this is a json object, why not insert the object in a javascript variable on the page, as presumably you want to use the variable e.g. in Ajax?
function someThingClicked(){
var myObject = <%= json_file %>;
$.ajax({
type: "POST",
url: "SomeUrl",
data: myObject,
success: function () { },
contentType: "application/json; charset=utf-8",
dataType: "json"});
}
This should serve something like the below to the browser:
var myObject = {
someField : 'someValue'
};
...
If you are using razor, you would write it out something like:
var myObject = #Html.Raw(ViewBag.json_file);
Assuming that you've added the json_file string into ViewBag from your controller.
in this case you can try use JsonResult
Try this please
Response.Write(string.Concat("<input id='data' type='hidden' value=\"", json_file.Replace('\"', '\''), "\" />"))
it's a result of you concatenation results in termination of the valuesttribute value before you intended. E.g. you have a 'character in the json_file
as an example if the file contains
var x = 'this is a string'
then the result of your concatenation would yield invalid html
<input id='data' type='hidden' value='var x = 'this is a string'' />
notice that the value attribute is terminated after var x = and that the final "attribute" string is missing an = prior to the value (the empty string '')
to avoid that you should assign the json to a variable and then assign that value as the value to the input element
Response.Write(string.Concat("<input id='data' type='hidden'/>",
"<script>$(function(){var x = ", json_file,
";$("#data").val(JSON.stringify(x));</script>");
(assuming you are already using jQuery otherwise you'd have to do it with plain vanilla JS which is a little more work but can be done
An other solution instead of printing json string inside the html attribute
Create an action that returns your json in your controller
public string GetData()
{
//read your json file
return json_file; //return your json string
}
On View side, put your input tag and fetch json_file through an ajax request
<input id='data' type='hidden' />
<script>
$(function () {
$.post("/yourControllerName/getData", {}, function (response) {
$("#data").val(response);
},'json');
});
</script>

Passing IEnumerable parameter to WebAPI

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 ]

Categories