Customize the SharePoint Upload Page

On a recent project I needed to disable the ‘overwrite existing files’ or ‘add as new version to existing files’ option on the document library upload page. I did a lot of searching and found many articles stating how to modify the Upload.aspx file directly in the SharePoint root to make the change effective on the entire server, but in my situation I just wanted to make the changes take effect on only a certain list.

I decided to create a solution that would allow users to customize the upload page on a library-by-library basis. The solution would consist of:

  1.  A Custom Action to add a link on the Library Settings page that would allows user to customize the library’s Upload Page.
  2. An Application Page that would allow users to set properties on the Library’s RootFolder to control how the Upload page should be customized.
  3. A Custom Upload page, inheriting from the SharePoint Upload page, that would modify its controls based on the properties of the Library’s Root Folder.
  4. A Feature Receiver that would set the CustomUploadPage property of the SPWeb to the page created in Step 3.

Adding the Link on the Library Settings Page

To add the link to the library settings page, I created a new feature and added the following to the Elements.xml file:

<CustomAction Description="Customize the upload.aspx file for a document library"
RegistrationType="List"
RegistrationId="101"
GroupId="Permissions"
Id="05511583-fb44-4eca-817a-45892250da9e"
Location="Microsoft.SharePoint.ListEdit"
Sequence="1000"
Title="Customize Upload Form (RGove)"
>
<UrlAction Url="~site/_layouts/RGove.CustomUpload/SetCustomUploadProperties.aspx?List={ListId}" />
</CustomAction>

Creating the Application Page

Next, I created a new Application Page and changed it to inherit from Microsoft.Sharepoint.ApplicationPages.ListPageBase. ListPageBase takes care of getting the SPList object based on using the List={ListId}” parameter in the query string. Many of the pages linked to from the list/library settings page inherit from ListPageBase. All I needed to do to utilize it is put the ListID in the query string and the SPList object was created for me by the ListPageBase base class. To use this base class I needed to add a reference to Microsoft.SharePoint.ApplicationPages to my application. This dll can be found in c:\inetpub\virtualdirectories\_app_bin.

The SetCustomUploadProperties page allows the user to set three properties in the PropertyBag of the root folder of the document library :

  • RGoveCustomUpload.UncheckOverwrite — cauases the Overwrite Existing Files (ot the ‘Add as new version to Existing File’ if versioning is enabled) checkbox to be unchecked when the page displays.
  • RGoveCustomUpload.DisallowUserOverrride — Disables the Overwrite Existing Files checkbox so that the user cannot change its value
  • RGoveCustomUpload.HideUploadMultiple– Hides the Upload Multiple Files link

The PageLoad just checks the boxes on the page if the correspoomding property is found in the Lists Rootfolder Properties:

if (List.RootFolder.Properties.ContainsKey("RGoveCustomUpload.UncheckOverwrite"))
{
InputFormCheckBoxUncheckOverwrite.Checked = true;
}
else
{
InputFormCheckBoxUncheckOverwrite.Checked = false;
}

When the user clicks the Save button, the event handler sets the the correspoomding property in the List’s Rootfolder

if (InputFormCheckBoxHideUploadMultiple.Checked)
{
if (!List.RootFolder.Properties.ContainsKey("RGoveCustomUpload.HideUploadMultiple"))
{
List.RootFolder.Properties.Add("RGoveCustomUpload.HideUploadMultiple", true);
}
}
else
{
if (List.RootFolder.Properties.ContainsKey("RGoveCustomUpload.HideUploadMultiple"))
{
List.RootFolder.Properties.Remove("RGoveCustomUpload.HideUploadMultiple");
}
}

Creating the Custom Upload Page

Next, I created a new Application Page called CustomUpload.aspx that inherits from the SharePoint upload page Microsoft.SharePoint.ApplicationPages.UploadPage. I copied the aspx code from the upload.aspx file in the layouts directory. It is important to note that after I copied content of the SharePoint Upload.aspx to my CustomUpload.aspx, Visual Studio took all the fields from the aspx code and added them to CustonUpload.aspx.designer.cs as protected fields. This caused the SharePoint Upload.aspx from which I was inheriting, not to be able to access them. I removed all the field declarations from the designer.cs file to fix this.

The CustomUpload page gets the values of the custom properties on the root folder and updates the corresponding fields on the page accordingly.

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (CurrentList.RootFolder.Properties.ContainsKey("RGoveCustomUpload.UncheckOverwrite"))
{
this.OverwriteSingle.Checked = false;
this.OverwriteMultiple.Checked = false;
}
else
{
this.OverwriteSingle.Checked = true;
this.OverwriteMultiple.Checked = true;
}
if (CurrentList.RootFolder.Properties.ContainsKey("RGoveCustomUpload.DisallowUserOverrride"))
{
this.OverwriteSingle.Enabled = false;
this.OverwriteMultiple.Enabled = false;
}
else
{
this.OverwriteSingle.Enabled = true;
this.OverwriteMultiple.Enabled = true;
}
if (CurrentList.RootFolder.Properties.ContainsKey("RGoveCustomUpload.HideUploadMultiple"))
{
this.UploadMultipleLink.Visible = false;
}
else
{
this.UploadMultipleLink.Visible = true;
}
}

On my initial attempts at this, things seemed to work, in that the customupload page would hide the appropriate fields on the upload form, but when I tried to upload a document, nothing would happen. The page would refresh, but no document was uploaded.

I looked at Microsoft.SharePoint.ApplicationPages.UploadPage and saw that it had code in the Pre-init event that checked if the web had a custom upload page defined and, if so, redirect to that custom upload page. So on my CustomUpload page, when I clicked the upload button, the click event went to the standard upload.aspx page, which then did a server.transfer to my custom upload.aspx page.

To fix this I overrode the PreInit method of the CustomUpload page and,if it was being transgered to, had it redirect back to itself:

protected override void OnPreInit(EventArgs e)
{
// If The SharePoint Upload.aspx page's preInit did a server.transfer to this page the postbacks wont work.
// We need to redirect to this page to get the postbacks working.
if (Page.Request.Url.PathAndQuery.StartsWith("/_layouts/Upload.aspx?"))
{
string newUrlString = Request.Url.ToString().Replace("/_layouts/Upload.aspx?", SPContext.Current.Web.Url + "/_layouts/CustomUpload.aspx?");
var newUri = new Uri(newUrlString);Response.Redirect(newUri.PathAndQuery);
}
base.customPage = true; // this will stop the base(Upload.aspx) pre-init from redirecting again.
base.OnPreInit(e);
}

Creating the Feature Receiver

Finally, I added a feature Receiver to the Feature. int the FeatureActivated event I set the CustomUploadPage on the SPWeb to the CustomUpload page I created above.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPWeb web = properties.Feature.Parent as SPWeb;
web.CustomUploadPage = "/_layouts/CustomUpload.aspx";
web.Update();
}
catch (Exception ex)
{
LogException(ex);
throw;
}
}

The full sourcecode for the project, as well as an installable WSP can be found at http://spcustomupload.codeplex.com.

After packaging the solution in Visual Studio(or downloading thewsp from codeplex), the solution can be deployed with the following powershell script:

$url=”http://yoursiteurl
$solutionPath=”c:\pathtoyourwsp\Rgove.Customupload.wsp”

Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

Write-Host ‘Going to add solution’
Add-SPSolution $solutionPath
 
Write-Host ‘Going to install solution to all web applications’
Install-SPSolution –identity $solutionName  –GACDeployment

Leave comments at https://yetanothersharepointblog.wordpress.com/

Additional Information can be found on  MSDN here.

Note that disabling the allow overwrite check box will not neccesarily stop all users from overwriting files. They could open the library in Explorer mode, or use other Webdav enabled tools to overwrite the file. If you want to prevent file overwrites from these other methods, you will need to also enable in-place records management!

Advertisements
This entry was posted in sharepoint. Bookmark the permalink.

11 Responses to Customize the SharePoint Upload Page

  1. Leo Middendorp says:

    I really like this approach but I see this is for SP2010.
    Can this be adapted to work for SP2007 as well?

    A client needs this for a 2007 site where external parties shouldn’t be able to upload multiple files at once.

    I am a SharePoint technical adminstrator so I have no developer tools available so any hints or tips (other than ‘upgrade to SP201X’) or a MOSS2007 WSP are welcome!

    Regards, Leo

    • russgove says:

      Leo,
      The way the uploadpage works has changed between 2007 and 2010 (in 2010 they added the SPWeb.CustomUploadPage property) so this solution probably won’t work there without some modification.

      The article at http://msdn.microsoft.com/en-us/library/cc713554.aspx describes how to do this in 2007 but that does require develer tools.

      You could edit the UploadPage.aspx in the layouts directory to hide the overwrite checkbox, but that would be unsupported. You could even put some javascript in there to hide it based on the url and maybe use SPServices to see if the loged on user was in a certain Sharepoint group so that you could hide it based on the user.
      Russell

  2. aissamk2000 says:

    hello,
    I download the wsp and I deployed it the problem I can’t see the customize upload in permission management is there something to change it in the code before deploying.
    thanks

  3. aissamk2000 says:

    Hello,
    I have an other problem, I don’t have the option when I want to upload the document in folder.
    the folder path don’t showing in the upload page.

    thanks,

  4. saru says:

    Hello,

    I have deployed this to my test site. If i upload duplicate file with option “Add as new version to existing files” unchecked, it does not throw me a message “file already exists” and it uploads the file successfully. with OOTB upload.aspx, it throws message “File already exists”.

    Can you please let me know how to validate the duplicate file?

    Thanks

  5. Denis Renam says:

    Hi, I was reading your article, I wonder being can help me with a problem I’m having?

    I need to put the Upload.aspx and EditForm.aspx in a single page. Forcing my user to upload the document and fill in the information in the first place.

    Have you ever done something like that?

    att,
    Denis Renam

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s