Sunday, October 27, 2013

Upgrade SharePoint 2010 Visual Studio Solution to SharePoint 2013

With every new version of SharePoint, we need to upgrade our Visual Studio solution. There’s no easy way or tool out there that can automate these upgrade. So I’ll just describe few points you need to consider when you’ll upgrade the Visual Studio 2010 project for SharePoint 2010 to Visual Studio 2012 project for SharePoint 2013. First of all, you need to upgrade your Visual Studio pre-VS2012 solution to Visual Studio 2012.

Change Target .NET Framework

SharePoint 2010 uses .Net Framework 3.5 with SharePoint 2013 uses .Net Framework 4.5. So you need to change the target framework for the project. To change the target framework version, unload the project and then edit the project file in Visual Studio and change the property as shown below:

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>

 

Change SharePoint Version

Unload the project and edit in Visual Studio, then add/edit the section to ensure the following entry near to the <TargetFrameworkVersion>

<TargetOfficeVersion>15.0</TargetOfficeVersion>

Then load the project and replace all SharePoint 2010 specific DLLs with SharePoint 2013 specific DLLs (version 15). Also find out any reference of SharePoint 2010 DLLs/Controls  version ‘14.0.0.0’ and replace with ‘15.0.0.0’

 

Change Generic Setup Path in code

In SharePoint 2013, you can deploy your solution in SharePoint 2010 more or SharePoint 2013 mode or both. For example to deploy your solution to both 2010 and 2013 mode, you can use the following command:

Install-SPSolution -Identity my_solution.wsp -GACDeployment -CompatibilityLevel {14,15}

If you skip the CompatibilityLevel (and we usually skip), then the solution is deployed default compatibility level included in the WSP manifest file – which is based on Visual Studio project’s target SharePoint Version. But since we are targeting to upgrade Visual Studio solution to SharePoint 2013, we need to make sure code looks for artifacts in 15 hive, instead of 14 hive. To ensure that code looks in 15 hive, we need to find all use of ‘SPUtility.GetGenericSetupPath()’ and need to replace it with ‘SPUtility.GetVersionedGenericSetupPath()’ passing parameter 15 as shown below:

SPUtility.GetVersionedGenericSetupPath(‘/_Layouts/myproject/script/test.js’,15)

Note – If you are still deploying your solution in compatibility 14 mode, then you should also replace the ‘GetGenericSetupPath()’ with ‘GetVersionedGenericSetupPath()’ passing parameter 14, but instead of hardcoding the version inline, you can use a constant so that you can replace the version number in one place to change it to 15. You can use constant ‘Microsoft.SharePoint.Utilities.SPUtility.ContextCompatibilityLevel’ which returns the current compatibility level of the SPSite. Your code then will look like:

SPUtility.GetVersionedGenericSetupPath(‘/_Layouts/myproject/script/test.js’,Microsoft.SharePoint.Utilities.SPUtility.ContextCompatibilityLevel)

However, if you want to use the same code both for SharePoint 2010 and SharePoint 2013, then you can code block like below to run code in different version of SharePoint:

//if SharePoint site collection is running in 2013 (15) mode
if (SPUtility.ContextCompatibilityLevel==SPUtility.CompatibilityLevel15)
{
    //Code needs to be executed in SharePoint 2013
}
else if (SPUtility.ContextCompatibilityLevel==14)
{
  // Code needs to executed in SharePoint 2010
}
//You can also use SPSite.CompatibilityLevel to find out site collection compatibiltiy mode

Change Reference to Layouts, ControlTemplates

Finally all references to ‘_Layouts/’ and ‘_ControlTemplates/’ needs to be changed to ‘_Layouts/15/’ and ‘_ControlTemplates/15/’ to ensure the artifacts are loaded from 15 hive. Either SharePoint will try to load files from 14 hive. However if you deploying the solution in SharePoint 2010 mode, (compatibility level is 14), then you don’t need to update the reference.

 

Conclusion

After making all the above changes, finally compile the solution. However, my suggestion would be to deploy the WSP in SharePoint 2010 mode first, test the deployment and adjust/modify code to comply with SharePoint 2010 object model. Once you are comfortable with changes, then upgrade code as described in the post and then deploy/test.

Sunday, October 13, 2013

SharePoint Suite/Chrome Control

SharePoint 2013 or Office 365 introduced a new ribbon on the top of the page known as Suite Control as shown below (‘SharePoint’ text):
image
However, we may want to control the text to appear in the suite control and how they will appear. I’ll explain how to put static text as well as dynamic text in the suite control. For example you may want to show your environment name like ‘DEV’, ‘Test’.

 

Static Content

If you would like to put just some static text replacing ‘SharePoint’ or ‘Office 365’ you can do so in few different ways that are described below:
Modify using PowerShell
You can modify the text using PowerShell and apply your own static text. You can apply text to web application level as shown below:
$webApplication = Get-SPWebApplication -Identity "http://web-application-url"
$webApplication.SuiteBarBrandingElementHtml = '<div class="ms-core-brandingText">My Text</div>'
$webApplication.Update()


This approach will work for whole web application but if you need different text in different sites, you may not be interested in this approach. Also for Office 365, you will not have these PowerShell command available.

 

Modify through MasterPage

However, if you don’t have access to PowerShell (as in Office 365, you have limited PowerShell access), you can modify master page to edit the text. For your information, if you are using HTML based master page design, then this approach will not work. For your information, in SharePoint 2013, you can develop HTML design first and then can convert the HTML to master page – hence HTML based master page design. Open the default master page in your site using SharePoint Designer, or if you are using custom branding, open your custom master page in edit mode (either in SharePoint Designer or Visual Studio). Find a div with Id ‘suiteBar’ and there’s a delegate control inside the div with id ‘ID_SuiteBarBrandingDelegate’, set this delegate control visible property to ‘false’ (shown in the image below) as this will hide the default Chrome text. Then add your own chrome text in another div after the delegate control

<div class="ms-core-brandingText">My Static Chrome Text</div>

Finally the change will look like below:

image
However, if you are using HTML based master page design (where you have editing html page which is generating master page), this option will not work as the delegate control is not available in HTML file (rather available in master page file) and you are not supposed to edit the master page directly in HTML based master page design.

 
Modify Using JavaScript
If you want to use JavaScript to modify the text, edit your master page (or corresponding html file) and add the following script in the file.
<script type="text/javascript">
    $(document).ready(function () {
        ApplySuiteBranding('My Text');

        //ApplySuiteBranding("<b>My Text</b>");
        //ApplySuiteBranding("<b>My Text</b>");
        //ApplySuiteBranding("<a href='http://abc.com'><img src='test.jpg' alt='icon'/></a>");
    });
    function ApplySuiteBranding(htmlToApply) {
        //find for office 365 suite control
        var brandingBox = $('#suiteBrandingBox');
        if ($(brandingBox).length == 0) {
            //office 365 suite control not found, so it's SharePoint
            brandingBox = $('#suiteBar').find(".ms-core-brandingText");
        }

        $(brandingBox).html(htmlToApply);
    }
</script>


For your information, the above script need to be applied in master page html file if you are using html based master page design. Otherwise apply the script in master page directly. Also you need to add reference to jQuery in the master page as the above script make use of jQuery Library. You can also modify the script to add dynamic text, like current site title by using ‘_spPageContextInfo.webTitle’. So this approach will enable developer to provide semi-dynamic text in the chrome – like web title or any other text that is accessible from jQuery/JavaScript.

 

Dynamic Content

If you would like to modify the suite control text dynamically, for example add some dynamic navigation or apply different text in different site collection, then you need to create a delegate control. I would recommend this solution, if possible. Though it requires custom development/deployment but it gives you more flexibility and more robust solution. Let’s describe how to do that. I’m not going to explain it steps by steps as you can find a nice example of this at: http://blogs.msdn.com/b/findnavish/archive/2013/02/07/sharepoint-2013-customizing-suite-bar.aspx.

 

Chrome Control in SharePoint 2013 Apps

If you want to use Chrome Control in SharePoint apps, you can find more details on MSDN: http://msdn.microsoft.com/en-us/library/fp179916.aspx.

 

Conclusion

So in summary, if you are happy with static text for whole web application and have PowerShell command available, then use the option of PowerShell. However, if you don’t have access to PowerShell command (as in Office 365), then you can use JavaScript based or direct Master Page edit option described. Finally, if you want a decent and manageable solution (considering, you are deploying a custom WSP solution), you can use Delegate control which gives you more control to change text dynamically. Using JavaScript option will give you the option of adding static text as well as some dynamic text.