Monday, March 20, 2017

Use of SharePoint Designer 2013

Following are the high level list of features and functionality that we can do using SharePoint Designer 2013
  1. Edit Site
a.      Create list/libraries/Sites
b.      Create site pages
c.      Create Web Part Pages
d.      Create/edit Master pages
e.      Create custom new form  
f.       Copy/move/delete items
g.      Create content types/columns/external content types/site assets
h.      Site Groups
2. Create Workflows
a.      Workflow Actions
b.      List Workflow  
b.      Reusable Workflow  
c.      Site Workflow
d.      Package workflows  
e.      Loops in Workflow
3.      Create external Data sources
 4.      Integrate the Visio designer into SharePoint

 5.      Call REST Web Services

Friday, March 3, 2017

Personalize this page menu is missing

Version: SharePoint Server 2013

Issue: Personalize this page menu is missing on some pages.

Resolution:

If page is enabled with approval workflow, make sure that the approval status is 'approved'. Personalize this page menu will not show up if the Approval status of the page is in draft or pending status.

Thursday, March 2, 2017

Programmatically creating a field from the Custom field type

Environment: SharePoint Server 2013
Requirement: Programmatically create a field/column from a custom field type.


Following is a simple example with sample code to create a field from custom field type. In this example we are creating a custom field type (derived from SPFieldNumber) and add it to document library.

Note: I would recommend to refer to this MSDN post before this post to understand the entire steps involved to create a custom field type.


Creating the Custom Field Class.
The following example defines a custom control for displaying the custom field of type SPFieldNumber. The example overrides the OnAdded method to contain the logic while adding the custom field type in library/list.


using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Prasath.SP
{
   class SampleHitCountField: SPFieldNumber
   {
       public SampleHitCountField(SPFieldCollection fields, string fieldName)
           : base(fields, fieldName)
       {
       }


       public SampleHitCountField(SPFieldCollection fields, string typeName, string displayName)
           : base(fields, typeName, displayName)
       {
       }


       //Event triggered when new field is added to the document library
       public override void OnAdded(SPAddFieldOptions op)
       {
           base.OnAdded(op);
           Update();


           //Hide the field from new and edit form
           this.ShowInEditForm = false;
           this.ShowInNewForm = false;
           this.DefaultValue = "0";
           this.EnforceUniqueValues = false;
           this.Required = false;
           this.Update();
       }
   }
}


Creating the Field Type Definition
The following example registers the custom field type. This file must be named in the format fldtypes*.xml


<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
 <FieldType>
   <Field Name="TypeName">SampleHitCountField</Field>
   <Field Name="TypeDisplayName">Total View Count</Field>
   <Field Name="InternalType">SampleHitCountField</Field>
   <Field Name="TypeShortDescription">Total View Count</Field>
   <Field Name="FieldTypeClass">Prasath.SP.SampleHitCountField, $SharePoint.Project.AssemblyFullName$</Field>
   <Field Name="ParentType">Number</Field>
   <Field Name="Sortable">TRUE</Field>
   <Field Name="Filterable">TRUE</Field>
   <Field Name="UserCreatable">TRUE</Field>
   <Field Name="ShowOnListCreate">FALSE</Field>
   <Field Name="ShowOnSurveyCreate">FALSE</Field>
   <Field Name="ShowOnDocumentLibrary">TRUE</Field>
   <Field Name="ShowOnColumnTemplateCreate">TRUE</Field>
   <Field Name="ShowInListSettings">TRUE</Field>
 </FieldType>
</FieldTypes>


Creating a Field from custom Field Type
Following is the method to create field from custom type
/// <summary>
       /// Create custom field as XML
       /// </summary>
       /// <param name="oId">Field GUID</param>
       /// <param name="strDisplayName">Unique Display Name of field</param>
       /// <param name="Required">Field required property</param>
       /// <param name="strFieldType">Custom field type</param>
       /// <param name="strFieldName">Custom field display name</param>
       /// <returns>string</returns>
       internal static string GetCreateFieldAsXml(Guid oId, string strDisplayName, bool Required, string strFieldType, string strFieldName)
       {
           XmlElement element = new XmlDocument().CreateElement("Field"); // Creating the “Field” element for the Inner XML schema
           element.SetAttribute("ID", oId.ToString()); // Setting the GUID of the field from value passed
           element.SetAttribute("Type", strFieldType); // Setting the Parent Type name of custom type registered in the “Fldtypes*.xml” file
           element.SetAttribute("Name", strFieldName); // Setting the Type Display Name registered in the “Fldtypes*.xml” file
           element.SetAttribute("DisplayName", strDisplayName); // Any unique Display Name
           element.SetAttribute("Required", Required.ToString().ToUpper());
           return element.OuterXml; // Returning the OuterXML to create the field as XML
       }

//Code to custom field as XML from custom field type
String strFieldasXML = GetCreateFieldAsXml(Guid.NewGuid(), “Hit Count Field”, false, "SampleHitCountField", “SampleHitCountField”);
web.Fields.AddFieldAsXml(strFieldasXML); //here 'web' is a SPWeb object

Wednesday, March 1, 2017

Retrieve SharePoint Document Icons programmatically

Environment: SharePoint Server 2013


Requirement: Retrieve SharePoint Document library icon based on the document type (extension).


Solution: Use SPUtility.GetCurrentGenericSetupPath to obtain the file path for sharepoint 2013 location and use System.IO.File.Exists() method to check if the file exists in the location.


Following method returns the file name and relative URL of the icon file location based on the extension parameter passed.


       /// <summary>
       /// Method to get the document icon path
       /// </summary>
       /// <param name="extn">document type</param>
       /// <returns>relative URL of the icon image file</returns>
       public static string GetDocumentIconPath(string extn)
       {
           try
           {
               if (File.Exists(SPUtility.GetCurrentGenericSetupPath("template\\images\\ic" + extn + ".png")))
                   return "_layouts/15/images/ic" + extn + ".png";
               else if (File.Exists(SPUtility.GetCurrentGenericSetupPath("template\\images\\ic" + extn + ".gif")))
                   return "_layouts/15/images/ic" + extn + ".gif";
               else
                   return "_layouts/15/images/icgen.gif";
           }
           catch (Exception ex)
           {
              //Handle Exception
           }
       }


//Call the above method by passing the File Type column value of a document library item.
String iconURL = GetDocumentIconPath(document.Item["File Type"].ToString();

Thursday, November 24, 2016

Force update analytics components timer job


Issue: The popular items report for the document library are updated every 24 hrs and we cannot get the recent hits updated immediately.

Workaround: Following is the workaround to get the recent hits updated in the most popular items report for a document library

Prerequisite: Make sure that Reporting feature and Popularity Trends/usage analytics is enabled for the site

1. Make sure that the Search Analytics timer job is started.
$analyticsJob = Get-SPTimerJob -Type Microsoft.Office.Server.Search.Analytics.AnalyticsJobDefinition
$searchanalytics = $analyticsJob.GetAnalysis("Microsoft.Office.Server.Search.Analytics.SearchAnalyticsJob")
$searchanalytics.StartAnalysis()

  1. Trigger the events by opening and downloading some files from document library

  1. Make sure that the usage files @ C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\LOGS\RequestUsage are updated with the event details.

  1. Events can be imported from usage to Event store by running the Timer Job manually using following PowerShell script

$usagejob = Get-SPTimerJob -Identity ("job-usage-log-file-import")
$usagejob.RunNow()

  1. Make sure that the event store (C:\Program Files\Microsoft Office Servers\15.0\Data\Office Server\Analytics_<GUID>\EventStore)  is updated with the event

  1. Copy the current data event store logs to a custom folder location. In this example we have copied the logs to following location
    15 Hive\Data\Office Server\Analytics_<GUID>\EventStore\20161124\MyEvents

  1. Run the following PowerShell script to start the usage analytics

$uajob = get-sptimerjob -type microsoft.office.server.search.analytics.usageanalyticsjobdefinition
$uajob.DisableTimerJobSchedule()
$uajob.StartAnalysis("\\ilinksys-121\Office Server\Analytics_abce7b74-9002-404b-92b2-126bcddf451e\EventStore\20161124\MyEvents")
$uajob.EnableTimerJobSchedule()

Check the most popular items report once the job state is complete and you notice that the recent events are updated.

Thursday, November 17, 2016

Retrieve Popular items Programmatically In SharePoint using SOM

Introduction


In this article, we’ll see how to retrieve popular items based on view counts programmatically using SOM.

Prerequisite

Make sure that you have enabled the reporting feature under site collection features in the site to see the popular documents.

Code
The following lines of code retrieve the data and update the results in a Data table.

using System;
using System.Linq;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Search.Query;
using System.Data;

namespace GetPopularItems
{
   class Program
   {
       static void Main(string[] args)
       {
          
           DataTable table = new DataTable();
table.Columns.Add("ItemID", typeof(Int32));
           table.Columns.Add("Name", typeof(String));
           table.Columns.Add("Recent", typeof(Int32));
           table.Columns.Add("Views", typeof(Int32));

           string siteurl = "http://SiteURL/";
           string docLibURL = "http://SiteURL/Shared%20Documents";


           using (SPSite siteCollection = new SPSite(siteurl))
           {
               using (SPWeb rootWeb = siteCollection.OpenWeb())
               {

                   KeywordQuery keywordQuery = new KeywordQuery(siteCollection);
var properties = keywordQuery.SelectProperties; properties.Add("ListItemID");
                   keywordQuery.QueryText = "Path:"+ docLibURL;
                   SearchExecutor searchExecutor = new SearchExecutor();
                   ResultTableCollection resultTableCollection = searchExecutor.ExecuteQuery(keywordQuery);
                   var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);
                   ResultTable resultTable = resultTables.FirstOrDefault();
                   DataRowCollection dataTable = resultTable.Table.Rows;
                                     
                   for (var i = 1; i < dataTable.Count; i++)
                   {
                       DataRow datarowObj = table.NewRow();
datarowObj["ItemID"] = resultTable.Table.Rows[i][(resultTable.Table.Columns["ListItemID"]).Ordinal];
                       datarowObj["Name"] =  resultTable.Table.Rows[i][(resultTable.Table.Columns["Path"]).Ordinal];
                       datarowObj["Recent"] = resultTable.Table.Rows[i][(resultTable.Table.Columns["ViewsRecent"]).Ordinal];
                       datarowObj["Views"] = resultTable.Table.Rows[i][(resultTable.Table.Columns["ViewsLifeTime"]).Ordinal];
                       table.Rows.Add(datarowObj);
                   }
               }
           }
       }
   }
}