Reputation: 90
I am working on a project which requires POST method for a multiple-array Json where the data are located on 5 different relating tables with FK.
here is the Json output using GET:
{
"UserId": 1,
"Id": 1,
"ValueStoryName": "Value Story 101",
"Organization": "Charity Foundation",
"Industry": "Education",
"Location": "Singapore",
"AnnualRevenue": 1000,
"CreatedDate": "2017-07-27T00:00:00",
"ModifiedDate": "2017-01-01T00:00:00",
"BusinessValueToYou": [
{
"Id": 1,
"BVUSId": 1,
"BalanceSheet": 348,
"IncomeStatement": 546,
"ValueDriver": [
{
"BVUSId": 1,
"BVUId": 1,
"ValueDriver": "Give kind to others",
"Selected": true,
"TotalSavings": 0,
"SubLever": [
{
"BVUId": 1,
"BVUSVDId": 1,
"Item": "Help when needed",
"Selected": true,
"EstAnnualValue": 1,
"UserInput": [
{
"BVUSVDId": 1,
"BVUUIId": 1,
"Item": "Total Benefit",
"UserInput": 10
}
]
}
]
}
]
}
]
}
and what I currently have for my POST method under the controller is:
// POST: api/ValueStories
[ResponseType(typeof(ValueStory))]
public async Task<IHttpActionResult> PostValueStory(ValueStory valueStory)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.ValueStories.Add(valueStory);
db.BusinessValueToYou.AddRange(valueStory.BusinessValueToYou);
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = valueStory.Id }, valueStory);
}
the code above only adds data for valuestory and businessvaluetoyou but is unable to add values for the valuedriver, subvaluedriver and userinput. I've been cracking by brain on how to make this work but to no luck. Any help and references will be very much appreciated.
This is my BusinessValueToYou model:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace AribaWebService.Models
{
public class BusinessValueToYou
{
// Foreign Key
public int Id { get; set; }
[Key]
public int BVUSId { get; set; }
public decimal BalanceSheet { get; set; }
public decimal IncomeStatement { get; set; }
// Navigation property
public virtual ValueStory ValueStory { get; set; }
public List<BVUValueDriver> ValueDriver { get; set; }
}
public class BVUValueDriver
{
// Foreign Key
public int BVUSId { get; set; }
[Key]
public int BVUId { get; set; }
[Required]
public string ValueDriver { get; set; }
public bool Selected { get; set; }
public decimal TotalSavings { get; set;}
// Navigation property
public virtual BusinessValueToYou BusinessValueToYou { get; set; }
public List<BVUSubValueDriver> SubLever { get; set; }
}
public class BVUSubValueDriver
{
// Foreign Key
public int BVUId { get; set; }
[Key]
public int BVUSVDId { get; set; }
[Required]
public string Item { get; set; }
public bool Selected { get; set; }
public decimal EstAnnualValue { get; set; }
// Navigation property
public virtual BVUValueDriver BVUValueDriver { get; set; }
public List<BVUUserInput> UserInput { get; set; }
}
public class BVUUserInput
{
// Foreign Key
public int BVUSVDId { get; set; }
[Key]
public int BVUUIId { get; set; }
[Required]
public string Item { get; set; }
public double UserInput { get; set; }
// Navigation property
public virtual BVUSubValueDriver BVUSubValueDriver { get; set; }
}
}
here is my ValueStory model:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace AribaWebService.Models
{
public class ValueStoryDetailDTO
{
// Foreign Key
public int UserId { get; set; }
[Key]
public int Id { get; set; }
public string ValueStoryName { get; set; }
public string Organization { get; set; }
public string Industry { get; set; }
public string Location { get; set; }
public string Currency { get; set; }
public double AnnualRevenue { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
// Navigation property
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public virtual User User { get; set; }
public List<AreaOfInterest> AreaOfInterest { get; set; }
public List<BusinessValueToYou> BusinessValueToYou { get; set; }
public List<BusinessValueFromSap> BusinessValueFromSap { get; set; }
}
}
Upvotes: 4
Views: 2164
Reputation: 90
I managed to get it working using AddRange. Thanks for the help.
Upvotes: 0
Reputation: 2177
Usually we don't expose the real Db entities directly in web api, just return what we need using view model or DTO to prevent overexpose.
You can change your get method to return what you need in a single model.
Learn more about auto mapper http://automapper.org/
Build better RESTful api: https://www.codeproject.com/Articles/990492/RESTful-Day-sharp-Enterprise-Level-Application
For your question this is a example how to read multiple array:
// POST: api/ValueStories
public async Task<IHttpActionResult> PostValueStory(AbcViewModel viewModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//Manual map or use Automapper here
var entity = Mapper.Map<ValueStory>(viewModel);
db.ValueStories.Add(entity);
//db.BusinessValueToYou.AddRange(entity.BusinessValueToYou); // can map with automapper
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = entity .Id }, entity );
}
public class AbcViewModel
{
public int UserId { get; set; }
public int Id { get; set; }
public string ValueStoryName { get; set; }
public string Organization { get; set; }
public string Industry { get; set; }
public string Location { get; set; }
public string AnnualRevenue { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public IEnumerable<BusinessValueToYouViewModel> BusinessValueToYou { get; set; }
}
public class BusinessValueToYouViewModel
{
public int Id { get; set; }
public int BVUSId { get; set; }
public int BalanceSheet { get; set; }
public int IncomeStatement { get; set; }
public IEnumerable<ValueDriverViewModel> ValueDriver { get; set; }
}
public class ValueDriverViewModel
{
public int Id { get; set; }
public int BVUSId { get; set; }
public int BVUId { get; set; }
public string ValueDriver { get; set; }
public bool Selected { get; set; }
public int TotalSavings { get; set; }
}
Upvotes: 2