I have a Web API targetting .Net Core 2.0.
I'm showing a simplified version of it here for the sake of ease. Essentially, I have two controllers, each one with an action.
api/Properties and api/PropertyItems
and two classes/models:
PropertyItemQuantityDto and PropertyItem
The code:
public class PropertyItemQuantityDto { [Column("item_id")] public int? ItemId { get; set; } [NotMapped] public int? Quantity { get; set; } }
[Table("property_item")] public class PropertyItem { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Column("property_item_id")] public int Id { get; set; } [Column("property_id")] public int PropertyId { get; set; } [ForeignKey("PropertyId")] public virtual Property Property { get; set; } [Column("item_id")] public int ItemId { get; set; } [ForeignKey("ItemId")] public virtual Item Item { get; set; } [Column("notes")] public string Notes { get; set; } }
[Route("api/Properties")] public class PropertiesController : Controller { private readonly MyContext _context; public PropertiesController(MyContext context) { _context = context; } // POST: api/Properties/5/itemQuantities [HttpPost("{propertyId}/itemQuantities")] public async Task<IActionResult> PostItems([FromRoute] int propertyId, [FromBody] PropertyItemQuantityDto[] propertyItemQuantityDtos) { List<PropertyItem> propertyItems = new List<PropertyItems>(); foreach (PropertyItemQuantityDto propertyItemDto in propertyItemQuantityDtos) { for (int i = 1; i <= propertyItemDto.Quantity; i++) { PropertyItem propertyItem = new PropertyItem() { PropertyId = propertyId, ItemId = propertyItemDto.ItemId }; _context.PropertyItem.Add(propertyItem); } } await _context.SaveChangesAsync(); return CreatedAtRoute("GetPropertyItemsByPropertyId", new { propertyId = propertyId }, null); } }
[Route("api/PropertyItems")] public class PropertyItemsController : Controller { private readonly MyContext _context; public PropertyItemsController(MyContext context) { _context = context; } // GET: api/propertyItems/property/5 [HttpGet("property/{propertyId}", Name = "GetPropertyItemsByPropertyId")] public async Task<IActionResult> GetItemsByPropertyId([FromRoute] int propertyId) { var items = _context.PropertyItems.Where(i.PropertyId == propertyId); if (items == null) return NotFound(); else return Ok(items); } }
Basically, one would execute a POST against the api/Properties action to insert items, in batch, into a given property (by property, i mean a house, flat, apartment, etc).
So the body of the POST would look like this, for example:
[ {"ItemId": 1,"Quantity": 1, }, {"ItemId": 2,"Quantity": 7, }, {"ItemId": 5,"Quantity": 32, }, ]
and it will create those items, in the given quantities, in the database (so if quantity = 3, it will execute 3 sql INSERTS).
Once this is done, I would like to return a 201 Created, and in the body, I would like to return all the items just created. I.e. an array of PropertyItem objects, for the given propertyId. In other words, I would like to return what actionGetPropertyItemsByPropertyId returns. So I'm trying to call GetPropertyItemsByPropertyId in my CreatedAtRoute but it's not returning anything it just returns a 201 Created with an empty body. Any ideas? As you can see, I'm leaving
the value blank in the third parameter of CreatedAtRoute, as I'm not acutally sure what to put there...