.NET MVC上傳圖片到資料庫

  • 5347
  • 0

upload image into database and display using C#

一般上傳圖片可以直接存在磁碟,需要的時候用路徑直接取,或是轉成二進位存進DB裡面,這邊兩種都會介紹到
 

第一部分先做畫面的部分
就是很簡單的fuleuploadg,因為是範例就不檢查檔案類型跟大小了

<form action="@Url.Action("UploadImage", "Upload")" method="post" enctype = "multipart/form-data">

<input type="file" accept=".png, .jpg, .jpeg" name="File" id="File"/>
<input type="submit" value="上傳" />

</form>

然後是action方法
這邊要把圖片轉成二進位
有兩種方式可以做

第二種是先存在資料夾後再轉成byte array

 [HttpPost]
        public ActionResult UploadImage(HttpPostedFileBase File)
        {
            if (File != null && File.ContentLength > 0)
            {
                //存到資料夾
                var FileName = Path.GetFileName(File.FileName);
                var FilePath = Path.Combine(Server.MapPath("~/Images/"), FileName);
                File.SaveAs(FilePath);


                //轉成byte 方法一 直接轉
                byte[] FileBytes;
                using (MemoryStream ms = new MemoryStream())
                {
                    File.InputStream.CopyTo(ms);
                    FileBytes = ms.GetBuffer();
                }
                //方法二 讀實體檔案出來再轉
                //using (var Fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
                //{
                //    using (var Reader = new BinaryReader(Fs))
                //    {
                //        FileBytes = Reader.ReadBytes((int)Fs.Length);
                //    }
                //}

                //存進資料庫再取出
                InsertPhoto(FileBytes);
                FileBytes = SelectPhoto();

                TempData["Data"] = FileBytes;
               
            }


            return View();
        }

接著再把轉好的byte array存到database裡
順帶一提,DB存圖片二進位的型別可以用VARBINARY(MAX) 或image

但是建議使用VARBINARY(MAX)
可以參考https://sqltutorialtips.blogspot.com/2016/11/image-vs-varbinarymax.html

DB schema
 

create table ImageData(
ID Int identity(1,1),
Image VARBINARY(MAX)
PRIMARY KEY( ID )
)

然後就要把圖片新增到資料表裡面了
第一次做的時候是用Dapper 插入的
但是Dapper的DbType只有Binary可以選
這樣造成插入的資料被截斷,撈圖片出來的時候會不完整
後來改成用最原始的ADO.NET 才可以
 

public void InsertPhoto(byte[] photo)
        {
            string str = "Insert into ImageData(Image) values(@Image)";
            using (SqlCommand cmd = new SqlCommand(str, con))
            {
                cmd.Parameters.AddWithValue(@"Image", photo);
                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();
            }


        }
        public byte[] SelectPhoto()
        {
            byte[] photo;
            string str = "select top 1 Image from ImageData order by ID desc";
            using (SqlCommand cmd = new SqlCommand(str, con))
            {
                cmd.CommandType = CommandType.Text;
                con.Open();
                SqlDataReader reader = cmd.ExecuteReader();
                if (reader.Read())
                {
                    photo = (byte[])reader["Image"];
                    con.Close();
                    return photo;
                }
                else
                    return null;

                
            }
           

        }


 

再回到頁面上要顯示圖片
這邊是直接參考mrkt的做法,所以就不多說了
有興趣可以直接去看http://kevintsengtw.blogspot.com/2013/10/aspnet-mvc-image.html
 


    @{ 
        byte[] photo = TempData["Data"] == null?null: TempData["Data"] as byte[];
        string imageData = null;
        if (photo != null)
        {
            
            string base64 = Convert.ToBase64String(photo);
            imageData = string.Format("data:image/gif;base64,{0}", base64);
        }

    }
    <br/>
    
    <img src="@imageData" />

 

 

 

專案github連結

https://github.com/shadow061103/NetMVCTool/blob/master/NetMVCTool/Controllers/UploadController.cs