[ASP.net WebForm] Image控制項仿WinForm的PictureBox,指定Image物件顯示圖片

[ASP.net WebForm] Image控制項仿WinForm的PictureBox,指定Image物件顯示圖片

這是第二次在論壇上遇到相同問題

第一次看到此發問,我很肯定地Image控制項只有ImageUrl成員可以指定路徑,沒辦法指派一個Image物件給它顯示

今天又看到類似的發問(asp.net 页面上如何显示图片),這次不知道什麼原因,我居然有靈感了

 

本Demo主要仿造WinForm的PictureBox控件,圖片來源都在記憶體中處理,不在Server電腦上存放實體圖片

這邊就來紀錄多個檔案上傳情況,順便測試使用Session的方式會不會造成衝突

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    
 

</head>
<body>
    <form runat="server"  >
    
       <!--Image控件1-->
      <asp:Image runat="server" ID="img1" Width="300" Height="300" />
      <asp:FileUpload runat="server" ID="fu_1" /><br />
       <!--Image控件2-->
      <asp:Image runat="server" ID="img2" Width="300" Height="300" />
      <asp:FileUpload runat="server" ID="fu_2" />

      
     <asp:Button Text="Click" ID="btn_Go" UseSubmitBehavior="false" runat="server" 
        onclick="btn_Go_Click" />
      


       
    </form>
</body>
</html>

 

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
 
public partial class _Default : System.Web.UI.Page
{
    //Page_Load事件  
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }

    //Click事件
    protected void btn_Go_Click(object sender, EventArgs e)
    {
        if (fu_1.HasFile)
        {
            // File was sent
            HttpPostedFile obj_file = fu_1.PostedFile;
            //將File物件存在Session
            Session["myFile"] = obj_file;
            // Set ImageUrl
            img1.ImageUrl = "showImage.ashx";
        }
        if (fu_2.HasFile)
        {
            // File was sent
            HttpPostedFile obj_file = fu_2.PostedFile;
            //將File物件存在Session
            Session["myFile"] = obj_file;
            // Set ImageUrl
            img2.ImageUrl = "showImage.ashx";
        }
         
    }


}

 

然後在網站根目錄下新增一個「showImage.ashx」

showImage.ashx內容

<%@ WebHandler Language="C#" Class="showImage" %>

using System;
using System.Web;
/*啟用讀取、寫入Session*/
using System.Web.SessionState;

/*須實作 IRequiresSessionState*/
public class showImage : IHttpHandler,IRequiresSessionState {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";/*預設純文字*/
        if (context.Session["myFile"] != null)
        {
            HttpPostedFile obj_file = (HttpPostedFile)context.Session["myFile"];

            //檔案有多大,陣列就多大
            byte[] file = new byte[obj_file.ContentLength];
            obj_file.InputStream.Read(file, 0, file.Length);//讀取Stream內容到byte[]
            context.Response.Clear();//清除緩衝區
            context.Response.ContentType = "image/jpeg";//設定MIME類型
            context.Response.BinaryWrite(file);//輸出圖片
        }


    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

執行結果:

image

點擊Click後

image

果然被我猜中!這種寫法在多個預覽圖的情況,show出來的圖片都一樣(而且都是最清涼的圖片)

所以再改寫一下Code-Behind

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
 
public partial class _Default : System.Web.UI.Page
{
    //Page_Load事件  
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }

    //Click事件
    protected void btn_Go_Click(object sender, EventArgs e)
    {
        if (fu_1.HasFile)
        {
            // File was sent
            HttpPostedFile obj_file = fu_1.PostedFile;

            //產生不重覆的sessionKey
            string sessionKey = Guid.NewGuid().ToString();
            //將File物件存在Session
            Session[sessionKey] = obj_file;
            // Set ImageUrl
            img1.ImageUrl = "showImage.ashx?sessionKey=" + sessionKey;
        }
        if (fu_2.HasFile)
        {
            // File was sent
            HttpPostedFile obj_file = fu_2.PostedFile;
            //產生不重覆的sessionKey
            string sessionKey = Guid.NewGuid().ToString();
            //將File物件存在Session
            Session[sessionKey] = obj_file;
            // Set ImageUrl
            img2.ImageUrl = "showImage.ashx?sessionKey=" + sessionKey;
        }
         
    }


}

 

showImage.ashx也要配合修改

<%@ WebHandler Language="C#" Class="showImage" %>

using System;
using System.Web;
/*啟用讀取、寫入Session*/
using System.Web.SessionState;

/*須實作 IRequiresSessionState*/
public class showImage : IHttpHandler,IRequiresSessionState {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";/*預設純文字*/
        if (!string.IsNullOrEmpty(context.Request.QueryString["sessionKey"]))
        {
            string sessionKey = context.Request.QueryString["sessionKey"];
            if (context.Session[sessionKey]!=null)//防呆
            {
                HttpPostedFile obj_file = (HttpPostedFile)context.Session[sessionKey];

                //檔案有多大,陣列就多大
                byte[] file = new byte[obj_file.ContentLength];
                obj_file.InputStream.Read(file, 0, file.Length);//讀取Stream內容到byte[]
                context.Response.Clear();//清除緩衝區
                context.Response.ContentType = "image/jpeg";//設定MIME類型
                context.Response.BinaryWrite(file);//輸出圖片
            }
           
        }


    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

再次執行:

image

點擊Click預覽圖片

image

這次就正常了

 

※2011.01.05 追記

如果預覽圖片,使用者看了滿意後想要真的上傳到Server的話?

那就再從Session把圖片物件撈出來儲存在Server上

改寫一下Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"
    Debug="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <!--Image控件1-->
    <asp:Image runat="server" ID="img1" Width="300" Height="300" />
    <asp:FileUpload runat="server" ID="fu_1" /><br />
    <!--Image控件2-->
    <asp:Image runat="server" ID="img2" Width="300" Height="300" />
    <asp:FileUpload runat="server" ID="fu_2" />
    <asp:Button Text="Click" ID="btn_Go" UseSubmitBehavior="false" runat="server" OnClick="btn_Go_Click" /><hr />
    <asp:Button Text="預覽滿意,上傳到Server" runat="server" ID="btn_Save" 
        onclick="btn_Save_Click" />
    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Text;
using System.Security.Principal;
using System.Data;
using System.Collections;
using System.Net;
using System.Collections.Specialized;
using System.Data.SqlClient;
using System.Net.Mail;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            
        }

    }


    //Click事件
    protected void btn_Go_Click(object sender, EventArgs e)
    {
        if (fu_1.HasFile)
        {
            // File was sent
            HttpPostedFile obj_file = fu_1.PostedFile;

            //產生不重覆的sessionKey
            string sessionKey = Guid.NewGuid().ToString();
            //將File物件存在Session
            Session[sessionKey] = obj_file;
            // Set ImageUrl
            img1.ImageUrl = "showImage.ashx?sessionKey=" + sessionKey;
        }
        if (fu_2.HasFile)
        {
            // File was sent
            HttpPostedFile obj_file = fu_2.PostedFile;
            //產生不重覆的sessionKey
            string sessionKey = Guid.NewGuid().ToString();
            //將File物件存在Session
            Session[sessionKey] = obj_file;
            // Set ImageUrl
            img2.ImageUrl = "showImage.ashx?sessionKey=" + sessionKey;
        }

    }

    //預覽滿意我要儲存
    protected void btn_Save_Click(object sender, EventArgs e)
    {
        if (img1.ImageUrl!="")//防呆
        {
            //取得剛剛Guid的值
           string queryStringValue = HttpUtility.ParseQueryString(img1.ImageUrl)["showImage.ashx?sessionKey"];

           
           this.saveImageInServer(queryStringValue);
        }

        if (img2.ImageUrl!="")//防呆
        {
            //取得剛剛Guid的值
            string queryStringValue = HttpUtility.ParseQueryString(img2.ImageUrl)["showImage.ashx?sessionKey"];
            this.saveImageInServer(queryStringValue);
        }
          
    }

    //存圖片在upload目錄下
    private void saveImageInServer(string queryStringValue)
    {
        if (Session[queryStringValue] != null)//防呆
        {
            
            HttpPostedFile obj_file = (HttpPostedFile)Session[queryStringValue];
            obj_file.SaveAs(Server.MapPath("~/upload/") + Guid.NewGuid().ToString() + ".jpg");
        }
    
    }
}

執行結果:

使用者已按下Click進行預覽

image

預覽滿意,點擊上傳到Server

image

再到網站根目錄下的upload資料夾查看

image

確實兩張圖片上傳到網站了

至此功能全部補完~

 

 

只是不知道以這種寫法似乎會產生過多的Session造成Web Server負擔?

等哪天找到更好解法的話,到時候文章再更新

 

相關討論:关于FileUpLoad上传控件的问题(含HTML5做法)