Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to make a form that i could save a file(image) , but it shows me an error:
InvalidOperationException: The property 'Product.Image' is of an interface type ('IFormFile'). If it is a navigation property manually configure the relationship for this property by casting it to a mapped entity type, otherwise ignore the property from the model.
Apply
I dont know how to fix it , here's the code:
Product.cs
public class Product
public Product()
OrderDetails = new HashSet<OrderDetails>();
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? CategoryId { get; set; }
public decimal? Price { get; set; }
public int? Quantity { get; set; }
public string ImagePath { get; set; }
public virtual ICollection<OrderDetails> OrderDetails { get; set; }
public virtual Category Category { get; set; }
ProductFormViewModel.cs
public class ProductFormViewModel
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? CategoryId { get; set; }
public decimal? Price { get; set; }
public int? Quantity { get; set; }
public IFormFile Image { get; set; }
Create Action
[HttpGet]
public IActionResult Create()
var categories = _repository.GetCategories().ToList();
var categoriesModel = categories.Select(p => new
p.Id,
p.Name
ViewBag.Categories = new SelectList(categoriesModel, "Id", "Name");
return View();
[HttpPost]
public IActionResult Create(ProductFormViewModel product)
var file = product.Image; // **it returns NULL**
var upload = Path.Combine(_environment.ContentRootPath, "wwwroot\\uploads", product.Name);
if (!Directory.Exists(upload))
Directory.CreateDirectory(upload);
var filePath = Path.Combine(upload, file.FileName);
if (file.Length > 0)
using (var fileStream = new FileStream(filePath, FileMode.Create))
file.CopyTo(fileStream);
var producti = new Product();
producti.CategoryId = product.CategoryId;
producti.Description = product.Description;
producti.Name = product.Name;
producti.Price = product.Price;
producti.Quantity = product.Quantity;
producti.ImagePath = filePath;
_repository.AddProduct(producti);
_repository.SaveChanges();
<div class="panel-body">
<form class="form-group" asp-action="Create" asp-controller="Products" method="post">
<input type="hidden" asp-for="Id"/>
<div class="col-md-12">
<div class="form-group col-md-6">
<label asp-for="Name" class="control-label col-md-3"></label>
<input asp-for="Name" type="text" class="form-control col-md-3"/>
<div class="form-group col-md-6">
<label asp-for="CategoryId" class="control-label col-md-3"></label>
<select asp-for="CategoryId" asp-items="@ViewBag.Categories" class="form-control col-md-3">
<option hidden disabled selected >Select One</option>
</select>
<div class="form-group col-md-6">
<label asp-for="Description" class="control-label col-md-3"></label>
<textarea asp-for="Description" class="form-control" rows="4"></textarea>
<div class="form-group col-md-6">
<label asp-for="Price" class="control-label col-md-3"></label>
<input type="text" asp-for="Price" class="form-control col-md-3"/>
<div class="form-group col-md-6">
<label asp-for="Quantity" class="control-label col-md-3"></label>
<input type="text" asp-for="Quantity" class="form-control col-md-3"/>
<div class="form-group col-md-12">
<label class="control-label">Select Image</label>
<input asp-for="Image" type="file" class="btn-file"/>
<div class="form-group col-md-12 text-center">
<input type="submit" class="btn btn-success" value="Save"/>
</form>
IFormFile
is a type used by the ASP.NET Core framework and it does not have a sql server type equivalent.
For your domain model store it as byte[]
and when you work with views, is ok for you to use the IFormFile
type.
ProductModel:
public class Product
public Product()
OrderDetails = new HashSet<OrderDetails>();
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? CategoryId { get; set; }
public decimal? Price { get; set; }
public int? Quantity { get; set; }
public string ImagePath { get; set; }
public virtual ICollection<OrderDetails> OrderDetails { get; set; }
public virtual Category Category { get; set; }
ProductViewModel:
public class ProductViewModel
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? CategoryId { get; set; }
public decimal? Price { get; set; }
public int? Quantity { get; set; }
public IFormFile Image { get; set; }
Controller method:
[HttpGet]
public IActionResult Create()
var categories = _repository.GetCategories().ToList();
var categoriesModel = categories.Select(p => new
p.Id,
p.Name
ViewBag.Categories = new SelectList(categoriesModel, "Id", "Name");
return View();
[HttpPost]
public IActionResult Create(ProductViewModel model)
// Save the image to desired location and retrieve the path
// string ImagePath = ...
// Add to db
_repository.Add(new Product
Id = model.Id,
ImagePath = ImagePath,
// and so on
return View();
Also specify to the form enctype="multipart/form-data"
in your view.
–
–
–
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? CategoryId { get; set; }
public decimal? Price { get; set; }
public int? Quantity { get; set; }
[NotMapped]
public IFormFile Image { get; set; }
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.