How to create nested list of objects in javascript - javascript

I am trying to create Product instance in Javascript and than to pass it to the server using [webmethod].
[WebMethod]
public static void SetProduct(Product product)
{
// i want a product instance
}
Following is Product class that i'm trying to create:
public class Product
{
public Type Type { get; set; }
public Foo Foo { get; set; }
public List<Bar> Bars { get; set; }
}
public class Type
{
public string ID { get; set; }
}
public class Foo
{
public string ID { get; set; }
public string Color { get; set; }
}
public class Bar
{
public string Name { get; set; }
}
I am being able to create Type and Foo but not List<Bar> in Javascript: (see my comments in the code for more details)
Javascript
function setProduct() {
var product = {};
product.Type = {};
product.Foo = {};
product.Type.ID = 'typeID';
product.Foo.ID = 'fooID';
product.Foo.Color = 'fooColor';
//here is my question how can create List<Bar> Bars and add it to product item???
$.ajax({
type: "POST",
url: "Default.aspx/SetProduct",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
data: "{product:" + JSON.stringify(product) + "}",
});
}

JavaScript doesn't know what a List<T> is. It only knows how to make arrays. So you'll have to construct an array of Bars and pass that in the JSON.
Fortunately, it's an easy fix:
product.Bars = [
{ Name: "bar 1" },
{ Name: "bar 2" },
{ Name: "bar 3" },
];
The above is probably all you need. I'm pretty sure ASP.NET will be smart enough to convert that Bar[] into a List<Bar> automagically, but just in case it isn't:
public class Product
{
public Type Type { get; set; }
public Foo Foo { get; set; }
public IEnumerable<Bar> Bars { get; set; }
}
Then if you still want List<T> functionality, just convert the array to a List in your WebMethod:
[WebMethod]
public static void SetProduct(Product product)
{
var list = product.Bars.ToList();
product.Bars = list;
return product;
}
Now you can still access those nice List<T> methods:
((List<Bar>)product).Add(new Bar() { Name = "bar 4" });

// create an array
product.Bars = [];
// add an element to the array
product.Bars.push({
Name: "Foo"
});
alternatively you can initialize the array with elements as well:
// create and initialize array
product.Bars = [{Name:"Foo"}, {Name:"Bar"}];

Use an array, and add the items to the array with array.push. Eg :
product.Bars = [];
product.Bars.push({ Name: "foo" });

Related

Some elements from JSON object passed to MVC controller are NULL

I am trying to pass a JSON object to my MVC controller action via POST. The controller action is called but some elements of the object are NULL. The 'ArticleKey' is there but the 'MeasureDefinitions' are NULL (see below).
Here is the object which I am trying to parse (it gets appended with more values by the user):
var articleValues = [
{
'ArticleKey': {
'ArticleNo': 'ArticleNo',
'CustomerName': 'CustomerName',
},
'MeasureDefinitions ': [
{
'DisplayIndex': 0,
'MeasureType': 'MeasureType',
'Percentage': 99.99,
'OriginalPercentage': 0
}
]
}
];
My model looks like this:
public class ArticleValuesModel
{
[Key]
public ArticleKey ArticleKey { get; set; }
public List<MeasureDefinition> MeasureDefinitions { get; set; }
public string ArticleDescription { get; set; }
public bool AddToList { get; set; }
}
public class ArticleKey
{
public string ArticleNo { get; set; }
public string CustomerName { get; set; }
}
public class MeasureDefinition
{
public long DisplayIndex { get; set; }
[Key]
public string MeasureType { get; set; }
public double Percentage { get; set; }
public double OriginalPercentage { get; set; }
}
Here is my controller action:
[HttpPost]
public ActionResult UpdateArticleValuesJson(List<Gui.Models.ArticleValuesModel> modelList)
{
return RedirectToAction("Index");
}
Here is my Ajax POST:
$('#btnSaveArticleValues').click(function() {
$.ajax({
url: "/ArticleList/UpdateArticleValuesJson",
contentType: "application/json;charset=utf-8",
dataType: "JSON",
type: "POST",
data: JSON.stringify(articleValues),
success: function() {
console.log("Saved");
},
error: function(e) {
console.log(e);
}
});
});
Can you please help me to make the 'MeasureDefinitions' list accessible in my controller?
Removing the extra spaces in my JSON object like indicated by the_lotus did help to resolve the problem.

Pass an Object from Angularjs to MVC controller and map to Class Object

I have an object in angularjs which I want to pass and map it to custom c# class in mvc controller. but whenever I am doing this class object is null completely.
$scope.Get = function () {
var EService = [{
id: $scope.Id,
servicename: $scope.ServiceName,
servicetype: $scope.ServiceType,
monthlyrental: $scope.MonthlyRental,
serviceremarks: $scope.ServiceRemarks,
servicestatus: $scope.status,
activationdate: $scope.ActivationDate,
deactivationdate: $scope.DeActivationDate
}];
$http.post('/TS/API/Insert', Service).then(function (res) {
debugger;
})
MVC Controller and Class:
[HttpPost]
public string Insert(ServicesMaster Service)
{
GIBCADBEntities gfientity = new GIBCADBEntities();
var record = "Sent"
return Json(record, JsonRequestBehavior.AllowGet);
} public class ServicesMaster
{
public string id { set; get; }
public string servicename { set; get; }
public string servicetype { set; get; }
public int? monthlyrental { set; get; }
public string serviceremarks { set; get; }
public byte servicestatus { set; get; }
public DateTime? activationdate { set; get; }
public DateTime? deactivationdate { set; get; }
}
The javascript variable/object "EService" is ok here, and when passing only the ServicesMaster object is created with null values and no data is mapped to it. I can send single string or any value from here but when sending a complete object its behaving like this.
You are passing an array from front end and fetching object from server end. just remove the "[" and "]" brace while set value to EService . Like :
$scope.Get = function () {
var Service = {};
Service = {
id: $scope.Id,
servicename: $scope.ServiceName,
servicetype: $scope.ServiceType,
monthlyrental: $scope.MonthlyRental,
serviceremarks: $scope.ServiceRemarks,
servicestatus: $scope.status,
activationdate: $scope.ActivationDate,
deactivationdate: $scope.DeActivationDate
};
$http.post('/TS/API/Insert', Service).then(function (res) {
debugger;
});
};
It should work now. :)

How to pass in nested data from the client to the controller

I have a form that has two sections. 3 input fields and another section with 10 checkboxes.
public class Customerproductdto
{
public string CustomerNumber { get; set; }
public string CustomerName { get; set; }
public string CustomerPhone { get; set; }
List<ProductDetails> GetAllChecked {get;set;}
}
public class ProductDetails
{
public string ProductName{ get; set; }
}
Here is jquery code I am using to get all the values of the checkboxes that were
checked on my form. They are about 10 and users could check everything.
var yourArray[]
$("input:checkbox[name=type]:checked").each(function(){
yourArray.push($(this).val());
});
Here is javascript that I use to collect the data and pass to my controller.
How can I pass in my array here all in one shot?
var objdata =
({
CustomerNumber: txtcustnumber,
CustomerName: txtcustname,
CustomerPhone: txtphone
//How do I pass the yourArray here?
});
var url = "#Url.Action("WriteToDb", "Home")";
var completeData = JSON.stringify({ 'Information': objdata });
$.get(url, { 'objdata': completeData }, function (data) {
$('#mainListContent').html(data);
});
Please note that I will like to deserialize this once I get to the controller.
Here is the method.
public ActionResult WriteToDb(string objdata)
{
Customerproductdto getAllTaskSaved = null;
try
{
var stripOffObjectName = JObject.Parse(objdata)["Information"];
var cleanedData = JsonConvert.DeserializeObject<Customerproductdto>(stripOffObjectName.ToString());
getAllTaskSaved = _dtcDataService.WriteTaskToDb(cleanedData, "Add");
}
catch (Exception ex)
{
logger.Error(ex);
}
return PartialView("_Taskdisplay", getAllTaskSaved);
}

How to pass a composite array from Javascript to WEB API controller HttpPOST?

My JavascriptCode
//insert the employee and department record
this.insertEmployeeDepartment = function (Employee) {
var request = $http({
method: "post",
url: "/Employee/InsertEmployeeDepartment",
contentType: "application/json",
data: JSON.stringify(Employee)
});
return request;
}
EmployeesAPIController.cs
using System.Web.Http;
namespace EmployeeService
{
[RoutePrefix("Employee")]
public class EmployeesAPIController : ApiController
{
[HttpPost]
[Route("InsertEmployeeDepartment")]
public EmployeeDepartment InsertEmployeeAndDepartment([FromBody]EmployeeDepartment emp)
{
var xx = emp;
}
}
}
EmployeeDepartment.cs
using System.Collections.Generic;
namespace Test
{
public class EmployeeDepartment
{
public IEnumerable<Employee> Employees { get; set; }
public IEnumerable<Department> Departments { get; set; }
}
}
Models -
Employee.cs
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int Age { get; set; }
public int Salary { get; set; }
public int DepartmentId { get; set; }
}
Department.cs
public class Department
{
public int Deptid { get; set; }
public string Deptname { get; set; }
}
The array that I am passing from Javascript is as under
In the controller method, the value is coming as null?
What wrong I am making?
Given your Javascript Object array (and not sure if it is limited to just two entries), we can re-write your javascript post model to mimic your WebApi request model.
Something like (remeber limited to 2 objects in the javascript array).
this.insertEmployeeDepartment = function (Employee) {
//construct a new object to match the WebApi Object
var dto = {
Employees: [Employee[0]], //Employee[0] is the employee record
Departments: [Employee[1]] //Employee[1] is the department record
};
var request = $http({
method: "post",
url: "/Employee/InsertEmployeeDepartment",
contentType: "application/json",
data: JSON.stringify(dto)
});
return request;
}
Now if your JavaScript array is constructed differently per method you will have to format your new model data object differently.
Edit:
To make it match exactly as i see your WebApi DepartmentId property is not on the Employee[0] record we can copy it over manually. Such as.
this.insertEmployeeDepartment = function (Employee) {
//construct a new object to match the WebApi Object
Employee[0]['DepartmentId'] = Employee[1].Deptid;
var dto = {
Employees: [Employee[0]], //Employee[0] is the employee record
Departments: [Employee[1]] //Employee[1] is the department record
};
var request = $http({
method: "post",
url: "/Employee/InsertEmployeeDepartment",
contentType: "application/json",
data: JSON.stringify(dto)
});
return request;
}
Your javascript object is an array that essentially contains a object of each type. You need to use an object that contains an array of objects of each type.
So what you have is something like
[{Age:"23", EmployeeId:"67", EmployeeName:"TestEmpName", Salary:"6666"}, {Deptid:"34", Deptname:"New Dept"}]
What you need is something like
{Employees: [{Age:23, EmployeeId:67, EmployeeName:"TestEmpName", Salary:6666, DepartmentId:0 }],
Departments: [{Deptid:34, Deptname:"New Dept"}]}

What does [ ] mean in javascript and how to return it from C#

I returned class from C# to javascript in this format
Format needed in javascript:
{ key: 1, label: 'Food'}
This part works and the class I used to return from C# looks like this:
public static FoodClass get_AllFood()
{
FoodClass FoodClass = new FoodClass
{
label = "Food",
key = "1",
};
return FoodClass;
}
public class FoodClass
{
public FoodClass() { }
public FoodClass(string data1, string data2)
{
label = data1;
key = data2;
}
public string label { get; set; }
public string key { get; set; }
public Boolean open { get; set; }
public int ID { get; set; }
}
Now when I have to add a child element to my format, It has the [ ] bracket which I dont know how to get from C#
Format needed in javascript:
{ key: 1, label: 'Food', open: false, children: [{ key: 211, label: 'Burger' }]}
That is an array - in this case, with one element. Most json serializers will accept a list or array for that, so:
public List<Child> children {get;set;}
or
public Child[] children {get;set;}
where Child is something like:
public class Child {
public int key {get;set;}
public string label {get;set;}
}
You can rename Child to whatever makes sense without it impacting anything.

Categories

Resources