SharePoint 2013: How to copy files from document library to another site – Using silverlight

Well, working with SharePoint 2013 is very funny and many challenge for me.

Now, let start with my scenario: I need to copy or move files from one SharePoint library to another library in the same site collection. Easy, right? But, the challenge here is do it without server code, did you do the same before? In this post, I will do some solution to do this.

Please look at my previous post to see how I copy and move with CSOM, Everything seem simple when we copy files in the same site as I show you in previous post, but how to copy files from site A to site B without server code? I tried with many ways to do that: using the same method in previous, call Copy.asmx service, retrieve content of selected files, then upload it using REST or CSOM, but .. Cannot, huhu.

After few hours research with above solutions, my colleague suggest me to using Silverlight to do that, why not? Yes, I can using Silverlight to copy files from site to another site. It quite easy, let me show you how to do that:

First, in your aspx, you need to inject the Silverlight  application to your page similar this way:

1:      <div id="silverlightControlHost">  
2:        <objecttag id="MultiFileCopier"   
3:            data="data:application/x-silverlight-2,"   
4:            type="application/x-silverlight-2"   
5:            width="400"   
6:            height="10">  
7:          <paramtag name="source"   
8:              value="/SiteAssets/Quac/SilverlightCopyMove.xap" />  
9:          <paramtag name="onerror"   
10:              value="onSilverlightError" />  
11:          <paramtag name="initparamtags"   
12:              value="Customparamtags=yourparamtageters,DefaultColor=White" />  
13:          <paramtag name="background"   
14:              value="white" />  
15:          <paramtag name="onload"    
16:              value="pluginLoaded" />  
17:          <paramtag name="minRuntimeVersion"   
18:              value="4.0.50401.0" />  
19:          <paramtag name="autoUpgrade" value="true" />  
20:          <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0"   
21:            style="text-decoration: none">  
22:            <img  src="http://go.microsoft.com/fwlink/?LinkId=161376"   
23:                alt="Get Microsoft Silverlight"   
24:                style="border-style: none" />  
25:          </a>  
26:        </objecttag>  
27:        <itagframe style='visibility: hidden; height: 0; width: 0; border: 0px'></itagframe>  
28:      </div>  

Next, we add some script code to contact between Silverlight and Javascript:

1:      //calling Silverlight method  
2:      var slCtl = null;  
3:      //   
4:      function pluginLoaded(sender) {  
5:        slCtl = document.getElementById("MultiFileCopier");  
6:        //Set Parameter  
7:        bindDateToSilverlightControl(slCtl);  
8:      }   
9:      function onSilverlightError(sender, args) {  
10:         alert("some error");  
11:      }  
12:      function TalkToJavaScript(data) {        
13:            //eventFromSilverlightControl(data);  
14:      }  
15:      $(document).ready(function () {  
16:        $("#CopyFileUsingSilverlight").click(function () {  
17:          CopyFileUsingSilverlight();  
18:        });  
19:      });  

Then, we bind initial data to Silverlight control:

1:  var silverlightControl = null;  
2:  function bindEntitiesToDropdownList(slCtl) {  
3:    silverlightControl = slCtl;  
4:    if (silverlightControl != null) {  
5:      var context = SP.ClientContext.get_current();  
6:      var selection = SP.ListOperation.Selection.getSelectedItems(context);  
7:      var sourceListId = ctx.listName;  
8:      var item;  
9:      var sourceItemIds = "";  
10:      for (item in selection) {  
11:        if (selection[item].fsObjType === "0") {  
12:          sourceItemIds += selection[item].id + ";";  
13:        }  
14:      }  
15:      var initParams = "SourceWebAbsoluteUrl=" + _spPageContextInfo.webAbsoluteUrl +  
16:               ", SourceSiteAbsoluteUrl=" + _spPageContextInfo.siteAbsoluteUrl +  
17:               ", SourceListId=" + sourceListId + ", SourceItemIds=" + sourceItemIds;  
18:      silverlightControl.Content.MainPage.InitializeParams(initParams);  
19:      silverlightControl.Content.MainPage.AddUserFile();  
20:    }  
21:  }  

And, at the Silverlight project, we need to implement the method to receive the data from javascript and store the stream of these files to list of UserFile:

1:      [ScriptableMember]  
2:      public void AddUserFile()  
3:      {  
4:        files = new List();  
5:        DoAddUserFile();  
6:      }  
7:      void DoAddUserFile()  
8:      {  
9:        if (indexOfCopiedFile   
10:        {  
11:          if (sourceListItem.FileSystemObjectType == FileSystemObjectType.File)  
12:          {  
13:            // get the file  
14:            file = sourceListItem.File;  
15:            srcContext.Load(file);  
16:            srcContext.ExecuteQueryAsync(LoadSourceFileSucceededCallback, null);  
17:          }  
18:        });  
19:      }  
20:      void LoadSourceFileSucceededCallback(object sender, ClientRequestSucceededEventArgs args)  
21:      {  
22:        Dispatcher.BeginInvoke(() =>  
23:        {  
24:          Microsoft.SharePoint.Client.File.OpenBinaryDirect(srcContext, file.ServerRelativeUrl, OpenBinaryDirectSuccessedCallback, null);  
25:        });  
26:      }  
27:      private void OpenBinaryDirectSuccessedCallback(object eventSender, OpenBinarySucceededEventArgs eventArgs)  
28:      {  
29:        Dispatcher.BeginInvoke(() =>  
30:        {  
31:          if (eventArgs.Stream != null)  
32:          {  
33:            userFile = new UserFile();  
34:            userFile.FileName = file.Name;  
35:            userFile.FileStream = eventArgs.Stream;  
36:            userFile.FileDataArray = new byte[userFile.FileStream.Length];  
37:            userFile.FileStream.Read(userFile.FileDataArray, 0, (int)userFile.FileStream.Length);  
38:            var _dataLength = userFile.FileDataArray.Length;  
39:            userFile.FileDataLength = _dataLength;  
40:            files.Add(userFile);  
41:            indexOfCopiedFile++;  
42:            DoAddUserFile();  
43:          }  
44:        });  
45:      }  

Back to javascript, we need to call the method of Silverlight by clicking the button in CopyFileUsingSilverlight:

1:  function CopyFileUsingSilverlight(slCtl) {  
2:    var targetWebUrl = _spPageContextInfo.siteAbsoluteUrl;  
3:    var fullTargetUrl = "http://sp/Project-Project-2-2/Shared Documents";  
4:    silverlightControl.Content.MainPage.StartCopy(targetWebUrl, fullTargetUrl);  
5:  }  

And the  StartCopy of Silverlight:

1:      [ScriptableMember]  
2:      public void StartCopy(bool bIsCopy, string webAbsoluteUrl, string strFullTargetUrl)  
3:      {  
4:        //set fullTargetUrl  
5:        fullTargetUrl = strFullTargetUrl;//"http://sp/Project-Project-2-2/Shared Documents";  
6:        isCopy = bIsCopy;  
7:        destContext = new ClientContext(webAbsoluteUrl);  
8:        // get the list and items  
9:        destWeb = destContext.Web;  
10:        destList = destWeb.Lists.GetByTitle("Documents");  
11:        destContext.Load(destWeb);  
12:        destContext.Load(destList);  
13:        destContext.ExecuteQueryAsync(DestListItemcolSucceededCallback, null);  
14:      }  
15:      void DestListItemcolSucceededCallback(object sender, ClientRequestSucceededEventArgs args)  
16:      {  
17:        Dispatcher.BeginInvoke(() =>  
18:        {  
19:          DoUploadUserFile();  
20:        });  
21:      }  
22:      void DoUploadUserFile()  
23:      {  
24:        if (indexOfUploadedFile   
25:        {  
26:          indexOfUploadedFile++;  
27:          DoUploadUserFile();  
28:        });  
29:      }  
30:      private void FailureUploadFile(object sender, ClientRequestFailedEventArgs e)  
31:      {  
32:        Dispatcher.BeginInvoke(() =>  
33:        {  
34:          HtmlPage.Window.Invoke("TalkToJavaScript", "DoFunc:FailureUploadFile");  
35:        });  
36:      }  

Well, we done with the Silverlight solution to copy files to another site.