Ответ 1
Вы можете добавить новое свойство типа IFormFile
в модель представления
public class CreatePost
{
public string ImageCaption { set;get; }
public string ImageDescription { set;get; }
public IFormFile MyImage { set; get; }
}
и в вашем методе действия GET мы создадим объект этой модели представления и отправим в представление.
public IActionResult Create()
{
return View(new CreatePost());
}
Теперь в вашем Создать вид, который сильно типизированных на наш взгляд, модели, имеют form
тег, который имеет enctype
набор атрибутов для "multipart/form-data"
@model CreatePost
<form asp-action="Create" enctype="multipart/form-data">
<input asp-for="ImageCaption"/>
<input asp-for="ImageDescription"/>
<input asp-for="MyImage"/>
<input type="submit"/>
</form>
И ваше действие HttpPost для обработки отправки формы
[HttpPost]
public IActionResult Create(CreatePost model)
{
var img = model.MyImage;
var imgCaption = model.ImageCaption;
//Getting file meta data
var fileName = Path.GetFileName(model.MyImage.FileName);
var contentType = model.MyImage.ContentType;
// do something with the above data
// to do : return something
}
Если вы хотите загрузить файл в какой-либо каталог своего приложения, вы должны использовать IHostingEnvironment
чтобы получить путь к IHostingEnvironment
. Вот рабочий образец.
public class HomeController : Controller
{
private readonly IHostingEnvironment hostingEnvironment;
public HomeController(IHostingEnvironment environment)
{
hostingEnvironment = environment;
}
[HttpPost]
public IActionResult Create(CreatePost model)
{
// do other validations on your model as needed
if (model.MyImage != null)
{
var uniqueFileName = GetUniqueFileName(model.MyImage.FileName);
var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
var filePath = Path.Combine(uploads,uniqueFileName);
model.MyImage.CopyTo(new FileStream(filePath, FileMode.Create));
//to do : Save uniqueFileName to your db table
}
// to do : Return something
return RedirectToAction("Index","Home");
}
private string GetUniqueFileName(string fileName)
{
fileName = Path.GetFileName(fileName);
return Path.GetFileNameWithoutExtension(fileName)
+ "_"
+ Guid.NewGuid().ToString().Substring(0, 4)
+ Path.GetExtension(fileName);
}
}
Это сохранит файл в папке uploads
каталоге wwwwroot
вашего приложения со случайным именем файла, сгенерированным с помощью Guids (для предотвращения перезаписи файлов с тем же именем)
Здесь мы используем очень простой метод GetUniqueName
который добавляет 4 символа из guid в конец имени файла, чтобы сделать его несколько уникальным. Вы можете обновить метод, чтобы сделать его более сложным по мере необходимости.
Стоит ли хранить полный URL-адрес загруженного изображения в базе данных?
Нет. Не храните полный URL-адрес изображения в базе данных. Что если завтра ваш бизнес решит изменить название вашей компании/продукта с www.thefacebook.com
на www.facebook.com
? Теперь вы должны исправить все URL в таблице!
Что вы должны хранить?
Вы должны сохранить уникальное имя файла, которое вы сгенерировали выше (uniqueFileName
uniqueFileName мы использовали выше), чтобы сохранить имя файла. Если вы хотите отобразить изображение обратно, вы можете использовать это значение (имя файла) и построить URL для изображения.
Например, вы можете сделать это по вашему мнению.
@{
var imgFileName = "cats_46df.png";
}
<img src="~/uploads/@imgFileName" alt="my img"/>
Я просто жестко закодировал имя изображения в переменную imgFileName
и использовал его. Но вы можете прочитать имя сохраненного файла из вашей базы данных и установить его в свойстве модели представления и использовать его. Что-то вроде
<img src="~/uploads/@Model.FileName" alt="my img"/>
Сохранение изображения в таблицу
Если вы хотите сохранить файл как bytearray/varbinary в вашей базе данных, вы можете преобразовать объект IFormFile
в байтовый массив следующим образом
private byte[] GetByteArrayFromImage(IFormFile file)
{
using (var target = new MemoryStream())
{
file.CopyTo(target);
return target.ToArray();
}
}
Теперь в вашем методе http post action вы можете вызвать этот метод для генерации байтового массива из IFormFile
и использовать его для сохранения в вашей таблице. Приведенный ниже пример пытается сохранить объект сущности Post с использованием платформы сущностей.
[HttpPost]
public IActionResult Create(CreatePost model)
{
//Create an object of your entity class and map property values
var post=new Post() { ImageCaption = model.ImageCaption };
if (model.MyImage != null)
{
post.Image = GetByteArrayFromImage(model.MyImage);
}
_context.Posts.Add(post);
_context.SaveChanges();
return RedirectToAction("Index","Home");
}