1

I am new to Entity Framework Core 3.1 and ASP.NET Core 3.1 in general. What I am trying to do is set up my tables Categories, Manufacturers, Conditions, Locations and AssetFiles to have a one-to-many relationship with my Asset table.

These are the data models that I have currently

The Asset table

public class Asset
{
        public int Id { get; set; }
        public Categories Category { get; set; }
        public Manufacturers Manufacturer { get; set; }
        public string Model { get; set; }
        public string SerialNumber { get; set; }
        public string PurchasePlace { get; set; }
        public int Quantity { get; set; }
        public DateTime AcquiredDate { get; set; }
        public string PurchasePrice { get; set; } 
        public string CurrentValue { get; set; }
        public Conditions Condition { get; set; }
        public Locations Location { get; set; }
        public AssetFiles Files { get; set; }
} 

Categories table

public class Categories
{
        public int Id { get; set; }
        public string CategoryName { get; set; }
        public ICollection<Asset> Assets { get; set; }
}

The other tables have pretty much the same format. I can create the migration and update the database so that it is created. It looks to me like it is working the way that I want it to.

My question is how do I access these tables in my Assets controller in the [HttpPost] method to be able to add a category, manufacturer, condition, Location, to the Asset when it is posted cause right now With the controller scaffolded all I'm getting is null for those sections of my asset

Here is my post method of my assetController:

[HttpPost]
public async Task<ActionResult<Asset>> PostAsset([FromForm] Asset asset)
{
        _context.Assets.Add(asset);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetAsset", new { id = asset.Id }, asset);
}

I'm just looking for a little direction on how I need to look at this to move forward.

Any help would be appreciated.

postman submission/result enter image description here

Edit: 2

Also just to mention I am using a VueJs Front End not sure if that matters to the tips you are giving or if accessing the data is the same .

DRW
  • 335
  • 1
  • 3
  • 17

2 Answers2

0

Your string values: Tool, Ikea etc. will not be magically converted into C# objects. If you want to pass object with Form Data you can make POST in postman like this:

POST

This initialize your Category object with Id=0 and Name= "Tool". This solution is proper if you want to create new category with your request and id will be assigned by database engine (most common way).

But I suppose that you want to use existing category when creating Asset. You'd better create another endpoint: POST /api/categories. The endpoint should return you new category with database cateogry id. The Category id could be used in POST /asset request.

Your API controller should not has EF entity as parameter. Instead use ViewModel:

 public class AssetViewModel
 {
    public int CategoryId { get; set; }
    public int ManufacturerId { get; set; }
    public string Model { get; set; }
    public string SerialNumber { get; set; }
    public string PurchasePlace { get; set; }
    public int Quantity { get; set; }
    public DateTime AcquiredDate { get; set; }
    public string PurchasePrice { get; set; } 
    public string CurrentValue { get; set; }
    public int ConditionId { get; set; }
    public int LocationId { get; set; }
    public int AssetFilesId { get; set; }

}

In your controller you should check if category with CategoryId exists in database. If not return NotFound or BadRequest.

You could also want to create e.g. AssetFiles in the same request. Instead of property int AssetFilesId, you could use AssetFileViewModel and POST it as above.

 public class AssetViewModel
 {
    public int CategoryId { get; set; }
    ...
    public AssetFileViewModel AssetFile { get; set; }
}
public class AssetFileViewModel
{
    public string Name { get; set; }
    public string SomeOtherProperty { get; set; }
}

At the end you can create your Asset from ViewModel and save it to database.

Are you sure that you want to use Form Data Body. The most common way is to use JSON (in postman choose Body -> Raw -> JSON)

zolty13
  • 1,943
  • 3
  • 17
  • 34
  • I am using VueJS as the front end for my app, will this way work with that or is there another approach I should be looking at ? – DRW Jun 29 '20 at 20:41
  • What are you asking for? Frontend is independent from backend. – zolty13 Jun 29 '20 at 22:40
  • Just wanted to know if there was different ways I should go about setting up access to my data or not. or if the ViewModel is the best way to do it. Im still researching on how to actually do all this with the tips you gave Im still a little lost on how to work with my database and backend just working through it lol – DRW Jun 29 '20 at 22:56
  • It is good practise to have view model and entity model separated. You also could use DTO classes between other layers of your app but I suppose it is no need for you to do it. It is good practise u to have your entity classes as POCO. Your entity mappings should be done in EntityConfiguration classes – zolty13 Jun 29 '20 at 23:25
  • Ok ill keep that in mind .. thanks for the insight . – DRW Jun 29 '20 at 23:35
0

It is a Form Data model binding problem. To bind the nested objects to the model, you need to specify the properties' name of the child object, and name it in the format ModelName.PropertyName.

Take Category as an example, if you want to bind its Id and Name, you should write like this: Category.Id = 1 , Category.CategoryName = "Tool".

For more details about model binding, you can refer to the document

mj1313
  • 7,930
  • 2
  • 12
  • 32