I'm sending a JSON object when submitting a form that contains some primitive types and one array of objects from a browser (JavaScript) to an ASP.NET MVC backend, but the array of objects is deserialized as an empty array (list, actually).
I've checked what's being sent using Chrome's inspector and the JSON goes out with the correct values, so I believe the issue is in the backend.
Controller action:
[HttpPost]
public ActionResult FooAction(FooViewModel viewModel)
{
//code
}
FooViewModel:
public class FooViewModel
{
public List<BarViewModel> Bars { get; set; } // <-- What arrives empty, not null
public int PrimitiveProperty { get; set; }
public int OtherPrimitiveProperty { get; set; }
public string LastPrimitiveProperty { get; set; }
}
BarViewModel:
public class BarViewModel
{
public long LongProperty{ get; set; }
public string StringProperty { get; set; }
public bool BoolProperty { get; set; }
}
When debugging the controller's action, Bars is empty (not null).
And this is what Chrome's inspector shows me:
LastPrimitiveProperty: SomeText
PrimitiveProperty: 1
OtherPrimitiveProperty: 9
Bars: [{"LongProperty":274,"StringProperty":"SomeString","BoolProperty":true},{"LongProperty":119,"StringProperty":"SomeString","BoolProperty":false},{"LongProperty":163,"StringProperty":"SomeString","BoolProperty":false}]
[HttpPost]
public ActionResult FooAction([FromBody]FooViewModel viewModel)
{
//code
}
Try this and it should collect the json object
Related
I am working in service fabrics micro services , where i need to fetch record for an object. when I send request to API , it shows me empty lists while rest of the data is in place. while debugging I came to know that before returning to API controller my service object has all the data expected i.e lists has data , but when it comes back to web API the lists are empty.
After searching for solution over web I came to know that every time a request is to the API the lists are recreated , so it shows empty result. Any Solutions to come out of this problem?
Here is my piece of code.
The following Is the Web Api Method.
[HttpGet()]
[Route("edit/{readingListId}")]
[ProducesResponseType(typeof(List<GetReadingListDTO>), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(List<GetReadingListDTO>), (int)HttpStatusCode.BadRequest)]
public async Task<IActionResult> GetReadingListById(int readingListId)
{
try
{
var readingList = await this._readingListService.GetReadingListByIdAsync(readingListId);
return Ok(readingList);
}
catch (Exception ex)
{
this._logger.LogError(ex.Message);
return BadRequest();
}
}
The following Is the Service Method.
public async Task<Domain.ReadingList> GetReadingListByIdAsync(int readingListId)
{
try
{
Domain.ReadingList readingList = await _repository.FindById(readingListId);
return readingList;
}
catch (Exception ex)
{
throw;
}
}
Moreover , This Is My Entity.
public class ReadingList : EntityBase, IAggregateRoot, IAggregateCreateRoot, IAggergateUpdateRoot, IAggregateDeleteRoot
{
public ReadingList()
{
this.Items = new List<ReadingListItem>();
this.Assignees = new List<ReadingListAssignee>();
}
public int Id { get; set; }
public EntityType EntityTypeId { get; set; }
public int EntityId { get; set; }
public string Title { get; set; }
public DateTime CompletionDate { get; set; }
public int ReminderDay { get; set; }
public string ReminderDayType { get; set; }
public bool SendReminder { get; set; }
public int CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public int? UpdatedBy { get; set; }
public DateTime? UpdatedDate { get; set; }
public int? DeletedBy { get; set; }
public DateTime? DeletedDate { get; set; }
public bool? Deleted { get; set; }
public List<ReadingListItem> Items { get; private set; }
public List<ReadingListAssignee> Assignees { get; private set; }
}
Thanks!
Edited
The Issue Was Resolved , By Simply Changing The dll Versions.One Of The Service Had And Old Version While The Version Was Updated In The Other One.
Thanks For The Help.
I have two simple models:
Book:
public class Book
{
public int BookID { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Year { get; set; }
public string Publisher { get; set; }
public int GenreId { get; set; }
[ForeignKey("GenreId")]
public Genre Genre { get; set; }
}
and Genre
public class Genre
{
public Genre()
{
Books = new List<Book>();
}
public int GenreID { get; set; }
public string Name { get; set; }
public ICollection<Book> Books { get; set; }
}
With method from ApiController I get all data from table Books.
How can I get in javascript code Name of genre from table Genres using foreign key GenreId ?
I would like to write something like book.Genre.Name, but it does not work in js
You can try below code to serialize the object to return to frontend with json format:
var genre = new Genre();
JavaScriptSerializer js = new JavaScriptSerializer();
string data = js.Serialize(Genre);
Or in other way, you can use Json.NET for do that, this is a powerful json object convert lib.
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;
}
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!
I have json object in javascript as
{"CategoryID":"1","CountryID":"1","CountryName":"United Arab Emirates",
"BillerID":"23","AccountNo":"1234567890",
"Authenticators":"{\"ConsumerNumber\":\"1234567890\",\"LastBillDate\":\"14-10-2014\",\"LastBillDueDate\":\"24-11-2014\"}",
"ShortName":"0000000001"}
I have similar c# class as
[Serializable]
public class UserContext
{
public string CategoryID { get; set; }
public string BillerID { get; set; }
public string AccountNo { get; set; }
public string Authenticators { get; set; }
public string ShortName { get; set; }
public string CountryID { get; set; }
public string CountryName { get; set; }
}
I can get each element value in c# as
UserContext obj1 = Deserialize<UserContext>(context);
But as Authenticators is nested json object i want something like this in C#
[Serializable]
public class Authenticators
{
public string ConsumerNumber { get; set; }
public string LastBillDate { get; set; }
public string LastBillDueDate { get; set; }
}
So that i can get each value of each Authenticators element like
string value = obj.ConsumerNumber;
I want to populate two classes with values. How can i achieve the same ?
Your UserContext class has a string field Authenticators, while the json structure suggests it's an object.
Change
public string Authenticators { get; set; }
to
public Authenticators Authenticators { get; set; }
Then you can deserialize the UserContext object along with the nested object Authenticators
UserContext obj1 = Deserialize<UserContext>(context);
var consumerNumber = obj1.Authenticators.ConsumerNumber;
UPDATE:
You probably need to fix javascript code, bacause now it stores already serialized json string as a string field inside UserContext object.
What you have now, is something similar to:
var data =
{
CategoryID:"1",
Authenticators: JSON.stringify({ConsumerNumber:"1234567890"})
};
var json = JSON.stringify(data);
It should be like:
var data =
{
CategoryID:"1",
Authenticators:{ConsumerNumber:"1234567890"}
};
var json = JSON.stringify(data);
just change
public string Authenticators { get; set; }
to
public Authenticators Authenticators { get; set; }
then you can access the properties of the inner object simply by
var number = obj1.Authenticators.ConsumerNumber;
but i noticed that your JSON had some problems when deserializing using Newtonsoft, i had to change the value of Authenticators in the JSON string to
'Authenticators':{'ConsumerNumber':'1234567890','LastBillDate':'14-10-2014','LastBillDueDate':'24-11-2014'},
just remove the backslash
Once you've deserialized the outer object, you can run another deserialize on the Authenticators JSON string, which is now a property on obj1.
This is required because your Authenticators is a string, it is escaped and thus can't be deserialized until the outer object is deserialized.
Authenticators obj2 = Deserialize<Authenticators>(obj1.Authenticators);
string value = obj2.ConsumerNumber;