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

AJAX 照片专辑项目

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (10投票s)

2008年12月16日

CPOL

4分钟阅读

viewsIcon

98373

downloadIcon

3086

该项目展示了如何使用 AJAX XmlHttpRequest 创建照片集和幻灯片。

AjaxPhotoAlbumProject

引言

本文介绍了几种创建简单照片集和幻灯片的技术。

  • 将图像保存并检索到 MS SQL Server 数据库。
  • 调整图像大小。
  • 使用 AJAX XmlHttpRequest 从数据库检索图像。
  • 使用 AJAX UpdatePanelScriptManager 在不刷新网页的情况下从数据库检索图像。

背景

AjaxPhotoAlbum 项目的开发旨在展示几项有用的技术。

  1. 示例照片集由缩略图和一个图像控件组成,用于浏览大图。
  2. 当用户将鼠标悬停在缩略图图像上时,大图也会填充所选图像。大图使用网页 GetSelectedImage.aspx 通过 AJAX XmlHttpRequest 从数据库中检索。

  3. 用户还可以单击“上一个”(<<)和“下一个”(>>)链接按钮来获取大图占位符中的上一个/下一个图像。整个控件放置在 AJAX UpdatePanel 中,因此,即使图像是在回发事件中从数据库检索的,网页也不会刷新,只有大图控件会被新图像更新。
  4. 用户还可以运行幻灯片,它将从数据库中以从 Interval 下拉列表控件中选择的间隔检索图像。在这种情况下,AJAX XmlHttpRequst 对象用于发送请求并使用后台网页 GetSelectedImage.aspx 获取响应。
  5. 照片集的图像存储在数据库中。要将图像添加到数据库,用户可以单击“添加新图像”按钮。原始图像将被调整为两种不同的尺寸 - 小尺寸(宽度 120 像素 - 用于缩略图)和大尺寸(宽度 250 像素 - 用于大图占位符)并保存到数据库的“Images”表中。
  6. 当需要从数据库检索图像时(无论是用于缩略图还是大图控件),都会将其读入字节数组,然后写入网页“ImagePage.aspx”,该网页的链接又用作网页上图像控件的“src”属性。

使用代码

对于这个项目,创建了一个 MS SQL Server 数据库“AjaxPhotoAlbum”,其中只有一个表“Images”。创建表的脚本可以在下载包中找到,但下面是“Images”表的描述。

列名 数据类型
ImageId int(主键,标识种子 = 1)
ImageSmall 图像
ImageLarge 图像

此表将保存 AjaxPhotoAlbum 项目的图像。这里显示了 web.config 文件中的连接字符串。

<appSettings>
    <add key="DSN" 
      value="server=localhost;Integrated Security=SSPI;database=AjaxPhotoAlbum"/>
</appSettings>

完整的项目结构包括四个层。

  • 表示层Default.aspx
    • GetSelectedImage.aspx(提供 AJAX XmlHttpRequest 调用中实际回发的网页)
    • ImagePage.aspx(在图像控件中显示从数据库检索到的图像的网页)
    • WebControls
      • PhotoAlbumControl.ascx
      • SlideShow.ascx
    • JavaScript
      • AjaxImage.js
    • 图像
    • CSS
  • 业务逻辑层:App_Code
  • BL

    • ImageClass.cs
  • 数据访问层:App_Code
  • DAL

    • SQLHelper.cs
  • MS SQL Server 数据库AjaxPhotoAlbum 数据库
    • Images 表

PhotoAlbumControl.ascx 放置在 AJAX UpdatePanel 中的 Default.aspx 网页上。Default.aspx 还有一个 ScriptManager 控件。为了使 AJAX 控件正常工作,必须在 <system.web> 节点下包含 <httpHandlers> 部分。

<httpHandlers>
    <remove verb="*" path="*.asmx"/>
    <add verb="*" path="*.asmx" validate="false" 
      type="System.Web.Script.Services.ScriptHandlerFactory, 
            System.Web.Extensions, Version=1.0.61025.0, 
            Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add verb="*" path="*_AppService.axd" 
            validate="false" 
            type="System.Web.Script.Services.ScriptHandlerFactory, 
                  System.Web.Extensions, Version=1.0.61025.0, 
                  Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add verb="GET,HEAD" path="ScriptResource.axd" 
            type="System.Web.Handlers.ScriptResourceHandler, 
                   System.Web.Extensions, Version=1.0.61025.0, 
                   Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
            validate="false"/>
</httpHandlers>

通过上述设置,当用户单击“上一个”/“下一个”按钮(“<<”或“>>”)时,网页会回发但不会整体刷新。只有 imgPhoto Web 控件会被新选定的图像刷新。缩略图构建为 DataList 控件。图像 ID 从数据库检索,并在 DataList ItemDataBound() 事件中填充缩略图的“src”、“onclick”和“onmouseover”属性。

protected void ThumbnailsItemDatabound(object sender, DataListItemEventArgs e)
{
    Image tImage = (Image)dlThumbnails.Controls[e.Item.ItemIndex].Controls[3];
    string ajaxServerUrl = "GetSelectedImage.aspx";
    tImage.Attributes.Add("src", "ImagePage.aspx?s=s&id=" + 
      ((DataRowView)e.Item.DataItem).Row.ItemArray[0].ToString());
    tImage.Attributes.Add("onclick", 
      "getImage(‘" + ajaxServerUrl + "‘," + 
      ((DataRowView)e.Item.DataItem).Row.ItemArray[0].ToString() + ")");
    tImage.Attributes.Add("onmouseover", "getImage(‘" + 
      ajaxServerUrl + "‘," + 
      ((DataRowView)e.Item.DataItem).Row.ItemArray[0].ToString() + ")");
}

onclick”和“onmouseover”缩略图图像属性在 AJAX JavaScript 函数 getImage() 中调用,以使用缩略图中选定的图像填充大图控件 impPhotogetImage() JavaScript 函数向网页 GetSelectedImage.aspx 发送 AJAX XmlHttpRequest,该网页进而执行实际回发以从数据库检索请求的图像 ID。

//Sending information to server
function getImage(AjaxServerUrl, id)
{ 
    var url = AjaxServerUrl + "?id=" + id
    imageClient.open("GET", url);
    imageClient.onreadystatechange = getImageBack; 
    imageClient.send(null); 
}

GetSelectedImage.aspx 网页检索所需的图像 ID,并以 XML 格式作为响应返回。

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Tirex;
public partial class GetSelectedImage : System.Web.UI.Page
{
    DataSet ds = new DataSet();
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Clear();
        Response.ContentType = "text/xml";
        int id = 0;
        if (Request.Params["id"] != null)
        {
            id = Int32.Parse(Request.Params["id"].ToString());
        }
        else
        {
            if (Session["ImageId"] != null)
            { 
                id = Int32.Parse(Session["ImageId"].ToString());
            }
            id = ImageClass.GetImageId(id);
            Session["ImageId"] = id.ToString();
        } 
        Session["SelectedImageId"] = id.ToString();
        Response.Write("<Root>");
        Response.Write("<ImageId>");
        Response.Write(id);
        Response.Write("</ImageId>");
        Response.Write("</Root>");
    }
}

响应由 getImageBack() JavaScript 函数接收并解析。请考虑 Internet Explorer 和 Firefox 处理响应方式的差异。

//Waiting and processing server response
function getImageBack(response)
{ 
    var imageId = 0;
    try
    { 
        if(imageClient.readyState == COMPLETE && imageClient.status == OK)
        { 
            //branch for Firefox version
            if (document.implementation.createDocument)//Firefox
            { 
                //Get Image
                var xmlElementImageId = 
                  imageClient.responseXML.getElementsByTagName(
                  "Root")[0].childNodes[0];
                imageId = xmlElementImageId.textContent;
            }
            //branch for IE/Windows ActiveX version
            else if (document.all)//IE
            { 
                xmlDocument = new ActiveXObject(‘Microsoft.XMLDOM‘);
                xmlDocument.async = false;
                //The responseText is loaded into XML document
                xmlDocument.loadXML(imageClient.responseText);
                //Get Image
                var xmlElementImageId = 
                    xmlDocument.selectSingleNode(‘Root/ImageId‘);
                imageId = xmlElementImageId.text;
            } 
            var imgPhoto;
            imgPhoto = window.document.getElementById(
                           "PhotoAlbumControl1_imgPhoto");
            imgPhoto.src = "ImagePage.aspx?s=l&id=" + imageId;
        }
    }
    catch(err)
    {
        alert(err.message);
    } 
}

图像以字节数组的形式从数据库检索,并写入 Image.aspx 网页,该网页又用作缩略图图像或 imgPhoto 图像控件的“src”属性。

private void Page_Load(object sender, System.EventArgs e)
{
    string sSQL = "";
    SqlDataReader drData = null;
    SqlCommand cmd = null;
    SqlConnection cnn = new SqlConnection(SqlHelper.connectionString()); 
    cnn.Open();
    string id = Request.Params["id"].ToString();
    string s = Request.Params["s"].ToString(); 


    if (s == "s")
    {
        sSQL = "SELECT ImageSmall FROM Images WHERE ImageId=" + id.ToString();
    }
    else
    {
        sSQL = "SELECT ImageLarge FROM Images WHERE ImageId=" + id.ToString();
    } 
    //try
    //{
        using (cmd = new SqlCommand())
        {
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = sSQL;
            cmd.Connection = cnn;
            drData = cmd.ExecuteReader(); 
            if (drData.Read())
            { 
            if (s == "s")
            {
                Response.BinaryWrite((byte[])drData["ImageSmall"]);
            }
            else
            {
                Response.BinaryWrite((byte[])drData["ImageLarge"]);
            }
        }
        cnn.Close();
    } 
//}
//catch { }
}

用户可以通过“添加新图像”按钮向照片集添加新图像。要将图像保存到数据库,它们首先被读取到字节数组中。

len1 = File1.PostedFile.ContentLength;
imageSmall = new byte[len1];
imageLarge = new byte[len1];
File1.PostedFile.InputStream.Read(imageLarge, 0, len1);

在保存到数据库之前,将上传的图像调整到所需的尺寸。

imageSmall = ImageClass.ResizeImage(250, imageLarge);
imageLarge = ImageClass.ResizeImage(250, imageLarge);
public static byte[] ResizeImage(int newWidth, byte[] pictureBytes)
{
    Bitmap b = (Bitmap)Bitmap.FromStream(new MemoryStream(pictureBytes));
    int imageWidth = b.Width;
    int imageHeight = b.Height;  
    double newHeightD = Convert.ToDouble(newWidth) / 
           Convert.ToDouble(imageWidth) * Convert.ToDouble(imageHeight);
    int newHeight = Convert.ToInt32(newHeightD);
    Bitmap output = new Bitmap(b, new Size(newWidth, newHeight));
    MemoryStream ms = new MemoryStream();
    output.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
    byte[] bmpBytes = ms.GetBuffer();
    output.Dispose();
    ms.Close();

    return bmpBytes;
}

可以在 http://www.realproject.ca/default.aspx?contentid=1660 处查看在线示例。

© . All rights reserved.