Second Life of a Hungarian SharePoint Geek

July 22, 2014

How to validate file names of attachments on SharePoint forms

Filed under: Attachments, jQuery, SP 2010 — Tags: , , — Peter Holpar @ 18:36

A few months ago I already posted a solution to check duplicated attachment names on SharePoint forms. Another common problem source are invalid file names.

For example, if you have a standard list item edit form, and would like to upload an attachment with invalid file name (for example, invalid characters or exceeding length limitation), on submitting the form you receive an exception. Despite of the error, the item itself is saved, however, if you appended other files (with valid names) as well, the ones you appended after the attachment having invalid name are not saved to the item.

The error message you receive if the file name contains invalid characters:

The file or folder name contains characters that are not permitted.  Please use a different name.<nativehr>0x81020073</nativehr><nativestack></nativestack>

The stack trace:

[COMException (0x81020073): The file or folder name contains characters that are not permitted.  Please use a different name.<nativehr>0x81020073</nativehr><nativestack></nativestack>]
   Microsoft.SharePoint.Library.SPRequestInternalClass.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback) +0
   Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback) +406

[SPException: The file or folder name contains characters that are not permitted.  Please use a different name.]
   Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx) +27609826
   Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback) +28003823
   Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents, String filename) +26729805
   Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents, String filename) +26726414
   Microsoft.SharePoint.SPListItem.Update() +161
   Microsoft.SharePoint.WebControls.SaveButton.SaveItem(SPContext itemContext, Boolean uploadMode, String checkInComment) +848
   Microsoft.SharePoint.WebControls.SaveButton.OnBubbleEvent(Object source, EventArgs e) +1315
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +70
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +29
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2981

image

The error message you receive if the file name is too long:

The specified file or folder name is too long. The URL path for all files and folders must be 260 characters or less (and no more than 128 characters for any single file or folder name in the URL). Please type a shorter file or folder name.<nativehr>0x800700ce</nativehr><nativestack></nativestack>

image

The issue is even more annoying if you have an edit form with some kind of custom logic behind it. For example, in one of our applications, there is a custom approval workflow attached to the list that is started automatically after the item is saved. If the file name is invalid, the workflow starts without the (probably for the approval important) attachment. It doesn’t really help customer satisfaction, I shouldn’t say.

How could we validate attachment file names and prohibit attachments having invalid names? We can use the same method as described in my former post. We should update our onAttachOKbuttonClicked method with the file name validations. The new version, including the duplicate check as well as file name length and special character validation:

  1. $(document).ready(attachEventHandlers);
  2.  
  3. function attachEventHandlers() {
  4.     // override the default event handler with our custom method
  5.     $('#attachOKbutton').attr("onclick", "onAttachOKbuttonClicked()");
  6. }
  7.  
  8. function onAttachOKbuttonClicked() {
  9.     var newFilePath = $('#attachmentsOnClient').find('input').last().val();
  10.     // get the file name from the file path as described at
  11.     // http://stackoverflow.com/questions/423376/how-to-get-the-file-name-from-a-full-path-using-javascript
  12.     // TrimWhiteSpaces is a js method of SharePoint to filter out special characters from the file name
  13.     var newFileName = TrimWhiteSpaces(newFilePath).replace(/^.*[\\\/]/, '');
  14.  
  15.     var maxFileNameLength = 128;
  16.  
  17.     // Information about the characters that you cannot use in site names, folder names, and file names in SharePoint
  18.     // http://support.microsoft.com/kb/905231
  19.     // http://www.sysadminsblog.com/microsoft/file-name-length-and-character-restrictions-for-sharepoint/
  20.     // ivalid characters in SP:
  21.     // ~#%&*{}\:<>?/+|"
  22.     // ivalid characters in file system:
  23.     // \/:*?"<>|
  24.     // we have to check only:
  25.     // ~#%&{}+|
  26.     /*
  27.     Cant be longer than 128 characters
  28.     Cant use: ~ # % & * { } \ : < > ? / + | "; RegExp: [~#%\&{}+\|] – do not include characters that are not allowed in the file system
  29.     Cant use the period character consecutively in the middle of a file name (blahblah.docx); RegExp: \\.\\.
  30.     Cant use the period character at the end of a file name; RegExp:  ^\\.
  31.     Cant use the period character at the start of a file name; RegExp:  \\.$    
  32.     */
  33.  
  34.     var match = (new RegExp('[~#%\&{}+\|]|\\.\\.|^\\.|\\.$')).test(newFileName);
  35.     if (match) {
  36.         alert("Ivalid file name. The name of the attached file contains invalid characters.");
  37.     }
  38.     else if (newFileName.length > maxFileNameLength) {
  39.         alert("Ivalid file name. The name of the attached file is too long.");
  40.     }
  41.     else {
  42.         // it is the same duplicate check code from former post (https://pholpar.wordpress.com/2014/03/12/how-to-check-for-duplicated-attachments-on-sharepoint-forms/)
  43.         var foundDuplication = false;
  44.  
  45.         $('#idAttachmentsTable').find('tbody').find('tr').each(function () {
  46.             var existingFileName = $(this).find('.ms-vb').find('a').text();
  47.             // if the existingFileName is empty then the attachment was uploaded in this session
  48.             // that is, it is not saved yet
  49.             if (existingFileName == '') {
  50.                 var existingFilePath = $(this).find('.ms-vb').find('span').text();
  51.                 existingFileName = existingFilePath.replace(/^.*[\\\/]/, '');
  52.             }
  53.  
  54.             if (newFileName == existingFileName) {
  55.                 foundDuplication = true;
  56.                 return false;
  57.             }
  58.         });
  59.  
  60.         if (foundDuplication) {
  61.             alert("A file with name '" + newFileName + "' is already attached to this item.");
  62.         }
  63.         else {
  64.             // call the OkAttach js method of SharePoint
  65.             // this is the method that is originally called by uploading attachments
  66.             OkAttach();
  67.         }
  68.  
  69.     }
  70. }

Note: I check only special characters that are supported in the NTFS file system, but not supported in SharePoint file names. I don’t check if the file name contains officially forbidden strings (.files, –Dateien, etc.). Reason is that up to now I had no issues with such files.

Including this method on the form helps us to prevent submitting the form with invalid attachments, and let the user to fix potential issues around attachment file names before saving the item.

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

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

Create a free website or blog at WordPress.com.

%d bloggers like this: