Slide.Show Dynamic Images from Database (Solution)

May 20, 2008 at 9:56 PM
Edited May 21, 2008 at 2:00 PM
Hello,
 I was searching earlier and I couldnt really find my simple answer, "How do I get my images (their path) from the database?". So I will post my simple solution to help others. Im sure there are different ways to do this and better ways for performance. So, please comment on ways to improve the code below and not how much it sucks . . .lol. P.S.- This simple sample is for only one album, but can be very easily changed to handle more.

Keep in mind the database table Im using is very simple.
TABLE NAME: PHOTOS 
COLUMNS: ID, PATH, TITLE

1.) First this I would do is make sure you can get the Slide Show to work with static images like in the examples. But rather running it from the Sample Project, put it in your own project. It took a little for me to get the file structure correct to get it to work.

2.) You are going to create 2 HttpHandlers. Data.ashx and ImageHandler.ashx.

//-----------------------------------------------------------
//--------------------Data.ashx----------------------------
//-----------------------------------------------------------
<%@ WebHandler Language="C#" Class="Data" %>

using System;
using System.Web;
using System.Xml;
using System.Data;
using System.Collections.Generic;

public class Data : IHttpHandler {
   
    public void ProcessRequest (HttpContext context) {
        context.Response.Buffer = false;
        context.Response.Clear();
        context.Response.ContentType = "text/xml";

        using (XmlTextWriter writer = new XmlTextWriter(context.Response.Output))
        {
            writer.Formatting = Formatting.Indented;
            writer.WriteStartDocument();
            writer.WriteStartElement("data");
            writer.WriteAttributeString("transition", "CrossFadeTransition");
            writer.WriteStartElement("album");

            List<Photo> photos = DataProvider.GetPhotos();
            foreach (Photo p in photos)
            {
                writer.WriteStartElement("slide");
                writer.WriteAttributeString("title", p.Title);
                writer.WriteAttributeString("image", "ImageHandler.ashx?path=" + p.Path);
                writer.WriteEndElement();
            }

            writer.WriteEndDocument();
            writer.Flush();
        }
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }
}
  
//-----------------------------------------------------------
//------------Handler.ImageHandler----------------------
//-----------------------------------------------------------

<%@ WebHandler Language="C#" Class="Handler.ImageHandler" %>

using System;
using System.Web;
using System.IO;

namespace Handler
{
    public class ImageHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.QueryString["path"] != null)
            {
                string path = context.Server.MapPath("~/Images/" + context.Request.QueryString["path"]);
                context.Response.Clear();

                context.Response.ContentType = getContentType(path);
                context.Response.WriteFile(path);
                context.Response.End();
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        string getContentType(String path)
        {
            switch (Path.GetExtension(path))
            {
                case ".bmp": return "Image/bmp";
                case ".gif": return "Image/gif";
                case ".jpg": return "Image/jpeg";
                case ".png": return "Image/png";
                default: break;
            }
            return "";
        }
    }
}



3.) In your Configuration.xml file, add the following option to the dataProvider:
  <dataProvider type="XmlDataProvider">
    <option name="url" value="Data.ashx" />  
  </dataProvider>

4.)  (OPTIONAL) Create your photo class and dataprovider class. Photo class to hold the image data and dataprovider to get the database information. These go in the App_Code folder.
//-------------------------------------
// ------------- Photo Class---------
//-------------------------------------
public class Photo
{
    private int _id;
    public int ID { get { return _id; } set { _id = value; } }

    private string _path;
    public string Path { get { return _path; } set { _path = value; } }

    private string _title;
    public string Title { get { return _title; } set { _title = value; } }

    public Photo(int id, string path, string title)
    {
        this.ID = id;
        this.Path = path;
        this.Title = title;
    }
}


//-------------------------------------
// ------- DataProvider--------
//-------------------------------------
using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Data.SqlClient;

/// <summary>
/// Summary description for DataProvider
/// </summary>
public static class DataProvider
{
    public static List<Photo> GetPhotos()
    {
        List<Photo> list = new List<Photo>();

        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand("SELECT ID, PATH, TITLE FROM PHOTOS", conn))
            {
                conn.Open();
                using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                {
                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            list.Add(new Photo(Convert.ToInt32(reader["ID"]), reader["PATH"].ToString(), reader["TITLE"].ToString()));
                        }
                    }
                }
            }
        }
        return list;
    }
}


5.) Currently, the items I have in the same file directory are: Confirguration.xml, Data.ashx, Data.xml, Default.aspx (my test page), ImageHandler.aspx, SilverLight.js, SlideShow.js
     So these are all in the same directory. I was having problems at first getting it to work in my project, but these seemed to work. I have the Images in the 'Images' directory under the root. Like I mentioned before, get this sample working first with static images, then there will be little changes at the end relating to paths.

ALL DONE! You dont have to do any more modifications to the Default page. Simply like the example:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
        <script type="text/javascript" src="Silverlight.js"></script>
        <script type="text/javascript" src="SlideShow.js"></script>
</head>
<body>
        <script type="text/javascript">
            new SlideShow.Control(new SlideShow.XmlConfigProvider());
        </script>
</body>
</html>


HOPE THIS HELPS ANYONE LOOKING. PLEASE COMMENT ON THINGS THAT CAN BE IMPROVED BECAUSE THIS IS A QUICK EXAMPLE I THREW TOGETHER IN 15 MINS :) THANKS!
Jun 2, 2008 at 8:21 PM
Thanks for the post CSharpSean! This is exactly what I was looking for.

I tried out your example but I wasn't able to get it to work. Can you post a demo website so I can see exactly how it works and what I am missing?

Thanks,

Oran
Jun 6, 2008 at 10:24 AM

Hi

Thanks For the Post but My problem is slide different But i am sure if its Solve than many question will be answered.

I have seen the code now it will work in the sql data base but I want to configure the Data.XML that it takes the images from the Image Library in share point or it can generate dynamic Image from a folder where the Image is situated.

Please help if you have any Idea

Thanks

Mehfuz

Jun 28, 2008 at 10:41 PM
I noticed your post on the main page indicated you wanted to dynamically create your data.xml file.  You may be able to do that by creating a data.asmx file with .Net. Just a suggestion. Cheers! 
Jul 17, 2008 at 8:21 AM
Edited Jul 17, 2008 at 8:26 AM
I followed your solution, but when i start Slide.Show, i only get the first image. I even saved the resulting xml, and loaded it statically, and it works that way. What could be the problem?

Edit:
It looks like the problem is here: context.Response.Buffer = false;
I've set this property to True, and now it works.

Thanks
Aty
Aug 2, 2008 at 4:03 PM
Hi. I'm doing it like that but i get an error :AG_E_RUNTIME_METHOD : CreateFromXaml.
Any ideas?
Aug 19, 2008 at 9:32 AM
Edited Aug 19, 2008 at 9:43 AM
I tried your way and  it was ALMOST done....
BUT I got AG_E_NETWORK_ERROR when the Slide.Show tried to download image.
I checked the returned xml and it is alright.

Any ideas????
Sep 16, 2008 at 10:09 AM
Thanx a lot for your effort. It helped me a lot.
Oct 4, 2008 at 10:22 AM
This is really great.  I converted it to VB (http://www.carlosag.net/Tools/CodeTranslator/) and it worked straight off the bat.

Two ideas:

To use thumbnails add this line -  

writer.WriteAttributeString("thumbnail", "ImageHandler.ashx?path=" + p.ThumbPath);

To refer to a session variable for database queries etc, implement IRequiresSessionState -

Public

 

Class HttpHandlers : Implements IHttpHandler, IRequiresSessionState (in VB)

 

Clive Glover
Oct 14, 2008 at 4:23 PM
Edited Oct 14, 2008 at 4:24 PM
Well done, CSharpSean. Excellent work.   I love the generic handler.  I added a few extra methods to your code to implement  the idea of Albums, so the dataprovider class now can gets all or a few albums and then gets the photos for the album id.  I got rid of the second generic handler to speed things up a bit.  If anyone's interested, I will post the code. 

Best, Matt

ps. live sample

http://www.mattdunn.us/PhotoGallery00.aspx
Oct 15, 2008 at 8:10 PM
Awesome work.  Thanks for pointing me in the "write" direction.  One thing that I was able to put together between your work here and another discussion is that you can even pull the configuration file from an .ashx file which is nice if you need to pass parameters in that determine the data that is pulled

<script type="text/javascript">
    new SlideShow.Control(new SlideShow.XmlConfigProvider({ url: "SSConfig.ashx?sysid=1001050505" }));
</script
>

This generates the config which dynamically passes the querystring value into the data call :

<

 

dataProvider type="XmlDataProvider">
    <
option name="url" value="SSListingPics.ashx?sysid=1001050505" />
</
dataProvider>

 


Cheers, Kent

 



 

Oct 28, 2008 at 10:59 PM
mattdunn, That would be great if you would post the VB code that includes support for multiple albums. Thanks!
Nov 3, 2008 at 1:03 AM
Hey Kent,
can you elaborate a little more on what exactly you did there?
Thx - Marcus.
Nov 7, 2008 at 4:30 PM
Mattdunn,

Would appreciate it if can post the C# code that supports multipe albums. By the way, did you take a look at slide show 2 which is written in managed code.

Thanks,
Suresh
Nov 29, 2008 at 3:40 PM
Hi, 
 
it's a great example and works very well. 
Now after my control to load the images I had a bad quality of my images. 
I supposed that it happened because I don't load one image directly and yes from one handler. Anyone has idea how to solve it?

Thanks
Jan 21, 2009 at 6:09 PM
Hi Guys,

That's very good codes. What I'm trying to do now is displaying images saved in SQL Server database. So basically you retrieve byte[] from the database and you display that in the SlideShow. Does anyone have an idea how to do that?

Thanks