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.

But i want to store the picture in a folder in server, and just want the ImagePath to store in DB. Thats why i used IFormFile instead of byte[]. – Ertan Hasani Apr 1, 2017 at 20:18 Ok , take a look at very first post , i updated and added the HttpPost method. but the problem is that now takes Image as NULL. Do you have any idea why it takes Image as NULL? – Ertan Hasani Apr 1, 2017 at 20:50 In your View. specify enctype="multipart/form-data" to the form. This will allow you to send both the file and the model. – Cristian Szpisjak Apr 1, 2017 at 20:53 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; } As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center. – Community May 28, 2022 at 0:25 Kindly add more details to your answer, explanations on how your code works and how this address the OP's question would be a great help not just for the asker but also for the future researchers. – Kuro Neko May 31, 2022 at 5:55

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.