该属性是接口类型('IFormFile')MVC Core [英] The property is of an interface type ('IFormFile') MVC Core
问题描述
我正在尝试制作一个可以保存文件(图像)的表格,但这显示了一个错误:
I'm trying to make a form that i could save a file(image) , but it shows me an error:
InvalidOperationException:属性"Product.Image"具有接口类型("IFormFile").如果它是导航属性,则通过将其强制转换为映射的实体类型来手动配置该属性的关系,否则从模型中忽略该属性. 申请
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
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
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");
}
Create.cshtml
Create.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>
推荐答案
IFormFile
是ASP.NET Core框架使用的一种类型,并且没有等效的sql server类型.
IFormFile
is a type used by the ASP.NET Core framework and it does not have a sql server type equivalent.
对于您的域模型,将其存储为byte[]
,当您使用视图时,可以使用IFormFile
类型.
For your domain model store it as byte[]
and when you work with views, is ok for you to use the IFormFile
type.
产品型号:
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:
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; }
}
控制器方法:
[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"
.
Also specify to the form enctype="multipart/form-data"
in your view.
这篇关于该属性是接口类型('IFormFile')MVC Core的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!