[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;
}
}
}
執行結果:
點擊Click後
果然被我猜中!這種寫法在多個預覽圖的情況,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;
}
}
}
再次執行:
點擊Click預覽圖片
這次就正常了
※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進行預覽
預覽滿意,點擊上傳到Server
再到網站根目錄下的upload資料夾查看
確實兩張圖片上傳到網站了
至此功能全部補完~
只是不知道以這種寫法似乎會產生過多的Session造成Web Server負擔?
等哪天找到更好解法的話,到時候文章再更新
相關討論:关于FileUpLoad上传控件的问题(含HTML5做法)