views:

38

answers:

2

've programmatically created a listview, for displaying images. When you click on the download the ItemCommand is fired, and the browser sends the user the image as a binary response, using the following:

SPFile ImageIfile = spfolder.Files[ServerName];
byte[] bs = ImageIfile.OpenBinary();
string res = Page.Response.ContentType;
Page.Response.ContentType = "image/jpeg";
Page.Response.AppendHeader("Content-Disposition", "attachment; filename=" +  Path.GetFileName(fileName))
Page.Response.BinaryWrite(bs);
Page.Response.End();

This works, exactly once. Then neither the download link, nor the DataPage paging controls work until you refresh (Indeed any postbacks).

EDIT: It's a SharePoint 2007 WebPart, this is the declaration of the ListView in the CreateChildControls method:

lv.ItemPlaceholderID = "itemPlaceholder";
lv.GroupPlaceholderID = "groupPlaceholder";
lv.ID = "MediaSearch";
lv.LayoutTemplate = new LayoutTemplate(); 
lv.GroupTemplate = new GroupTemplate(); 
lv.GroupItemCount = 4;
lv.ItemTemplate = new ItemTemplate(); 
lv.EmptyDataTemplate = this.Page.LoadTemplate("/usercontrols/MediaResults_Empty.ascx");

And this is the ItemTemplate and DataBinding

public class ItemTemplate : ITemplate
{
   public void InstantiateIn(Control container)
   {
       //Top bit
       Panel ItemPanel = new Panel();
       ItemPanel.ID = "itemPlaceholder";
       ItemPanel.Attributes["class"] = "mlitem";
       var thumbdiv = new HtmlGenericControl("div");
       thumbdiv.Attributes["class"] = "thumb-image";
       HyperLink aspLink = new HyperLink();
       aspLink.ID = "hlPicPreview";
       aspLink.Attributes["class"]="picture-preview";
       Image aspImg = new Image();
       aspImg.ID = "thumb";

       aspLink.Controls.Add(aspImg);
       thumbdiv.Controls.Add(aspLink);
       ItemPanel.Controls.Add(thumbdiv);

       //Bottom bit
       var bDiv = new HtmlGenericControl("div");
       bDiv.Attributes["class"] = "details";
       var UnOrderedList = new HtmlGenericControl("ul");
       var li1 = new HtmlGenericControl("li");
       Literal lit = new Literal();
       lit.ID = "liSize";
       lit.Text = "Size";
       li1.Controls.Add(lit);
       var li2 = new HtmlGenericControl("li");
       LinkButton down = new LinkButton();
       down.ID = "lbDownload";
       down.CommandArgument = "Pugs";
       down.CommandName = "Download";
       down.Text = "Download";
       li2.Controls.Add(down);
       UnOrderedList.Controls.Add(li1);
       UnOrderedList.Controls.Add(li2);
       bDiv.Controls.Add(UnOrderedList);

       ItemPanel.Controls.Add(bDiv);
       ItemPanel.DataBinding += new EventHandler(ItemPanel_DataBinding);
       container.Controls.Add(ItemPanel);
   }

   void ItemPanel_DataBinding(object sender, EventArgs e)
   {
       Panel ThePanel = (Panel)sender;
       //Get bindables
       Image thumb = ThePanel.FindControl("thumb") as Image;
       LinkButton lbdown = ThePanel.FindControl("lbDownload") as LinkButton;
       ListViewDataItem lvdi = (ListViewDataItem)ThePanel.NamingContainer;

       //Bind that stuff.
       lbdown.CommandArgument = ((DataRowView)lvdi.DataItem)["URL"].ToString();
       thumb.ImageUrl = "~/" + ((DataRowView)lvdi.DataItem)["ThumbsNailsImg"].ToString();
   }

I more than a little stumped here. AJAX is enabled on the site, but not being used in this control.

A: 

Hi OneHorse

What you're running into is SharePoint trying to be clever. When a Web site it slow (and this can happen even when running SharePoint) users tend to push buttons/links multiple times, which isn't going to make things faster and may cause trouble as events are fired twice. So SharePoint is by default disabling multiple postbacks.

The fix for this can be found in almost any article about using AJAX with SharePoint. Look for the EnsurePanelFix function which you should implement and call in the code showing the listview.

Per Jakobsen
Thanks, but my control doesn't use an Update panel, and EnsurePanelFix didn't do anything other than make my Telerik Dropdown box disappear! I'll edit my question to show more of the structure of the control.
A: 

The problem was nothing to do with the listview or even SharePoint(for once). I was using the itemCommand method, which is a postback, so when the postback is being processed my code suddenly hijacks the HTTP response then changes the output to a image type and adds an attachment header. This means that the asp.net can no longer process the stream as it would usually. solution: I made the download link a standard anchor tag, pointing to a httpHandler that solves that issue.