65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 XML Web 服务将图像上传到 Oracle 数据库以及从 Oracle 数据库下载图像

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.33/5 (2投票s)

2008 年 5 月 3 日

CPOL

3分钟阅读

viewsIcon

46784

downloadIcon

453

本文将介绍如何使用 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
© . All rights reserved.