【问题标题】:The property is of an interface type ('IFormFile') MVC Core该属性是一个接口类型 ('IFormFile') MVC Core
【发布时间】:2023-03-09 09:55:01
【问题描述】:

我正在尝试制作一个可以保存文件(图像)的表单,但它显示了一个错误:

InvalidOperationException:属性“Product.Image”属于接口类型(“IFormFile”)。如果它是导航属性,则通过将其转换为映射的实体类型手动配置此属性的关系,否则忽略模型中的属性。 申请

我不知道如何修复它,这是代码:

产品.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; }
    }

创建动作

  [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();




            return RedirectToAction("Index","Products");
        }

创建.cshtml

@model ProductFormViewModel
<br />
<br />
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">
        </div>
        <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>
                    <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>
                    <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>
                    <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>
                    <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>
                    <div class="form-group col-md-12">
                        <label class="control-label">Select Image</label>
                        <input asp-for="Image" type="file" class="btn-file"/>
                    </div>
                    <div class="form-group col-md-12 text-center">
                        <input type="submit" class="btn btn-success" value="Save"/>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

【问题讨论】:

    标签: c# asp.net-mvc forms asp.net-core asp.net-core-mvc


    【解决方案1】:

    IFormFile 是 ASP.NET Core 框架使用的类型,它没有等效的 sql server 类型。

    对于您的域模型,将其存储为byte[],当您使用视图时,您可以使用IFormFile 类型。

    产品型号:

    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; }
    }
    

    产品视图模型:

    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; }
    }
    

    控制器方法:

    [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();
    }
    

    还要在您的视图中指定enctype="multipart/form-data" 形式。

    【讨论】:

    • 但我想将图片存储在服务器的文件夹中,并且只想将 ImagePath 存储在数据库中。这就是我使用 IFormFile 而不是 byte[] 的原因。
    • 我修改了答案。
    • 好的,看看第一篇文章,我更新并添加了 HttpPost 方法。但问题是现在将 Image 设为 NULL。你知道为什么它把 Image 当作 NULL 吗?
    • 在您的视野中。在表单中指定enctype="multipart/form-data"。这将允许您发送文件和模型。
    猜你喜欢
    • 1970-01-01
    • 2021-05-16
    • 2018-03-14
    • 1970-01-01
    • 2013-10-15
    • 2019-11-11
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多