Wesley Bakker

Interesting things I encounter doing my job...

Sponsors

News

Wesley Bakker
motion10
Rivium Quadrant 151
2909 LC Capelle aan den IJssel
Region of Rotterdam
The Netherlands
Phone: +31 10 2351035

(feel free to chat with me)

Add to Technorati Favorites

DownloadAsZip SharePoint Feature RTW

I have to admit. I am late! Much to late! I promised you all a DownloadAsZip feature for SharePoint in a few days and it took me more than a month. But finally it’s here. First have a look at what it’s actually all about.

A picture says so much more

Hover the images for explanation…

Open a document library Apply some filtering Enable item selection Select the items to download Start the download Save the file Watch it complete The result looks like this

 

 

 

 

 

 

 

How did we get to this result?

I’ve explained how to create the multi select button and how to create the download handler in two previous posts. So now I’m going to focus on the last part. The ‘DownloadAsZip’ buttons.

Easy peasy

Let’s start with the easiest part. With the handler in place we can add custom actions to list items simply by adding some CustomAction elements to our Elements manifest file. Here’s what the elements.xml looks like:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  ...
  <CustomAction
    Id="{18A0608F-7917-4fa3-8164-18E81B55A551}"
    ImageUrl="/_layouts/images/ICZIP.GIF"
    Title="Download as Zip"
    Description="Download all files in this folder and view as one zip"
    RegistrationType="ContentType"
    RegistrationId="0x0120"
    Location="EditControlBlock">
    <UrlAction Url="{SiteUrl}/_layouts/DownloadAsZip.ashx?List={ListId}&amp;Item={ItemId}" />
  </CustomAction>
  <CustomAction
    Id="{175D475D-C962-4965-9C9B-7CAFBB36A669}"
    ImageUrl="/_layouts/images/ICZIP.GIF"
    Title="Download as Zip"
    Description="Download this file as zip"
    RegistrationType="ContentType"
    RegistrationId="0x0101"
    Location="EditControlBlock">
    <UrlAction Url="{SiteUrl}/_layouts/DownloadAsZip.ashx?List={ListId}&amp;Item={ItemId}" />
  </CustomAction>
</Elements>

What this fragment does is that it adds two buttons to the edit control block. One for files (RegistrationId=”0x0101”) and one for folders (RegistrationId=”0x0120”). These custom actions simply redirect the client to the previously created DownloadAsZip.ashx with the correct query string values.

So this adds single item DownloadAsZip functionality to our SharePoint site.

singledownload

Little bit more difficult

The code for the DownloadAsZip button on the ListView level is somewhat more difficult but still not to complicated. The code looks like this:

//-----------------------------------------------------------------------
// <copyright file="DownloadAsZipAction.cs" company="motion10">
//     Copyright (c) motion10. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
 
using System.Globalization;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
 
namespace Motion10.SharePoint2007 {
    public class DownloadAsZipAction : MenuItemTemplate {
        /// <summary>
        /// Initializes a new instance of the <see cref="DownloadViewAsZipAction"/> class.
        /// </summary>
        public DownloadAsZipAction()
            : base("Download as Zip", "/_layouts/images/ICZIP.GIF") {
            base.Description = "Download selected files or complete view if no items selected.";
        }
 
        /// <summary>
        /// Sends the content of the control to the specified <see cref="T:System.Web.UI.HtmlTextWriter"></see> object, which writes the content that is rendered on the client.
        /// </summary>
        /// <param name="output">The HtmlTextWriter object that receives the server control content.</param>
        [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel=true)]
        protected override void Render(System.Web.UI.HtmlTextWriter output) {
            ListViewWebPart listViewWebPart = FindListView(this.Parent);
            if (listViewWebPart == null) {
                this.Visible = false;
            }
 
            if (this.Visible) {
                string navigateUrl = string.Format(CultureInfo.InvariantCulture,
                                                   "{0}/_layouts/DownloadAsZip.ashx?List={1}&View={2}&Item=",
                                                   SPContext.Current.Web.Url,
                                                   listViewWebPart.ListName,
                                                   listViewWebPart.ViewGuid);
 
                string clientClick = string.Format(CultureInfo.InvariantCulture,
                                                   "window.location = '{0}' + GetSelectedItemsString('WebPart{1}')",
                                                   navigateUrl,
                                                   listViewWebPart.Qualifier);
 
                this.ClientOnClickScript = clientClick;
            }
 
            base.Render(output);
        }
 
        protected ListViewWebPart FindListView(Control parent) {
            ListViewWebPart retVal = parent as ListViewWebPart;
            if (retVal != null) {
                return retVal;
            }
 
            if (parent.Parent == null) return null;
 
            return FindListView(parent.Parent);
        }
    }
}

The code is pretty straightforward. We create a class that inherits the MenuItemTemplate class and we change the ClientOnClickScript property in the render method. What the result of this is, is that client will be redirected to the DownloadAsZip.ashx with the selected items in the querystring. The javascript is explained in one of the previous posts.

To add this button to the ListView we need to adjust our elements.xml a little. We actually add two more CustomAction elements in there.

<CustomAction
  Id="{DE394AD0-0A8E-4e5c-B246-A498BA2A7FB2}"
  Title="Download as Zip"
  RegistrationType="List"
  RegistrationId="101"
  Location="Microsoft.SharePoint.StandardMenu"
  GroupId="ActionsMenu"
  ControlAssembly="SharePointSolutionPack, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4a7cd02bdf107f7a"
  ControlClass="Motion10.SharePoint2007.DownloadAsZipAction">
</CustomAction>
<CustomAction
  Id="{CB4BE13C-C095-4a02-B875-787325045759}"
  Title="Enable item selection"
  RegistrationType="List"
  RegistrationId="101"
  Location="Microsoft.SharePoint.StandardMenu"
  GroupId="ActionsMenu"
  ControlAssembly="SharePointSolutionPack, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4a7cd02bdf107f7a"
  ControlClass="Motion10.SharePoint2007.SelectItemsAction">
</CustomAction>

The second one is to add the ‘Enable item selection’ button and the first one to add the ‘Download as Zip’ button. Pay attention to the RegistrationId again. We add this button only to lists that inherit from the Document Library.

Wrapping it up

Well if you read all of the posts you’ve noticed that this is a pretty complex feature. We have a dependency on the jQuery feature. A lot of JavaScript. A custom HttpHandler etc. etc.

If you don’t know how to create solution packages yourself. Or if you don’t have the time to read all posts and create your own packages you can download the motion10 SharePoint Solution Pack.  I’ve updated the Share Point Solution Pack to contain all these and and some more features.

!Please be smart and test the solution package in a test environment!

Cheers and have fun,

Wes

Comments

Twitted by mysharepoint said:

Pingback from  Twitted by mysharepoint

# April 28, 2009 3:34 AM

James said:

Sorry for the inane noob question, I installed the wonderful Solution Pack you have built.

Except I am having a problem getting it running up in my test environment, I have run the executable on my sharepoint server it has gone through it's steps and completed successfully, I can see it in the Central Admin as deployed but can't see it in the site features for the site i deployed it too, nor any of the doc libs or lists have the functionality from the pack. (yes I did an iisreset as well)

# May 5, 2009 1:52 AM

webbes said:

@James: It is a site collection scoped feature. So you should take a look at Site Collection Features instead of Site Features.

# May 5, 2009 3:55 AM

James said:

I posted a reply but it doesn't seem to have come up.

I found the entries in the Site Collection Features and enabled them thank you very much but most of the features are not working with an error being thrown in the Event Log of -

SafeControl load exception:SharePointSolutionPack, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4a7cd02bdf107f7a Exception: Could not load file or assembly 'Microsoft.SharePoint.ApplicationPages.Administration, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.

# May 11, 2009 5:06 AM

webbes said:

Do you have MOSS2007 installed? And if so... what Service Pack. Because at both my development servers the dll is there in "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG\ADMINBIN\Microsoft.SharePoint.ApplicationPages.Administration.dll"

Cheers,

Wes

# May 11, 2009 5:56 AM

James said:

I have Service Pack 2 installed on my MOSS Enterprise 2007 server.

It was throwing the error for a few days then suddenly stopped, very bizarre, but thats microsoft for you, thank you for replying, I will keep you posted if it re-appears.

Cheers,

James

# May 22, 2009 7:51 AM

Antonio Ambrosio said:

Ciao Wesley,

the feature you made is really useful!

I istalled it without any issues.

I had some pages with document library web parts. In full view menu, unfortunately the select an download as zip feature is not available.

Is a problem of my installation or a limit of the feature?

Thanks

Best regards

Antonio

# May 31, 2009 7:02 AM

webbes said:

@Antonio: I expecting the 'download as zip' works on the default document libraries. You can make it work on the document library webpart. All you have to do is make sure it shows the title column with edit control block. Otherwise it's unpossible to get the item id and thus the item selection is disabled.

Cheers,

Wes

# June 2, 2009 3:45 AM

WERNER AUMAYR said:

wss3.0 engl with german language pack

installs OK

deleting multiple items throws above error

Why??

# June 7, 2009 9:18 AM

werner aumayr said:

Adding to my last comment: download as zip is working...

# June 7, 2009 9:27 AM

webbes said:

@Werner: I cannot see the error...

# June 7, 2009 2:42 PM

Werner Aumayr said:

1. window pops up correctly asking "do you really want..."

2. then Error page with:  File not found

# June 8, 2009 2:22 AM

Werner Aumayr said:

question to my problems could it be that your features need .net 3.5 framework to be installed??

# June 10, 2009 9:43 AM

slinger said:

Is there a way to leave the "select items" field enabled all of the time? I would like to eliminate the step of having to enable the select multiple items, select the items and then select to download.  I was hoping that instead of having to enable and disable the select items feature, that once activated it would always be available.

# August 12, 2009 4:27 PM

webbes said:

@slinger: Sure you can. Simply enable selection on page load with jQuery.

# August 20, 2009 8:15 AM

Multi-Select and Delete Items in a SharePoint List - SharePoint Blank - Bamboo Nation said:

Pingback from  Multi-Select and Delete Items in a SharePoint List - SharePoint Blank - Bamboo Nation

# September 2, 2009 5:15 PM

Mark van Dijk said:

I just wanted to thank you for this nice series of blog posts. It really helped me with something I had to develop for one of my clients!

# October 5, 2009 5:39 AM

Stjepan said:

Hi and thanks for a code explaining how to implement JIT zip using SharpZipLib. I also read your discussion (with the team of DotNetZip) about using DotNetZip instead of the above mentioned library because of license problems and I couldn't find any good example of using DotNetZip instead for that sake. You wrote that you should make an example of this when you have time, so I was wondering if you maybe allready did? If you didn't, could you give me some direction in this, so that I could try on my own?

My email is stjepan.karin@gmail.com

Thanks in advance!

# October 26, 2009 10:19 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)