Controller Action parameter not properly populated from AJAX POST - javascript

I'm performing an AJAX call and I want the Controller Action (using HttpPost) to accept a parameter of IEnumerable<PercentageViewModel> percentages
where PercentageViewModel is:
public class PercentageViewModel
{
public int Id { get; set; }
public string Percentage { get; set; }
}
The populated data structure on the Action has 2 items in the collection but each item is filled with default values (0 and null). Here is the data as it appears in Chrome Network Headers - when I click on the AJAX Post XHR call
percentages[0][Id]:7
percentages[0][Percentage]:26.1
percentages[1][Id]:8
percentages[1][Percentage]:20.3
Here is the JS where I am populating the params variable that will be sent using the AJAX Post call.
var params = {};
var dict = [];
for (var idx in data) {
var item = {
Id: idx,
Percentage: data[idx]
};
dict.push(item);
}
params['percentages'] = dict;
where the data variable has data like this (when written to Chrome console):
Object {7: "26.1", 8: "20.3"}
How can I construct the data in JS so the data structure in the Action is populated properly?
Full disclosure: this is a rephrasing of a question I asked yesterday - just as a more targeted question.

This was the answer that allow the server side data structure to be populated properly
var i = 0;
for (var idx in data) {
params['percentages[' + i + '].Id'] = data[idx].Id;
params['percentages[' + i + '].Percentage'] = data[idx].Percentage;
i++;
}

Related

URL parameters on javascript

I´m making a call using javascript and I would like to send an array:
var selected = [];
selected=getAllEnginesIdsSelected();
console.log("selected: "+selected);
$.getJSON('/call/' + selected,
function(myList) {
The funcion that I use in Javascript to retrieve array is:
function getAllEnginesIdsSelected() {
var selected = [];
$("input:checkbox[id^='engine_']:checked").each(function(){
var ele=$(this)[0].id;
selected.push(ele);
});
return selected;
}
Console.log retrieves selected: 2,5
In MVC Controller I have
#RequestMapping(method = RequestMethod.GET, value = "/call/{selected}")
public List<List<myList>> myCall(#RequestParam(value="selected[]") String[] selected){
I gives an error. I don´t want to use AJAX. This is posible to send?
selected is an array, which you are joining to a string in the URL. Try something like $.getJSON('/call/?selected=[' + selected.join(',')]

pass collection of objects through http post in angular js

I have pass a collection of objects through http post in angular js.
The code is as follows:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data.ContentId, { Selected: true }); // I could able to get all the selected objects here, No problem with it
var jsonData = angular.toJson(contents); //It is not able to convert to Json if there are more than 5 records
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent?jsonData=' + jsonData, {});
promise.success(function () {
window.location.reload();
});
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(string jsonData)
{
var contents = JsonConvert.DeserializeObject<List<ContentNodeInWorkFlow>>(jsonData);
foreach (var content in contents)
{
_contentService.PublishContent(content.ContentId, userId);
}
}
}
The above code works fine if there are 5 records or less. If there are more records, I could able to get all the selected record
objects in the variable 'contents'. But the problem is occuring when converting to Json for all those objects. I
have about 500 records to pass through. How can do I it?
There is no specific reason to convert to JSON data. I just need to extract the ids of all the selected items. I have modified the above code as below:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var abc = [];
angular.forEach(contents, function(content)
{
abc.push(content.ContentId); // got all the ids in the array now
});
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,{contents : abc});
promise.success(function () {
window.location.reload();
});
}
I have just took an array and pushed all the content ids into it. I could able to see all the ids in the array now. I tried to pass the array as above.
How to retrieve those array in the code behind.
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(int[] abc)
{}
I do not see any values obtained under int[] abc. What will be the datatype for the parameter in the method call above.
You need second argument of $http.post method. You have to send such data by POST requests, not in query of url. You can put some data into body of the post request.
You need this:
var postBodyWithHugeAmountOFData = {data: [1,2,3,4,5...500]};
$http.post(url, postBodyWithHugeAmountOFData).success(function () {});
Also, you must be ready to handle this request in your backend.
is there any specific reason u want to pass this data as a JSON?.
if u r using Web API in that case u can pass the object as it is but only make sure that collection in web API method contains all the property in javascript collection
Thank you for all your posts. It's working fine without converting to Json. The code is as below.
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,contents);
promise.success(function () {
window.location.reload();
});
}
and the signature would be
public void CmsPublishApprovedContent(List<ContentNodeInWorkFlow> abc)
{
}

Javascript send an input as array to a C# WebAPI

-------------------------EDIT--------------------------------
It's not a duplicate because I can't use an ajax Request, as asked on this question.
I'm creating a form in javascript to call a c# WebApi that will return a xls file (that's why I'm creating a form and not an ajax call).
The webApi must receive an array of integer, that will correspond to a list of ids of objects.
The webApi is the following
[Route("getExcel")]
[HttpPost]
public HttpResponseMessage getExcel([FromBody]int[] ids)
{
...
}
the form I'm building is like this:
var form = document.createElement("form");
form.setAttribute('method', "post");
setAttribute('action', baseUrl + "api/processos/getExcel");
form.setAttribute('target', "_blank");
var rows = $("#tbl").dataTable().fnGetNodes();
var arr = [];
for (var i = 0; i < rows.length; i++)
{
ids = $("#tbl").dataTable().fnGetData(i).processosId;
var input = document.createElement("input");
input.setAttribute('type', "text");
input.setAttribute('name', "ids[]");
input.setAttribute('value', ids);
form.appendChild(input);
}
document.body.appendChild(form);
form.submit();
The ids on the WebApi is empty (but not null)... When watching on Fiddler, the Raw View shows this ids=15&ids=14&ids=13&ids=12&ids=11 which is exactly what I need...
Why isn't associating with the WebApi ids ? If I send that exact values in the URL (and changing the [FromBody] to [FromUri] it works...
-------------------EDIT------------------------------
this is what is in the array ids on the WebApi when the method is called:
ids {int[0]} (as seen while debugging)
So, the solution is to create a model on the backend such this:
public class ExcelIds
{
public int[] ids { get; set; }
}
and change the controller to:
[Route("getExcel")]
[HttpPost]
public HttpResponseMessage getExcel([FromBody]ExcelIds model)
{
//code here
}
You could use FormDataCollection.GetValues(string Key) to get an array of strings, that you could later convert to int[].
[Route("getExcel")]
[HttpPost]
public HttpResponseMessage getExcel(FormDataCollection data)
{
string[] ids = data.GetValues("ids");
...
}

How to get Data from Model to JavaScript MVC 4?

that's my function:
<script> function Calculate()
{
var ItemPrice = document.getElementById("price");
var weight = document.getElementById("weight");
var SelWeight = weight.options[weight.selectedIndex].value;
alert(SelWeight);
var Category = document.getElementById("SelectedCategory");
var SelCategory = Category.options[Category.selectedIndex].value;
alert(SelCategory);
}
</script>
i want to get SelCategories.Tax and SelCategories.Duty to add them to weight value and total price to show the total in a label.. I'm using ASP.NET MVC 4 and this is my Model that i want to use
public class CategoriesModel
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public decimal Duty { get; set; }
public decimal Tax { get; set; }
public IEnumerable<SelectListItem> CategoriesList { get; set; }
}
I think the best approach here is to use Json and something like Vue.js, Knockout.js, etc. (but also you can do it without these libraries, if your case is simple).
First, you need to install Json support with a command in PM console:
PM> install-package NewtonSoft.Json
Then, in your view you can convert your model to javascript object like this:
#model ...
#using Newtonsoft.Json
...
<script type="text/javascript">
var data = #Html.Raw(JsonConvert.SerializeObject(this.Model));
</script>
Then you can access all the properties in your model with in plain JavaScript:
var id = data.CategoryID;
That's it! Use knockout (update 2018: this is obsolete, there is no reason you should use knockout now) if your logic is complicated and you want to make your view more powerful. It could be a little bit confusing for newbie, but when you get it, you'll gain the super-powerful knowledge and will be able to simplify your view code significantly.
You need to create actions (methods in the controller) that return JsonResult.
From the client side, make ajax calls to the server to recover and use that data. The easiest way to do this is to use any of the jQuery ajax methods.
public JsonResult GetData(int id)
{
// This returned data is a sample. You should get it using some logic
// This can be an object or an anonymous object like this:
var returnedData = new
{
id,
age = 23,
name = "John Smith"
};
return Json(returnedData, JsonRequestBehavior.AllowGet);
}
When you use a jQuery get to the /ControllerName/GetData/id, you'll get a JavaScript object in the success callback that can be used in the browser. This JavaScript object will have exactly the same properties that you defined in the server side.
For example:
function getAjaxData(id) {
var data = { id: id };
$.get('/Extras/GetData/1', // url
data, // parameters for action
function (response) { // success callback
// response has the same properties as the server returnedObject
alert(JSON.stringify(response));
},
'json' // dataType
);
}
Of course, in the success callback, instead of making an alert, just use the response object, for example
if (response.age < 18) { ... };
Note that the age property defined in the server can be used in the JavaScript response.
If you prefer a class try jsmodel. After converting the mvc view model to javascript it adds the benefit of retrieving DOM updates.
var jsmodel = new JSModel(#Html.Raw(Json.Encode(Model)));
Then anytime you want to get the latest state of the DOM do this to update your variable:
var model = jsmodel.refresh();
Website:
http://chadkuehn.com/jquery-viewmodel-object-with-current-values/
There is also a nuget:
https://www.nuget.org/packages/jsmodel/
var errors = '#Html.Raw(Json.Encode(ViewData.ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage)))';
var errorMessage=JSON.parse(errors);

Loop thru form to fill json object for post

I have a shopping cart and want to post it to my login window so I can proceed to checkout after authentication. But before this can be achieved, I am using a webservice call on shoppingcart window load, so I can get a hash of my cart items and secure the communication between us. How can I serialize all my cart items in the data object so I can send it to my webserver?
This is what I am trying so far, but it isn't working...
$(document).ready(function () {
getCartHashCode();
});
function getCartHashCode() {
var url = 'home/GetHashRequest';
var data = new Array();
//put all items from the cart on the data object
for (i = 1; i <= $('.product-name').length; i++) {
//setting up json parameter names
var CART_NAME = 'CART_'+i+'_NAME';
var CART_PRICE = 'CART_'+i+'_PRICE';
var obj = { CART_NAME: $('input[name=Cart['+i+'].Name').val(),
CART_PRICE: $('input[name=Cart['+i+'].Price').val() }
data.push(obj);
}
$.ajax({
type: 'POST',
url: url,
data: data,
success: function (hash) {
alert("It worked! Hash = " + hash.toString());
}
});
EDIT
Follow up after ferrants' comment: I took it off, and really did go to the server! Thanks
The problem is how do I get the items I posted on the server side?
I have a item domain class defined as this:
public class Item
{
public string Name { get; set; }
public int UnitPrice { get; set; }
}
and my controller action is this:
public string GetHashRequest(List<Item> cart)
{
GetSecureHashPOCORequest hashRequest = new GetSecureHashPOCORequest();
}

Categories

Resources