使用 XML Web 服务将图像上传到 Oracle 数据库以及从 Oracle 数据库下载图像
本文将介绍如何使用 XML Web 服务和 ASP.NET 将图像上传到 Oracle 数据库以及从 Oracle 数据库下载图像。
引言
在本文中,我将介绍如何使用 XML Web 服务将图像上传到 Oracle 数据库以及从 Oracle 数据库下载图像。在某些情况下,我的 Web 应用程序需要与远程数据库服务器进行通信。远程通信是 Web 应用程序的主要方面之一,因此其受欢迎程度取决于此框架。共享远程终端之间的文本信息是一项常见的任务,我们不必为此烦恼。但是,最近我发现自己处于一个需要将图像存储到远程 Oracle 数据库作为 blob 数据类型,并在之后将其提取到客户端的境地。下图描述了我的代码的内部工作原理。
背景
首先,客户端机器通过请求 Web 服务来上传图像。XML Web 服务会验证用户是否已通过身份验证。如果用户已授权,则会将图像转换为字节并将其发送到 Oracle 数据库。以下代码描述了其内部工作原理。
使用代码
首先,在 Oracle 数据库中创建以下表
Create table tblImageService
(
Image_id timestamp default sysdate,
image_data blob,
constraint pk_image_id primary key(image_id)
);
创建以下存储过程以将图像插入 Oracle 数据库
CREATE OR REPLACE PROCEDURE InsertImage
( image_data in blob )
AS
BEGIN
Insert into tblImageService(image_data) values(image_data);
END;
现在,创建一个 Web 服务并将以下子例程公开为一个用于上传图像的 Web 方法
[WebMethod]
public int FireImage(string user_name, string password,
byte[] news_image)
{
// Initiate connection with oracle
OracleConnection Conxn1 =
new OracleConnection("user id=test;password=test;data source=jamb");
try
{
//Verify the user
if (user_name == "user_name" && password == "password")
{
try
{
//Open the connection
Conxn1.Open();
byte[] tempBuff = news_image;
OracleTransaction tx;
tx = Conxn1.BeginTransaction();
OracleCommand cmd;
cmd = Conxn1.CreateCommand();
cmd.CommandText = "declare xx blob; begin " +
"dbms_lob.createtemporary(xx, false, 0);" +
" :tempblob := xx; end;"; // PL/SQL to read blob data
cmd.Parameters.Add(new OracleParameter("tempblob",
OracleDbType.Blob)).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
OracleBlob tempLob;
tempLob = (OracleBlob)cmd.Parameters[0].Value;
tempLob.BeginChunkWrite(); // start writing the LOB data
tempLob.Write(tempBuff, 0, tempBuff.Length);
tempLob.EndChunkWrite();
cmd.Parameters.Clear();
cmd.CommandText = "InsertImage";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new OracleParameter("image_data",
OracleDbType.Blob)).Value = tempLob;
cmd.ExecuteNonQuery(); //Execute the command to database
tx.Commit(); // Commit the transaction
}
catch
{
}
finally
{
Conxn1.Close();
}
}
}
catch (Exception ex)
{
string showError = "Error: " + ex.Message;
}
finally
{
}
return 1;
}
在上面的代码中,FireImage
子例程接受三个输入,即用户名、密码和字节形式的图像数据。调用此子例程后,以字节形式发送的图像数据将被转换为 blob 数据,并使用存储过程插入到 Oracle 数据库表中。
在此之后,您需要创建另一个子例程,该子例程从数据库中提取图像,将其传输到 64 位字符串,然后将其传递给客户端
[WebMethod]
public string FetchNewsImage(string image_id)
{ //Initiate the connection
OracleConnection Conxn1 =
new OracleConnection("user id=test;password=test;data source=jamb");
OracleDataReader dtr = null;
string imageString = "";
try
{
Conxn1.Open();
string id = image_id;
OracleCommand cmd = new OracleCommand("select image_data " +
"from tblImageService where to_char(" +
"image_id,'DD-MON:YY-HH:MI:SS')='" +
id + "'", Conxn1);
dtr = cmd.ExecuteReader();
byte[] arrpicture = new byte[0];
while (dtr.Read())
{
arrpicture = (byte[])dtr["image_data"];
}
imageString = Convert.ToBase64String(arrpicture);
}
catch (Exception ex)
{
string showError = "Error: " + ex.Message;
}
finally
{
dtr.Close();
Conxn1.Close();
}
return imageString;
}
上述子例程以图像 ID 作为参数,并使用该 ID 从数据库中提取图像。之后,它从数据库中提取数据,将其转换为 byte[]
数据类型,然后使用 Convert.ToBase64String
方法转换为 Base 64 字符串。
现在,您需要开发此 Web 服务的客户端交互。首先,创建一个名为 AddImage.aspx 的页面,并使用 FileUpload
服务器控件来浏览图像。然后,从我们的 XML Web 服务中调用 FireImage
子例程(不要忘记添加对我们上面的 XML Web 服务的引用)。以下是调用 FireImage
子例程的代码
protected void btnSubmit_Click(object sender, EventArgs e)
{
try
{
//Browse the image file and then convert it to byte[] data
byte[] tempBuff = new byte[Upload1.PostedFile.InputStream.Length];
Upload1.PostedFile.InputStream.Read(tempBuff, 0,
Convert.ToInt32(Upload1.PostedFile.InputStream.Length));
Upload1.PostedFile.InputStream.Close();
//Call ImageDataService Web Service
newsImageDataService.ImageDataService fireImage =
new newsImageDataService.ImageDataService();
fireImage.FireImage("user_name", "password", tempBuff);
Response.Write("Article Successfully saved!!");
}
catch (Exception ex)
{
Response.Write("Error: " + ex.Message);
}
finally
{
//do nothing
}
}
此代码使用 ImageDataService
XML Web 服务将您的图像保存到数据库。
现在,您需要从数据库中查看已插入的图像。首先,创建一个名为 viewImage.aspx 的 Web 页面,并将以下代码添加到页面加载子例程中。以下是给您的代码
protected void Page_Load(object sender, EventArgs e)
{
try
{
Conxn1.Open();
OracleCommand cmd = new OracleCommand("select '<a href=/ImageService" +
"/LoadImage.aspx?image_id='||to_char(" +
"image_id,'DD-MON:YY-HH:MI:SS')||'>'||" +
"to_char(image_id,'DD-MON:YY-HH:MI:SS')|| " +
" '' as news_url from tblImageService ", Conxn1);
OracleDataReader dtr = cmd.ExecuteReader();
while (dtr.Read())
{
this.lblImage.Text = "<ul>" +
"<li>" + dtr["news_url"].ToString() + "</li>" +
"</ul>";
}
}
catch(Exception ex)
{
Response.Write("Error: " + ex.Message);
}
finally
{
Conxn1.Close();
}
}
上述代码生成从数据库提取的图像的链接,并放置适当的查询字符串进行传递。现在,您需要构建另一个实际生成图像的页面。我们将页面命名为 LoadImage.aspx。实际上,所有处理都由这个页面完成
protected void Page_Load(object sender, EventArgs e)
{
string id = Request.QueryString["image_id"].ToString();
try
{
newsImageDataService.ImageDataService getImage =
new newsImageDataService.ImageDataService();
byte[] arrpicture =
System.Convert.FromBase64String(getImage.FetchNewsImage(id));
Response.ContentType = "Image/Jpeg";
Response.BinaryWrite(arrpicture);
}
catch (Exception ex)
{
Response.Write("Error: " + ex.Message);
}
finally
{
}
}
上述代码调用 FetchNewsImage
子例程,该子例程接受图像的 ID。一旦您将图像 ID 传递给 FetchNewsImage
子例程,它将返回一个 Base 64 字符串。从子例程获取 Base 64 字符串后,您可以使用 System.Convert.FromBase64String
方法将其转换回 byte[]
数据。最后,您使用 Response.BinaryWrite
方法将 byte[]
数据作为图像写入。就是这样!!
关注点
首先,我尝试使用 .ToString()
方法将图像作为字符串传输。在将此字符串转换为 byte[]
后,它出现了一个奇怪的输出……后来,我发现我需要将 byte[]
数据转换为 64 位字符串才能保留其原始状态。
历史
- 版本1.01