Sunday, March 11, 2012

AJAX slideshow - trouble with web service

Hi:

for the first questil, I don't see any code, so no help.

For the 2nd, meetSystem.IO namespace, that's your new friend. Specially the Directory.GetDirectories & DirectoryInfo.GetFileSystemInfos.

With those guys you can list whatever you have inside the directories.


Cool - I'll give that a shot. As for the 1st Q:

This will be a long post :-(

Here's the inline web service (this is placed right in the aspx markup):

<scriptrunat="Server"type="text/C#">

[System.Web.Services.WebMethod]

[System.Web.Script.Services.ScriptMethod]

publicstatic AjaxControlToolkit.Slide[]GetSlides()

{

AjaxControlToolkit.Slide[] slides =new AjaxControlToolkit.Slide[5];

slides[0] =new AjaxControlToolkit.Slide("Images/Courmayeur/Geneva/Geneva00.jpg","","");

slides[1] =new AjaxControlToolkit.Slide("Images/Courmayeur/Geneva/Geneva01.jpg","","");

slides[2] =new AjaxControlToolkit.Slide("Images/Courmayeur/Geneva/Geneva02.jpg","","");

slides[3] =new AjaxControlToolkit.Slide("Images/Courmayeur/Geneva/Geneva03.jpg","","");

slides[4] =new AjaxControlToolkit.Slide("Images/Courmayeur/Geneva/Geneva04.jpg","","");

return (slides);

}

</script>

(Imagine trying to do the above for 50 pictures times 6 pages times 9 trips!)

and here's the AJAX tool for displaying the slide show:

<cc1:SlideShowExtenderID="SlideShowExtender1"

AutoPlay="true"

ImageDescriptionLabelID="lblImageDescription"

Loop="true"

NextButtonID="Btn_Next"

PlayButtonID="Btn_Play"

PlayButtonText="Play"

PreviousButtonID="Btn_Previous"

SlideShowServiceMethod="GetSlides"

StopButtonText="Stop"

TargetControlID="IMG_SlideShow"

runat="server">

</cc1:SlideShowExtender>

I rt click on my website project in VS 2005 pro and add a web service to it. I then copy the inline web service code to the newly created web service (making the necessary changes - like adding this:

[System.Web.Script.Services.ScriptService()]

and changing this (from the aspx markup):

[System.Web.Services.WebMethod]

to:

just a plain old [WebMethod] though that shouldn't matter (I think)

I then add this to the AJAX control:

SlideShowServicePath="pathToThe_asmx_FileHere";

The page displays but I get an error message in the form of an alert saying this:

SlideShowServiceMethod="GetSlides"can't be found.

I'm thinking somehow that if I put this method in it's own web service then I can call from from multiple pages. Maybe add a string property in the from of the folder path to hold the path of the folder needed by the calling page.

Hope you can help!


Thank you very much! (for the answer to question 1):

string b = Server.MapPath("~/Images/Courmayeur/Cervinia");

string[] a =Directory.GetFiles(b);

All I need now is to figure out how to get the web service out of the aspx markup and into a stand alone web service (in the runtime) - so I can put those two statements to good use. I figure I can set 'a' to a property in the web service and use it to populate the arguments to the AjaxControlToolkit.Slide call.


Hi there!

I think I may have done what you're looknig for, but I am not entirely sure what you want.

Do you want to use the ASP.NET slideshow "as is", with the buttons, or just have an ASP.NET AJAX slideshow go through a directory full of pictures?
If it's the second, then I have exactly what you want, and it works perfectly with VWD 2005 Orcas, only since installing VWD 2008 Beta 2 it's broken!

Let me know if that's what you want, and I'll post the source!

Cheers!

Kelsey Thornton

p.s. My site's in VB, not C#, but I am sure you should be able to convert it...


Hi Kelsey,

Please do!

I'm always willing to learn something new.

Thanks Pat


OK - Prepare for a LONG post! :)
(this is a copy of a message I posted on the htmlforums athttp://www.htmlforums.com/asp-and-aspnet/t-need-slide-show-91896.html)

Source code for your ASPX web form:

<%@. Page Language="VB" MasterPageFile="Blue2.master" Title="Untitled Page" %><%@. ImportNamespace="System" %><%@. ImportNamespace="System.IO" %><%@. ImportNamespace="System.Web.UI" %><script runat="server">' ' Author: Kelsey Thornton ' KelseyNL(at)Orange.nl ' ' You can use this script and page layout in any manner ' so long as the author's name, email address and this ' disclaimer are kept intact. ' ***************************************************** ' Page displays a slideshow of all images in a subdirectory ' Default time for refresh is 5 seconds (5000 milliseconds) ' I've deliberately used a (hidden) list box so that you can ' easily map the datasource to, for examlpe, a database where ' your picture names are stored. ' Usage: ' Create an AJAX-enabled website. ' Copy this form in the root of the site ' (If desired) change the timer setting to make it refresh faster or slower ' Create a directory called "Images" and populate it with (JPG) images. ' Assign your own stylesheet, master page layout etc. ' View the page in your browser, sit back and enjoy your slideshow!Protected Sub Page_Load(ByVal senderAs Object,ByVal eAs System.EventArgs)'initialise some variables we're going to need.Dim files()As String Dim indexAs Integer If Not Page.IsPostBackThen'Get list of files for using in diashow files = Directory.GetFiles(Server.MapPath("./images"),"*.jpg")'remove any path nameFor index = 0To files.Length - 1 files(index) =New FileInfo(files(index)).NameNext index'bind list to dropdown box lstFiles.DataSource = files lstFiles.DataBind()'select 1st item in list to prevent prroblems with null array references lstFiles.SelectedIndex = 0End If' if list databound is to a database, then you should probably ' remove the "images/" bit here imgShow.ImageUrl ="images/" + lstFiles.SelectedItem.Text' Label telling the viewer what file is being shown ' (could also be linked to a database!) imgLabel.Text = lstFiles.SelectedItem.TextEnd Sub Protected Sub lstFiles_SelectedIndexChanged(ByVal senderAs Object,ByVal eAs System.EventArgs) imgShow.ImageUrl = lstFiles.SelectedItem.TextEnd Sub Public updateAs Boolean =False Protected Sub Timer1_Tick(ByVal senderAs Object,ByVal eAs System.EventArgs)Handles Timer1.TickIf update =True Then If lstFiles.SelectedIndex < lstFiles.Items.Count - 1Then lstFiles.SelectedIndex = lstFiles.SelectedIndex + 1Else lstFiles.SelectedIndex = 0End If End If update =Not updateEnd Sub</script> <asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"> <h2 style="text-align: center"> Slide Show</h2> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <div align="center"> <asp:Image ID="imgShow" AlternateText="" ImageUrl="" runat="server" Height="85%" /> <br /> <asp:Label ID="imgLabel" runat="server" Text="Label" Style="text-align: center"></asp:Label> <br /> <asp:ListBox ID="lstFiles" runat="server" Rows="6" OnSelectedIndexChanged="lstFiles_SelectedIndexChanged" AutoPostBack="True" Visible="False"></asp:ListBox> </div> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" /> </Triggers> </asp:UpdatePanel> <asp:Timer ID="Timer1" runat="server" Interval="5000" OnTick="Timer1_Tick"> </asp:Timer></asp:Content>

... and now the master page that sits behind it...

<%@. Master Language="VB" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"></script><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Slideshow</title> <asp:ContentPlaceHolder ID="HeaderTags" runat="server"> </asp:ContentPlaceHolder></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%"> <tr> <td style="height: 4px"> <h1 style="text-align: center"> <asp:ContentPlaceHolder ID="Header" runat="server"> </asp:ContentPlaceHolder> </h1> </td> </tr> <tr> <td style="height: 376px; vertical-align: top"> <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </td> </tr> </table> </div> </form></body></html>
hope this helps! :)

Just realised...

That was the version *before* I AJAXified the page...
Here's the version *after* AJAXifying:

(thinking about it, this probably also answers your question about putting the extender in-line, as I had to create a local class to put all the data into before this wouild work on more than one page at a tme!)

Main ASPX file:

<%@. Page Language="VB" MasterPageFile="~/Fotos.master" AutoEventWireup="false" CodeFile="Dia_FvanPoppel.aspx.vb"Inherits="Fotos_Der_Bettelstudent" Title="Untitled Page" %><%@. RegisterAssembly="AjaxControlToolkit"Namespace="AjaxControlToolkit" TagPrefix="cc1" %><asp:Content ID="Content1" ContentPlaceHolderID="HeaderTags" runat="Server"></asp:Content><asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div style="text-align:center"> <h2> Diavoorstelling - Der Bettelstudent</h2> <div style="text-align: center"> Helaas, op het moment, werken de diavoorstellingen niet</div> <div style="text-align:center"> <asp:Image ID="imgShow" AlternateText="Der Bettelstudent" ImageUrl="~/Fotos/FvanPoppel/images/baronieoperette2007001.jpg" runat="server" /> <br /> <asp:Label ID="imageLabel1" runat="server" Text="baronieoperette2007001" Style="text-align: center"></asp:Label> <cc1:SlideShowExtender ID="slideshowextend1" runat="server" TargetControlID="imgShow" SlideShowServiceMethod="GetPictures" AutoPlay="true" ImageDescriptionLabelID="imageLabel1"Loop="true" /> <asp:Label ID="lblError" runat="server" /> <br /> </div> </div></asp:Content>

CodeBehind file:

Imports System.IO

PartialClass Fotos_Der_Bettelstudent
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal senderAs Object,ByVal eAs System.EventArgs)Handles Me.Load
MyData.ImagePath = Server.MapPath("./Images")
Dim strUrlAs String = Request.Url.ToString

MyData.Url = strUrl.Substring(0, strUrl.LastIndexOf("/")) &"/Images/"
End Sub

<System.Web.Services.WebMethod()> _
<System.Web.Script.Services.ScriptMethod()> _
Public Shared Function GetPictures()As AjaxControlToolkit.Slide()
Dim diAs New DirectoryInfo(MyData.ImagePath)
Dim s(di.GetFiles.Length - 1)As AjaxControlToolkit.Slide
Dim xAs Integer = 0
For Each fiAs FileInfoIn di.GetFiles()
s(x) =New AjaxControlToolkit.Slide(MyData.Url & fi.Name,"", Path.GetFileNameWithoutExtension(fi.Name))
x += 1
Next
Return s
End Function

Protected Class MyData
Private Shared _PathAs String
Private Shared _UrlAs String

Public Shared Property ImagePath()As String
Get
Return _Path
End Get
Set(ByVal valueAs String)
_Path = value
End Set
End Property

Public Shared Property Url()As String
Get
Return _Url
End Get
Set(ByVal valueAs String)
_Url = value
End Set
End Property
End Class
End Class

I'm sure you can work out the master file, and what to change for your own application!


Kelsey,

Thank you for the code. When I was going through it it got me to thinking about the original problem for this post:

How to get the inline AJAX web service into a stand alone web service that can be called from many pages. Here's what the problem was:

publicstatic AjaxControlToolkit.Slide[]GetSlides()

Apparently you can't expose web service methods that are declared as static. I removed 'static' and called the web service with this call from the SlideShowExtender:

SlideShowServicePath="WebService.asmx"

Works now! Now all I have to do is create a method in the ws to set a string property in the web service to hold the path to whatever folder full of pics I'm want to display and use something like this:

string[] a =Directory.GetFiles(Server.MapPath("Property"));

and a then foreach statement to populate the argument to this:

slides[counter] =new AjaxControlToolkit.Slide(a[counter]);

So thanks again! Anyone who doesn a search on this problem and lands here will get two solutions!


Hi again...

I think that problem was what I bounced on, before creating the private (protected) class to hold the data. This solved the problem of having to use a "global" GetSlides method.

The way I eventually used was to use a private class. I can simply cut and paste this page in any directory containing the relevant sub-directories with images and it just works! :)

(btw - if you mark the relevant message with "answer", then I get some kudos - or is that on the other forum?) :)


Now all I have to do is create a method in the ws to set a string property in the web service to hold the path to whatever folder full of pics I'm want to display and use something like this:

Nope. I had been meaning to post this. The slideshow extender has a parameter in the aspx markup called the context key. You can use that to send the path to the web service.

One thing you have to do though is strip off the unnecessary path info using lastindexof and remove after the call to Directory.GetFiles. The full path won't be accepted as an argument to AjaxControlToolkit.Slide.

Good Luck

Pat


Thanks for the info!
When I eventually get my sites back working again I'll have a look at this!

No comments:

Post a Comment