web-dev-qa-db-ja.com

asp.netコアにファイルをアップロードする方法は?

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

22
ryzskzkhie

タイプ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");
}
58
Shyju
 <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();
        }
0
Diako Hasani