Migrate SharePoint sites using Content Migration APIs

The export/import method provides the flexibility to migrate a site/sub-site from one web application to another web application (in a different content database) within a farm. It also provides the flexibility to export a sub-site and import it as a root site-collection in another web application. In this post I’d be discussing about how to programmatically migrate SharePoint sites using Content Migration APIs.

 

Code to export a site

                    string sourceSiteURL = "Your site url";//site to be exported
                    SPExportObject exportObject = "Path where you site to be exported";
                    string folderPath = "folder path";

                    using (SPSite sourceSite = new SPSite(sourceSiteURL))
                    {
                        using (SPWeb sourceWeb = sourceSite.OpenWeb())
                        {                            
                            //Create the Export Setting object and update the setting properties.  
                            SPExportSettings settings = new SPExportSettings();
                            settings.SiteUrl = sourceWeb.Url;
                            settings.ExportMethod = SPExportMethodType.ExportAll;
                            settings.BaseFileName = EXPORT_FILENAME; // "export.cmp";
                            settings.FileLocation = "provide file location";
                            settings.LogFilePath = @folderPath + LOG_FILENAME; // "LogFile.log";                                
                            settings.IncludeSecurity = SPIncludeSecurity.All;

                            setExcludeDependencies(migrationSettings, settings);
                            settings.OverwriteExistingDataFile = true;
                            settings.CommandLineVerbose = true;
                            settings.FileMaxSize = 1024;
                            settings.FileCompression = true;

                            // Add the Export object to the ExportSetting Object  
                            settings.ExportObjects.Add(exportObject);


                            // add the Export Settings to the SPExport object and Run the Export .  
                            SPExport export = new SPExport(settings);
                            export.Run();

                            LogAll.logTextWriting(true, ServerConstant.exportSuccessfully);
                            isExportCompleted = true;
                        }
                    }
               

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Code to import a site

                    // Get the Site collection Url from the config file.  

                    using (SPSite rootSiteColl = new SPSite(destinationSiteURL))
                    {
                        SPWebApplication webApp = rootSiteColl.WebApplication;
                        rootSiteColl.AllowUnsafeUpdates = true;
                        using (SPWeb rootWeb = rootSiteColl.OpenWeb())
                        {
                            // Package import
                            System.Uri siteURL = new Uri(destinationSiteURL);
                            string baseDataFileName = EXPORT_FILENAME; // "export.cmp";
                            string dataFileLocation = @folderPath;
                            string logFileLocation = @folderPath + LOG_FILENAME; // "LogFile.log";

                            SPImportSettings importSettings = new SPImportSettings(siteURL, dataFileLocation, baseDataFileName);
                            importSettings.IncludeSecurity = SPIncludeSecurity.All;
                            importSettings.RetainObjectIdentity = true;                            
                            importSettings.CommandLineVerbose = true;
                            importSettings.LogFilePath = logFileLocation;
                            importSettings.WebUrl = destinationSiteURL;
                            importSettings.FileCompression = true;


                            SPImport import = new SPImport(importSettings);
                            import.Run();
                            rootWeb.AllowUnsafeUpdates = false;
                            webApp.FormDigestSettings.Enabled = true;
                            webApp.FormDigestSettings.Expires = true;
                            rootWeb.Close();
                        }
                        rootSiteColl.AllowUnsafeUpdates = false;
                    }

The power of the import functionality is that we can pick and choose whether to retain the security, versions, object ids etc. The main drawback of this approach
is that it does not preserve workflow instances, workflow associations, history and tasks. Every workflow association must be recreated and there is no way
to restore the running instances from original site. But nonetheless, the export/import has real power or re-arranging the site-hierarchy in the target.
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 Subscribe to my blog

SharePoint 2013 Programmatically read list items using Java Script

Yesterday, I saw a question in MSDN forums on how to programmatically read SharePoint List items using JavaScript. Here is the full workable code below :-

var siteUrl = '/sites/MySiteCollection';

function retrieveListItems() {

    var clientContext = new SP.ClientContext(siteUrl);
    var oList = clientContext.get_web().get_lists().getByTitle('YourCustomList');
        
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><Where><Geq><FieldRef Name='ID'/>' + 
        '<Value Type='Number'>1</Value></Geq></Where></Query><RowLimit>10</RowLimit></View>');
    this.collListItem = oList.getItems(camlQuery);
        
    clientContext.load(collListItem);
        
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));        
        
}

function onQuerySucceeded(sender, args) {

    var listItemInfo = '';

    var listItemEnumerator = collListItem.getEnumerator();
        
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        listItemInfo += 'nID: ' + oListItem.get_id() + 
            'nTitle: ' + oListItem.get_item('Title') + 
            'nBody: ' + oListItem.get_item('Body');
    }

    alert(listItemInfo.toString());
}

function onQueryFailed(sender, args) {

    alert('Request failed. ' + args.get_message() + 'n' + args.get_stackTrace());
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 Subscribe to my blog

Inspecting SharePoint 2013 ContextToken and Refresh Token

In previous post, I briefly discussed about the OAuth Tokens and SharePoint 2013 Authentication & Authorization.  We know that there are couple of tokens, namely Context-Token and Refresh-Token are involved in the life-cycle of SharePoint 2013 App Authentication and Authorization. These tokens are not exactly the SAML 1.1 tokens and they  are bit different. The whole intend of this article is to inspect and understand what these tokens are.

In this article I would be creating a sample Auto-Hosted App, inside the page_load of the App-web project (of auto-hosted app) I would be adding some snippet of code to inspect and fetch the OAuth Context Token and Refresh Token.

Let’s create a sample Auto-Hosted App in Visual Studio 2012 with name ‘TestAppforOAuth’,

pic2

Open the default.aspx.cs of the AppWeb Project

Import the following namespaces at the top of the project

using Microsoft.SharePoint.Client;
using System.Net;
using System.IO;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

In the Page_Load method add the following snippet of code

TokenHelper.TrustAllCertificates();
string contextTokenString =
      TokenHelper.GetContextTokenFromRequest(Request);

if (contextTokenString != null)
      {
            SharePointContextToken contextToken =
            TokenHelper.ReadAndValidateContextToken(
                  contextTokenString, Request.Url.Authority);

            Response.Write("<h2>Valid context token</h2>");
            Response.Write(
                  "<p>" + contextToken.ToString() + "</p>");
            Response.Flush();

            Uri sharepointUrl = new      
                  Uri(Request.QueryString["SPHostUrl"]);
            string accessToken =
                  TokenHelper.GetAccessToken(contextToken, 
                  sharepointUrl.Authority).AccessToken;

            Response.Write("<h2>Valid access token 
                  retrieved</h2>");
            Response.Write("<p>" + accessToken + "</p>");
            Response.Flush();

            HttpWebRequest request =
                   (HttpWebRequest)HttpWebRequest.Create
                   (sharepointUrl.ToString() + 
                  "/_api/Web/title");
            request.Headers.Add("Authorization", "Bearer " +
                  accessToken);
            HttpWebResponse response = 
                   (HttpWebResponse)request.GetResponse();
            StreamReader reader = new 
                  StreamReader(response.GetResponseStream());

            Response.Write("<h2>Web title retrieved using 
                  REST</h2>");
            Response.Write("<p>" + reader.ReadToEnd() + "</p>");
            Response.Flush();
      }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Configure the Tenant level Read Permission for the App.

app permission1

app permission2

Hit F5, Deploy the app and trust it. If we inspect the Tokens these are not SAML, they are what they call it as JWT Tokens.

tokens

 Subscribe to my blog