Friday, November 25, 2016

JSON based Site Template – Frist Release

I’ve published the SharePoint App in GitHub recently. The app needs to be installed at site collection level (root web). The app uses the following two types of templates:

  • Site Template – used to create new site.
  • Feature Template – used in existing sites to apply new features.

When the app will be launched, user will be provided a tree view of the site collection and option to create a new site under the selected site or apply a feature template to existing site.

image

Image 1: Home Page

 

Site Template

When user will select ‘create sub-site’ from home page teh following form will be provide to user:

image

Image 2: Create Sub-site page

 

Once user provides subsite details and click ‘create site’ the following progress screen will be showing:

image

Image 3: Creating site progress

 

Feature Template

The app comes with few feature templates built-in. As shown in the following image, all available templates will be shown in the screen:

image

Image 4: Feature Template Page

 

 

Conclusion

Feel free to use the source from GitHub and let me you know if you  have any suggestions or issues.

Wednesday, September 7, 2016

JSON based Site Template – Introduction

PnP Provisioning engine is really powerful to create and provision site templates. However PnP uses CSOM – which means to use PnP provision engine, we need to develop either desktop based application (console, wpf) or Provider hosted app. Would be nice to use PnP like templating to create site using SharePoint hosted Add-in which only supports JSOM.

Recently I worked with a client who needed to create sites based on site templates but didn’t want to use Provider hosted app nor any desktop application to provision new site based on site template. This is what I did for the client (more details will be provided in later blogs):

  1. Provisioned a site collection based on PnP Provisioning Engine.
    • Common Site Columns, Content Types are provisioned at site collection level.
    • Custom js (jquery, knockout) uploaded at site collection level and referenced in master page through custom action
    • Custom css uploaded at site collection level and used in alternate css property.
  2. The actual site template is created in PnP provision template but never used. Rather the template is converted to json using ‘JsonPnPFormatter’ and saved as json file.  More details provided later in this post.
  3. A SharePoint hosted Add-in is developed to create site based on site template and installed at site collection level. The add-in creates a new site and then reads the json file created from PnP template and provision artefacts as defined in json template. The Add-In does the followings:
    • Create Site, Site Groups
    • Create lookup fields and create content types
    • create lists
    • setup navigation
    • and many more

Since provisioning site collection/site based on PnP template is not part of this post,I’ll skip step 2.  I’ll explain step 2 – ‘convert PnP template to Json’ in this post. In later posts I’ll explain step 3 – ‘provision site based on json site template’.

Convert PnP template to JSON

To convert PnP template to json, you can use the following code snippet.

public void SaveTemplateAsJson(string templateFilePath, string templateName, string outputFilePath)
{
var templateProvider = new XMLFileSystemTemplateProvider(Path.GetDirectoryName(templateFilePath), "");
var template = templateProvider.GetTemplate(Path.GetFileName(XmlPath));
templateProvider.SaveAs(template, outputFilePath, new JsonPnPFormatter());
}

You can call the above method as

SaveTemplateAsJson(@"c:\templates\PnPTempalte.xml", "TemplateName", @"c:\templates\PnPTempalte.json");

To get a visual representation of Json file you can use online tools like http://jsoneditoronline.org/ or http://jsonviewer.stack.hu/

 

Now we are ready to use this JSON file in SharePoint Add-in to create site based on this template. If you need to convert multiple PnP templates to Json you can modify the SaveTemplateAsJson to do so.

I’ll explain how to use this json template to create SharePoint Add-in in my future posts.

Thursday, February 19, 2015

SharePoint 2013 Workflow: Code Activity Vs Service Call

SharePoint 2013 has introduced a new workflow model. The workflow model is mostly declarative (XML based). However, you might need to write custom code to implement complex business logic which the workflow itself doesn’t support. You have two options to implement code in this new workflow model:

  • Code activity
  • WCF Service

Now having these two options to implement, you need to know the pros and cons of both.

Let me compare these two options considering full-trust solution.

Options/Matrix Code Activity WCF Service Comments
Object Model You can use Client object model or server object model but better to user Client Object model as this gives you the flexibility to move the workflow manager (along with custom code activity) to non-SharePoint server for scalability.
You can use Server Object Model as the service will be hosted in SharePoint You should not use Server object model in code activity as the workflow services can be moved to non-SharePoint server for scalability
Development
  • Since you should use client object model, you need to be familiar with client object model.
  • The development involved few manual steps like creating xml file etc.
Easy to develop – just like regular Visual Studio solution (SharePoint template)  
Deployment Deployment requires copying files in different places, no out-of-box commands to deploy Code Activity Deployment is easy if you are familiar with WSP deployment If you don’t have remote access to the server (SharePoint admin will deploy using scripts for you), then code activity deployment might be a bit troublesome
Scalability If you use Server Object model, you can’t move workflow manager to it’s own non-SharePoint Server. However if you use client object model, you can move workflow manager to it’s own non-SharePoint server. Since it’s service, you can scale it anyway, like workflow manager and SharePoint server can be hosted in on-premise, cloud or hybrid.  
Reusability If you want to reuse the logic in workflow code activity, you might find it difficult Since your logic is hosted as WCF service, you can reuse the logic in other modules  
Execution I think code activity will run faster as it’ll be executed inside workflow manager. Service call will a bit slower than code activity, I believe This is based on assumption…

 

Workflow Manager in SharePoint 2013 is designed in a way that it can run independently in non-SharePoint server. Basically Workflow Manager and SharePoint communicate over REST endpoints. So if you use server object model in code activity you are breaking the overall architecture and bring the server side dependency. So in code activity it’s recommended to use either client object model or REST.

 

For calling WCF service, you can use built-in activity HttpGet/HttpPost.

 

Conclusion

I personally prefer service approach. I can use server object model, I can reuse the service in other modules and it’s easy to deploy/manage. However, if your custom code activity is doing something non-SharePoint related, like getting data from Line of Business (LOB) system, then maybe it’s better to code activity. It’s because it’s doesn’t make sense to deploy the logic (accessing data in LOB systems) in SharePoint.

Sunday, November 30, 2014

SharePoint 2013: Client Side People Picker

Introduction

SharePoint 2013 introduced client side people picker which can also be used from SharePoint apps. As like other SharePoint controls, the new people picker control is not well documented. I’ve reversed engineered the client side people picker control and tried to put some light in this dark area.

 

Functions

In the code snippet below, you can use user login id, email address as the key resolve the user in people picker.

Add Unresolved User

If you have user login Id or email address you can use them as key to add the user in people picker as shown below. By passing the ‘true’ as the last parameter in AddUnresolvedUser means, people picker will use the key to query the user details from server.

var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
var usrObj = { 'Key': loginIdOrEmail };
peoplePicker.AddUnresolvedUser(usrObj,true); 

 

Add users or show auto suggest

If you would like to show auto suggest box using javascript, you can use the following code snippet. if you pass true in the second parameter for AddUserKeys function, people picker will show the auto-suggest box, otherwise it’ll try to resolve the user. In case of passing true, you can pass any search-text and people picker will show the autosuggest based on the input search text.

var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
peoplePicker.AddUserKeys(loginIdOrEmailOrSearchText, false); //true shows the auto-suggest box, false resolve the user

 

Show Error Message

You can show an error message using code snippet as shown below:

SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.ShowErrorMessage('Error message...')

As as result you will the following error message:

image

 
IsEmpty

You can check if People picker is empty using the following code snippet. For your information, if there’s any text in the people picker textbox IsEmpty will return false. Basically it’ll check if there’s any resolved or unresolved text in the people picker editor textbox.

SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.IsEmpty()

 

HasResovledUsers

You can check if there’s any resolved user by using the following code snippet. If there’s at least one resolved user in the editor, it’ll return true (even if you have resolved or unresolved user, it’ll return true). The different between IsEmpty and HasResolvedUsers is that IsEmtpy will check if there’s any text in the people picker text box. Whereas HasResolvedUsers check if there’s any resolved users in the editor.

SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.HasResolvedUsers()

 

Get Current Editor Value

If you can get the editor’s current unresolved value by using the following code snippet:

SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.GetCurrentEditorValue()
The code snippet will not return any resolved value in the editor rather unresolved value

 

Enable/disable

You can use the following code snippet to enable or disable the people picker editor. However setting in disable state, prevent adding any new users in the editor but still user can remove existing resolved users by clicking cross (x) sign next to resolved user.

SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.SetEnabledState(false)

I think the easiest way to disable completely is to hide the delete (cross X) icon. You can do so using the following script:

$('.sp-peoplepicker-delImage').hide()

 

Remove Resolved Users

There’s no direct support for removing resolved users using the people picker API. I’ve put the following snippet below which I think should work and removes a user by using selected user’s key.

var peoplePickerId = 'peoplePickerDiv';
var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerId + '_TopSpan'];

//get selected users and select the second user (index 1) to remove
var selectedUsers = peoplePicker.GetAllUserInfo();
var userToRemoveKey = selectedUsers[1].Key; 

var resovledListElmId = peoplePicker.ResolvedListElementId;
var elementToRemove = '';
$('#' + resovledListElmId).children().each(function(index, element) {
    if (element.id.startsWith(peoplePickerId + '_TopSpan_' + userToRemoveKey + '_ProcessedUser')) {
        elementToRemove = element;
        return false;
    }
});

peoplePicker.DeleteProcessedUser(elementToRemove);

Simply, for all resolved users people picker creates span elements with id in the form ‘{peoplepickerid}_TopSpan_{userKey}_ProcessedUser_{index}’. So if we know the user key we want to remove, we can find the corresponding resolved user’s span element. Then finally people picker’s ‘DeleteProcessedUser’ method is used to remove the selected user.

 

Events

There’s few events available in the people picker control as described below. All of these events will get two parameters – first one is the people picker id and second parameter is an array of selected users.

On Control Value Changed

This event will be fired if anything changes, like if user type text, user select a user from auto-fill list or user removes selected user. You can easily hook into the event as shown below:

    this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.OnValueChangedClientScript=function (peoplePickerId, selectedUsersInfo) {
        console.log('inside OnValueChangedClientScript');
    };
 
On Control Resolved Users Changed

This event will be fired as soon as an user is resolved ( i.e., a resolved user is selected). You can hook into the event as shown below:

    this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.OnUserResolvedClientScript = function (peoplePickerId, selectedUsersInfo) {
        console.log('inside OnUserResolvedClientScript');
    };

 

On Control Validate

The people picker control validate it’s values – sometimes when values are changed or you can fire the event by yourself by calling the method ‘Validate’. You can hook into the event as shown below:

    this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.OnControlValidateClientScript = function (peoplePickerId, selectedUsersInfo) {
        console.log('inside OnControlValidateClientScript');
    };

 

Conclusion

I’ve tried to explain the API but you all are welcome to provide any feedback or suggestions or enhancements in this unofficial documentation.

Monday, September 29, 2014

SharePoint 2013: Branding with Theme

Theme is a nice and quick way of applying some new styles to SharePoint site. Using theme you can apply some customisation in branding: font, color, background image etc. In this post I’ll explain SharePoint 2013 Theme and you can download a sample SharePoint 2013 Visual Studio solution from here.

There’s some out-of-the-box theme preinstalled in SharePoint. However you can install your own custom theme in SharePoint site.

 

Theme - Concept

A theme is combination of the following items:

  • Color palette (a file with ‘.spcolor’ extension)
  • A font scheme (a file with ‘.spfont’ extension)
  • Background Image (if you would like to apply/change background image for this theme)
  • Master page, used for theme preview mainly

You can browse the URL http://{SiteCollection}/_catalogs/design/AllItems.aspx to view all theme list items.

Let me explain the theme components:

Color Palette

If you are not already familier with color palette – simply it’s a set of consistent colors to be used for designing/painting. You can find a lots of free site to choose color palette. Some free color platte sites are listed below. If you are designing your SharePoint site then these color palette sites can be really helpful:

Once you select your color palette, you can use a tool called ‘SharePoint Color Palette Tool’ to apply your color palette to design the theme. The following image shows the tool in action:

image

Few points to note about the tool:

  • You can only create the spcolor file
  • Though you can use background image to test the style in the tool, it’s for preview only. The background image will not be included in the spcolor file.
  • It’s quite unfortunate that there’s no user manual or documentation on how to use the tool. However there’s some videos available online, you can check.

 

 

Font Scheme

Font scheme defines the fonts to be used in different section of SharePoint site – navigation, heading, body etc when the theme will be applied. Most of the time you don’t need new font scheme. However if needed, the easiest way of creating a new font scheme is copy an existing one – for example ‘15/Template/Layouts/default.spfont’. If you don’t need custom font scheme as part of the theme, you don’t need to develop a custom font scheme.

 

Background Image

As part of the theme you can specify a background image that will used when the theme will be applied. Using background image is not quite common in SharePoint sites though.

 

Master Page

A theme can be associated with master page – but it doesn’t mean if theme is applied to a site, the master page will be changed too. Rather, the master page will be used for previewing the theme. You can view the theme preview by navigating to Site Settings => Change the look, or browsing “http://{siteurl}/_layouts/15/designgallery.aspx”. However, for custom theme if you specify a custom master page, then the master page should have a preview file associated, otherwise you will not see the theme in this design gallery.

 

Theme - Development/Deployment

I’ve provided a sample Visual Studio solution that shows how to develop a theme-based branding and deploy it. You can find code details from MSDN at http://msdn.microsoft.com/en-us/library/office/jj927175(v=office.15).aspx. However, simply developing, deploying and applying themes include the following steps:

  • Uploading files: You can upload your files as SharePoint modules(themes spcolor, spfonts, master pages etc.). In your visual studio solutions add these files as modules and as you deploy the solution the files will be uploaded in appropriate locations.
  • Install Theme: You need to create list items in ‘design catalog’ with populating different properties like theme url, order, title etc. Creating this list item will make the theme available in the design gallery at http://{siteurl}/_layouts/15/designgallery.aspx
  • Apply theme: If you would like to apply them when the feature is activated, you can apply the theme on feature activation. Alternatively you can apply theme manually from Site settings. In the sample solution, I’ve installed two themes (BrandingTestLight and BrandingTestDark) but only activated the dark theme on feature activation.

 

To install theme, we need to create a list item in design catalog gallery as shown below:

var themeItem = designCatalog.AddItem();
themeItem["Name"] = themeTitle;
themeItem["Title"] = themeTitle;
themeItem["MasterPageUrl"] = new SPFieldUrlValue(masterUrl);
themeItem["ThemeUrl"] = new SPFieldUrlValue(Web.Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/theme/15/" + themeName);
themeItem["DisplayOrder"] = displayOrderCounter; 
themeItem.Update();

In the code snippet above, Master page URL is only for displaying purpose. In my sample application I’ve used seattle.master. This is because whichever master page you use, the master page will have to have a ‘preivew’ file. Since it’s only for display purpose and seattle master page has a preview file, I’ve reused the same preview instead of creating a custom preview of my own for my custom master page. However, if you would like to create a custom preview for your master page you can see more details at http://msdn.microsoft.com/en-us/library/office/jj927173(v=office.15).aspx

 

 

To apply theme, you need to apply theme by using ‘Theme.ApplyTo’ method. However, there’s more. In the theme catalog (http://{sitecollection}/_catalogs/design/AllItems.aspx), you will find a list item with title ‘current’ as shown below. You need update the current theme - list item also as you can see in the sample solution provided.

image

 

Download the code

The sample solution I’ve uploaded is available here . The sample solution adds two themes (BrandingTestLight and BrandingTestDark)  and a custom master page. Once you deploy the sample WSP, there’ll be a Web scoped feature “SharePoint Branding - Theme” will be available. Activating and deactivating the feature will deploy the themes and custom master pages, modify the default and custom master page, apply the dark theme.

Sunday, June 22, 2014

SharePoint: Access large list

SharePoint list throttling limits to access maximum 5000 items through view/query. However your list can hold as much as 30,000,000 items but you can’t access more than 5000 items at once by view or query. But I’ve seen scenarios where list items goes millions in a year. So accessing large list having more than 5000 items not very rare in real life.

But have you ever asked yourself, why the limit is 5000 items?
The real limit of 5000 items is related to SQL server. I’m not a SQL server expert but let me try to explain as a non-SQL server expert – “If a SQL query returns more than 5000 items, SQL server locks the entire table – which will affect other queries on the table”.

So as a SharePoint expert you might need to be in a situation where you need to work with large list (having more than 5000 items). However, there’s few options you have when you need to access large list. I’ll explain different options with pros and cons.

 

Option 1: Override the throttling limit (Less preferable)

You can override the throttling limit from web application settings or through code. I would not suggest to do it from web application as it’ll be applied throughout the web application, instead if you querying your list then you can override the setting as shown below:

SPQuery spqry = new SPQuery();
spqry.QueryThrottleMode = SPQueryThrottleOption.Override;

The easy thing about this approach is that you don’t need to go through any complexity of writing complex code but downside is your query is taking excessive resources affecting other users. Points to note:

  • Easy to use, as you don’t need to include any complexity in your code if you are using SPQuery. If your list views return more than 500 items, the views will not fail
  • Also this approach will send a single (possibly) SQL query that will return all items
  • However, other users browsing the site will find the site slow – as the full table lock will be applied in SQL server delaying other users request to be queued
  • If you are loading all of the items in memory, then your server should be able to handle the items
  • You can override the throttling limit, if your server is able to handle all the items in memory and you are executing your script during off-peak hour. I would prefer overriding the throttling limit, if, for example, I’m moving all data for archiving during off peak hour. More specifically, if you need to run the script periodically or once during off-peak hour then you may be override the throttling limit.

 

Option 2: Access less than 5000 items Iteratively

With this approach, you don’t override the SharePoint throttling limit (always preferable). Rather you loop through and access less than 5000 items on each iteration (say, 2000 items per iteration). The following block shows the idea:

var list = web.Lists[listName];
var maxItemId = list.Items[list.ItemCount - 1].ID; //get max item id Or use below code to get max id using CAML
//spquery.RowLimit = 1;
//spquery.Query = "<OrderBy><FieldRef Name='ID' /></OrderBy>";
var startIndex = 1;
const int processByCount = 4000; //max no of items to be returned by spquery
var endIndex = startIndex + processByCount;
while (startIndex < maxItemId)
{
    var query = new SPQuery
    {
        Query = string.Format(@"<Where>
                            <And>
                                <Geq><FieldRef Name='ID' /><Value Type='Counter'>{0}</Value></Geq>
                                <Leq><FieldRef Name='ID' /><Value Type='Counter'>{1}</Value></Leq>
                            </And>
                        </Where>", startIndex, endIndex)
    };
    var items = web.Lists["ListName"].GetItems(query);
    //process items to convert to CSV
    startIndex = endIndex + 1;
    endIndex = startIndex + processByCount;

The above approach is a good option for querying items through SPQuery. However, for list view, you need to modify your views to make sure the view doesn’t return more than 500 items. Points to note:

  • You need to modify your existing views so that they don’t return more than 5000 items.
  • Once you modify your list views (as well as change the code to access less than 5000 items), the queries/views will have less affect on other live users.
  • However, you need to modify your existing code (or new code) to use the pattern to access not more than 5000 items.
  • Also for each loop, you will send a SQL query that will return the items.

 

Option 3: Use ContentIterator

SharePoint Server provides an API to access individual items using ‘ContentIterator’. ContentIterator is kind of complete API for processing large list items. Points to note:

  • The API has full capabilities of handling different scenarios
  • And the API is available in Office Server version not in Foundation.

 

Conclusion

Overriding throttling limit is in web application is the last option I would suggest. However overriding throttling limit through SPQuery can be used if you are running your query during off-peak hour and possibly one time. Option 2 of ‘Iteratively accessing less than 5000 items’ is more suitable as you can control how many items you would like to access on each request. ContentIterator is the preferable way, if you are using Server version of SharePoint.

Tuesday, May 13, 2014

SharePoint: Safe Control Entry using elements file

Recently I’ve discovered that it’s possible to add safe control entries through elements.xml file. To do this, add an elements.xml file (or use an existing xml file). Then select the elements.xml file and open the properties window as shown below:

image

Then click the ... button next to (Safe Control Entries) as shown in the above image. Then in the safe control entries dialog click ‘Add’ and edit the namespace as shown below:

image

Finally, add the element xml file to a web/site scoped feature. As you will deploy the WSP, the safe control entry will be added in web.config file.

Sunday, November 17, 2013

SharePoint 2013: Optimize your development Environment

SharePoint 2013 demands more resources – especially more memory. When we need to setup a SharePoint 2013 environment we can optimize resource usage in the development server by provisioning/configuring required services as well as following some other guidelines listed in this post.

 

Search Service Applications

Search Service is EXTREMELY resource hungry. noderunner process (Search Service process for crawling/indexing) is widely known for it’s resources usage footprint. In case you don’t need search service in your development server, you can delete the service application or at least stop the service. If you need to use the search service from time to time, you can keep the search service application running but stop the search service. However, if you try to stop the search service from windows service, you will find the service will be started again by SharePoint. The correct way to stopping service is from Central admin as shown below:

image

 

If you need the search service components (crawling/indexing) on development server, you can reduce the performance level by running the following command in SharePoint PowerShell. More information available at http://technet.microsoft.com/en-us/library/ff608126.aspx.

Set-SPEnterpriseSearchService -PerformanceLevel Reduced

You can also control the noderunner memory consumption by changing ‘memoryLimitMegabytes’ in the config file “C:\Program Files\Microsoft Office Servers\15.0\Search\Runtime\1.0\noderunner.exe.config”. Please remember, changing the value to too low might cause the search service to fail.

 

 

Provision Required Service Applications only

If you install SharePoint using Installation wizard, different service applications are installed but you many not need all of these service applications. From Central admin you can delete unnecessary Service applications as well as stop services. As you can see below

 

 

Stop unnecessary Web Application

Even web application running in your development environment will create w3wp process (if a separate application pool is used) or at least use resources. So if you don’t nee a web application for time being, you can stop the web application as well as related application pool from IIS Manager.

 

 

Visual Studio IntelliTrace

If you use Visual Studio debugging in the server and your Visual Studio supports IntelliTrace and the feature is enabled, you can disable the option. That might improve your debugging experience. More information on how to enable/disable the feature can be found at: http://msdn.microsoft.com/en-us/library/dd264948(v=vs.100).aspx

 

Multiple Disk Drive

If you have configured multi-server farm, you can keep some servers in another disk drive. For example, I’ve a multi-server (4 servers – AD, SQL, WFE and App) farm and I’ve kept two servers in my external USB3 supported external drive. So rather than four server vying for the same disk access, two are vying for internal disk access and other two are vying for external disk.

Even if are running a single server farm, you can use an external SSD drive (or USB3) for better I/O throughput. Especially if you can move your database files in an external drive, you will experience much better performance.

 

Tracing Service

SharePoint uses a windows Service ‘SharePoint Tracing Service’ for logging. sometimes, like during deployment, you will find the log file is growing few hundreds megabytes in short time. So tracing service might take a bit role in performance. If you don’t need the log file for a period of time, you can disable the windows service. During development I usually disable the service and when I need to see the log file, I enable the service.

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.