Passing complex object to WebAPI from AngularJS - javascript

I am trying to post a JavaScript item to a C# WebAPI call using AngularJS. Below is what I am trying to do.
Objects
class Address
{
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Address address { get; set; }
}
My C# Controller function
[Route("Update/")]
public void Update(Person person)
{
_service.Update(person);
}
AngularJS call
this.update = function (person) {
$http.post("api/Person/Update/", person);
}
When I receive the object in the WebAPI controller the address is null. Why is this data not being received?
Edit
I was wrong in my original question the Person object looked like this
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public IAddress address { get; set; }
}
When I changed address from IAddress to Address everything worked as expected.

Your post would be in json format which will assign person object to person, Address object must be well formed object as it contain sub properties.
Code
$scope.person = {
'Street': '',
'LastName': '',
'Address': {
'Street': '',
'City': '',
'State': '',
},
}
this.update = function (person) {
$http.post("api/Person/Update/", { person : $scope.person});
}

This approach allows to send complex objects with arrays and sub objects through HTTP GET:
Angular:
$http({
url: '/myApiUrl',
method: 'GET',
params: { personStr: angular.toJson(person, false) }
})
C#:
[HttpGet]
public string Get(string personStr)
{
Person obj = new JavaScriptSerializer().Deserialize<Person>(personStr);
...
}

What you want to do is not possible, but this solution allows you to use your complex object on the .NET side. There is no body in a GET request, so you have to add your object into the URI.
Change your web api method to:
[Route("Update/")]
public void Update([FromUri]Person person)
{
_service.Update(person);
}
Change your angular code to:
this.update = function (person) {
$http.post("api/Person/Update?FirstName=John&LastName=Doe&Address%5BStreet%5D=123%20Main%20St&Address%5BCity%5D=Knoxville&Address%5BState%5D=Tennessee");
}

Related

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. :)

Passing JavaScript object to C#

I am trying to create a new row in a table I have hosted in Azure SQL Database. My front end is AngularJS with C# in .NET as the back end.
Here is my code from the front end passing the object:
var insertTicket = function (newTicket) {
return $http.post("http://localhost:50412/api/tickets", JSON.stringify(newTicket))
.then(function (response) {
console.log(response);
console.log("Insert Successful");
return;
});
And here is my backend code that receives the data and tries to add to the database:
[Route("api/tickets")]
public HttpResponseMessage Post(Ticket t)
{
TicketsRepository.InsertTicket(t);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
In TicketRepisitory:
public static void InsertTicket(Ticket tick)
{
var maxID = (from ticket in dataContext.Tickets
select ticket.id).Max();
var tick = new Ticket();
tick.id = maxID + 1;
dataContext.Tickets.Add(tick);
dataContext.SaveChanges();
}
And Here is my Ticket class:
public partial class Ticket
{
//Properties
public int id { get; set; }
public string title { get; set; }
public string customer { get; set; }
public string barcode { get; set; }
public string assignedTo { get; set; }
public string category { get; set; }
public string importance { get; set; }
public Nullable<System.DateTime> openDate { get; set; }
public Nullable<System.DateTime> dueDate { get; set; }
public Nullable<System.DateTime> closedDate { get; set; }
public string comments { get; set; }
public string condition { get; set; }
public Nullable<int> workHours { get; set; }
//Relationships
public Employee Employee { get; set; }
public Employee Employee1 { get; set; }
public Equipment Equipment { get; set; }
}
I think the issue is with Post() expecting a ticket object. I have tried searching for how to receive JSON data and use that for Ticket, but with out much luck.
My Problem is that I can not create a new row. No changes are reflected in my database.
You don't need to JSON.stringify your object when POSTing data with $httpin AngularJS, just pass the object itself as the second parameter, like this:
var insertTicket = function (newTicket) {
return $http.post("http://localhost:50412/api/tickets", newTicket)
.then(function (response) {
console.log(response);
console.log("Insert Successful");
return;
});
First there is no need to call JSON.stringify() method on newticket javascript object for second paramter of $http.post() method.
Then in the web api method write a parameter of type JObject with the name newTicket to receive the posted object, and use generic version of ToObject method to convert posted data to desired type. Don't forget to use [FromBody] attribute for the method parameter. the code for webapi looks like this:
[Route("api/tickets")]
public HttpResponseMessage Post([FromBody]JObject newTicket)
{
var t = newTicket.ToObject<Ticket>();
TicketsRepository.InsertTicket(t);
HttpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
return response;
}

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"}]}

ASP.NET Web API - pass a complex type from javascript json

I have an ASP.NET Web API that accepts a POST with a UserModel in it:
[HttpPost]
public object Post(UserModel userModel)
{
// some logic here
}
The UserModel is a complex type that looks like this:
public class UserModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public AddressModel CurrentAddress { get; set; }
}
The AddressModel Model looks like this:
public class AddressModel
{
public string Country { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string Number { get; set; }
}
I'm trying to call this API from javascript and send a JSON object. This is the JSON object I'm sending:
var user = {
Id: 1,
FirstName: 'Hello',
LastName: 'World',
CurrentAddress: {
Country: 'Israel',
City: 'Tel Aviv',
Street: 'Shalom',
Number: '5'
}
};
What I get in my Post method is a UserModel with the UserModel fields filled with the correct information, the CurrentAddrent address is initialized, but the values sent are not there. The values of the parent object (the UserModel object are ok).
What am I doing wrong here? how can you send a complex object to WebAPI Model?
to receive complex data objects in MVC web API actions you have to add [FromBody] attribute to your POST arguments.
The [FromBody] tells the Web API to search for the parameter’s value in the body of a POST request.
[HttpPost]
public void Post([FromBody] UserModel userModel)
{
}
I've made a local test and I obtained the values.
I hope it helps!

Getting data from an object inside an object

Hi I am just learning knockout and I am facing a problem that I can not seem to understand.
I have this object:
var studentPersonalDetails = ko.observable();
var isInitialized = false;
var vm = {
//bindable
title: ko.observable('Profile'),
dataLoading: ko.observable(false),
hasErrors: ko.observable(false),
errorMessage: ko.observable(''),
//data
profileStudentPersonalDetails: studentPersonalDetails,
//operations
activate: activate
};
return vm;
profileStudentPersonalDetails is the equivalent of this C# object from the server:
public int? StudentNumber { get; set; }
public string Supervisor { get; set; }
public bool CanEdit { get; set; }
public string PersonId { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
And is populated from a service.My problem is that I do know how to access the data from this object so I can display it on a html view.
I have tryed this versions:
<strong data-bind="text: StudentNumber">
<strong data-bind="text: profileStudentPersonalDetails.StudentNumber">
But non seem to work.The data gets populated into the object the right way of that I am sure and I am able to acces the other fields from the data for example the title:
<strong data-bind="text: title">
And this works.
How can I access the data?
I think you want
profileStudentPersonalDetails().StudentNumber
observables are functions. To get the objects they represent, you need to call the function. You can then access the property off the result of the function.

Categories

Resources