Asp.net MVC 6にいくつかのモデルデータを使用してファイルまたは画像をアップロードする方法たとえば、このようなフォームがあります。
<form>
<input type="file">
<input type="text" placeholder="Image name...">
<input type="text" placeholder="Image description...">
<input type="submit" value="Submit">
</form>
アップロード方法については多くのチュートリアルを読みましたが、上記のフォームのようなデータをアップロードしているものは見当たりません。
また、Codeigniter画像操作クラスと同じサイズ変更と画像透かし用の画像操作用のライブラリはありますか? ( https://codeigniter.com/user_guide/libraries/image_lib.html
タイプ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());
}
ビューモデルに厳密に型指定されたCreateビューに、form
属性が"multipart/form-data"
に設定されたenctype
タグがあります。
@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
を使用してwebrootパスを取得する必要があります。これが実際のサンプルです。
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);
}
}
これにより、Guidsを使用して生成されたランダムなファイル名で、アプリのuploads
ディレクトリ内のwwwwroot
フォルダーにファイルが保存されます(同じ名前のファイルの上書きを防ぐため)
ここでは、非常に単純なGetUniqueName
メソッドを使用しています。このメソッドは、guidからファイル名の末尾に4文字を追加して、ファイル名を多少一意にします。メソッドを更新して、必要に応じてより洗練させることができます。
アップロードした画像の完全なURLをデータベースに保存しますか?
いいえ。データベースの画像の完全なURLを保存しないでください。明日、あなたの会社があなたの会社/製品名をwww.thefacebook.com
からwww.facebook.com
に変更すると決めたらどうしますか?次に、テーブル内のすべてのURLを修正する必要があります!
何を保存する必要がありますか?
上記で生成した一意のファイル名(、上記で使用したuniqueFileName
varibale)を保存して、ファイル名を保存する必要があります。画像を表示して戻す場合、この値(ファイル名)を使用して、画像の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ポストアクションメソッドで、このメソッドを呼び出して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");
}
<form class="col-xs-12" method="post" action="/News/AddNews" enctype="multipart/form-data">
<div class="form-group">
<input type="file" class="form-control" name="image" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary col-xs-12">Add</button>
</div>
</form>
私の行動は
[HttpPost]
public IActionResult AddNews(IFormFile image)
{
Tbl_News tbl_News = new Tbl_News();
if (image!=null)
{
//Set Key Name
string ImageName= Guid.NewGuid().ToString() + Path.GetExtension(image.FileName);
//Get url To Save
string SavePath = Path.Combine(Directory.GetCurrentDirectory(),"wwwroot/img",ImageName);
using(var stream=new FileStream(SavePath, FileMode.Create))
{
image.CopyTo(stream);
}
}
return View();
}