Monthly Archives: February 2014

Get Approve, Manage Hierarchy, Restricted Read, View Only Role Definition programatically

Everybody has experienced with SharePoint permission knows about the OOTB SharePoint default permission level. From technet article, it will look like below:

  • View Only – Includes permissions that enable users to view pages, list items, and documents.
  • Limited Access – Includes permissions that enable users to view specific lists, document libraries, list items, folders, or documents, without giving access to all the elements of a site. You cannot edit this permission level directly.
  • Read – Includes permissions that enable users to view items on the site pages.
  • Edit – Includes permissions that enable users to add, edit and delete lists; can view, add, update and delete list items and documents.
  • Contribute – Includes permissions that enable users to add or change items on the site pages or in lists and document libraries.
  • Design – Includes permissions that enable users to view, add, update, delete, approve, and customize the layout of site pages by using the browser or SharePoint Designer 2013.
  • Full Control – Includes all permissions.
  • Approve – Includes permissions to edit and approve pages, list items, and documents.
  • Manage Hierarchy – Includes permissions to sites and edit pages, list items, and documents.
  • Restricted Read – Includes permissions to view pages and documents, but not historical versions or permissions information.

Below code shows you how to get each Role Definition programatically.

private static void Main(string[] args)
{
    try
    {
        using (SPSite site = new SPSite("http://yourSiteUrl"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                // Loop through all permission level in root web
                foreach (SPRoleDefinition eachRoleDefinition in web.RoleDefinitions)
                {
                    Console.WriteLine(string.Format("Role:{0}; Type:{1};", eachRoleDefinition.Name, eachRoleDefinition.Type.ToString()));
                }

                // Based on Role Type above, we could retrieve each Role Definition
                SPRoleDefinition roleDefinitionAdministrator = web.RoleDefinitions.GetByType(SPRoleType.Administrator);
                SPRoleDefinition roleDefinitionDesigner = web.RoleDefinitions.GetByType(SPRoleType.WebDesigner);
                SPRoleDefinition roleDefinitionContributor = web.RoleDefinitions.GetByType(SPRoleType.Contributor);
                SPRoleDefinition roleDefinitionEdit = web.RoleDefinitions.GetByType(SPRoleType.Editor);
                SPRoleDefinition roleDefinitionReader = web.RoleDefinitions.GetByType(SPRoleType.Reader);
                SPRoleDefinition roleDefinitionLimitedAccess = web.RoleDefinitions.GetByType(SPRoleType.Guest);
            }
        }
    }
    catch (Exception ex)
    {
        // your error handler
    }
}

Role Definition results:

Role Name Role Type
Full Control Administrator
Design WebDesigner
Edit Editor
Contribute Contributor
Read Reader
Limited Access Guest
Approve None
Manage Hierarchy None
Restricted Read None
Restricted Interfaces for Translation None
View Only None

Then, the next question is How do we retrieve Approve, Manage Hierarchy, Restricted Read and View Only role definition ? Since Role Type for those Role Definition is None ? Thanks to Alex Sadomov blog, I found the solution …

                SPRoleDefinition roleDefinitionManageHierarchy = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == "Manage Hierarchy");
                SPRoleDefinition roleDefinitionApprove = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == "Approve");
                SPRoleDefinition roleDefinitionViewOnly = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == "View Only");
                SPRoleDefinition roleDefinitionRestrictedRead = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == "Restricted Read");

What about if you have Multilingual SharePoint site?

Long story short, you need to use Microsoft.SharePoint.Publishing.Internal.StringIds to retrieve the Role Name.

 
using System.Resources;
using System.Reflection;
using Microsoft.SharePoint.Publishing.Internal;

public class PublishingResources
{
    private static ResourceManager resourceManager;

    static PublishingResources()
    {
        var resourceAssembly = Assembly.Load("Microsoft.SharePoint.Publishing.intl, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
        resourceManager = new ResourceManager("Microsoft.SharePoint.Publishing.Strings", resourceAssembly);
    }

    internal static string GetString(string resourceName, CultureInfo cultureInfo)
    {
        return resourceManager.GetString(resourceName, cultureInfo);
    }
}


string roleName = PublishingResources.GetString(StringIds.RoleNameHierarchyManager, web.UICulture);
SPRoleDefinition roleDefinitionManageHierarchy = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == roleName);

roleName = PublishingResources.GetString(StringIds.RoleNameApprover, web.UICulture);
SPRoleDefinition roleDefinitionApprove = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == roleName);

roleName = PublishingResources.GetString(StringIds.RoleNameViewer, web.UICulture);
SPRoleDefinition roleDefinitionViewOnly = web.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(r => r.Name == roleName);

Reference

Advertisements

Create Retrieve Update and Delete SharePoint List Item using REST API and JQuery

In this article, I would like to show you utilizing SharePoint REST API and JQuery to Create, Retrieve, Update and Delete SharePoint list item.

Pre-Requisite

  • Reference to latest jquery.min.js
  • For this example purposes, create custom List called “MyList” with default “Title” column.

Create

// occurs when a user clicks the create button
function CreateNew() {
    var listName = "MyList";
    var newItemTitle = "New Title Item";
    CreateListItemWithDetails(listName, _spPageContextInfo.webAbsoluteUrl, newItemTitle, function () {
        alert("New Item has been created successfully.");
 }, function () {
     alert("Ooops, an error occured. Please try again.");
 });
}

// CREATE Operation
// listName: The name of the list you want to get items from
// weburl: The url of the web that the list is in. 
// newItemTitle: New Item title.
// success: The function to execute if the call is sucesfull
// failure: The function to execute if the call fails
function CreateListItemWithDetails(listName, webUrl, newItemTitle, success, failure) {
    var itemType = GetItemTypeForListName(listName);
    var item = {
        "__metadata": { "type": itemType },
        "Title": newItemTitle
    };

    $.ajax({
        url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items",
        type: "POST",
        contentType: "application/json;odata=verbose",
        data: JSON.stringify(item),
        headers: {
            "Accept": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val()
        },
        success: function (data) {
            success(data);
        },
        error: function (data) {
            failure(data);
        }
    });
}

// Get List Item Type metadata
function GetItemTypeForListName(name) {
    return "SP.Data." + name.charAt(0).toUpperCase() + name.split(" ").join("").slice(1) + "ListItem";
}

Retrieve Item

// READ SPECIFIC ITEM operation
// itemId: The id of the item to get
// listName: The name of the list you want to get items from
// siteurl: The url of the site that the list is in. 
// success: The function to execute if the call is sucesfull
// failure: The function to execute if the call fails
function getListItemWithId(itemId, listName, siteurl, success, failure) {
    var url = siteurl + "/_api/web/lists/getbytitle('" + listName + "')/items?$filter=Id eq " + itemId;
    $.ajax({
        url: url,
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: function (data) {
            if (data.d.results.length == 1) {
                success(data.d.results[0]);
            }
            else {
                failure("Multiple results obtained for the specified Id value");
            }
        },
        error: function (data) {
            failure(data);
        }
    });
}

Retrieve All Items

// occurs when a user clicks the read button
function Read() {
    var listName = "MyList";
    var url = _spPageContextInfo.webAbsoluteUrl;

    getListItems(listName, url, function (data) {
        var items = data.d.results;

        // Add all the new items
        for (var i = 0; i < items.length; i++) {
            alert(items[i].Title + ":" + items[i].Id);
        }
    }, function (data) {
        alert("Ooops, an error occured. Please try again");
    });
}

// READ operation
// listName: The name of the list you want to get items from
// siteurl: The url of the site that the list is in. 
// success: The function to execute if the call is sucesfull
// failure: The function to execute if the call fails
function getListItems(listName, siteurl, success, failure) {
    $.ajax({
        url: siteurl + "/_api/web/lists/getbytitle('" + listName + "')/items",
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: function (data) {
            success(data);
        },
        error: function (data) {
            failure(data);
        }
    });
}

Update

// occurs when a user clicks the update button
function Update() {
    var listName = "MyList";
    var url = _spPageContextInfo.webAbsoluteUrl;
    var itemId = "1"; // Update Item Id here
    var title = "New Updated Title";
    updateListItem(itemId, listName, url, title, function () {
        alert("Item updated, refreshing avilable items");
    }, function () {
        alert("Ooops, an error occured. Please try again");
    });
}

// Update Operation
// listName: The name of the list you want to get items from
// siteurl: The url of the site that the list is in. // title: The value of the title field for the new item
// itemId: the id of the item to update
// success: The function to execute if the call is sucesfull
// failure: The function to execute if the call fails
function updateListItem(itemId, listName, siteUrl, title, success, failure) {
    var itemType = GetItemTypeForListName(listName);

    var item = {
        "__metadata": { "type": itemType },
        "Title": title
    };

    getListItemWithId(itemId, listName, siteUrl, function (data) {
        $.ajax({
            url: data.__metadata.uri,
            type: "POST",
            contentType: "application/json;odata=verbose",
            data: JSON.stringify(item),
            headers: {
                "Accept": "application/json;odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                "X-HTTP-Method": "MERGE",
                "If-Match": data.__metadata.etag
            },
            success: function (data) {
                success(data);
            },
            error: function (data) {
                failure(data);
            }
        });
    }, function (data) {
        failure(data);
    });
}

Delete

// occurs when a user clicks the delete button
function Delete() {
    var listName = "MyList";
    var url = _spPageContextInfo.webAbsoluteUrl;
    var itemId = "1"; // Update Item ID here
    deleteListItem(itemId, listName, url, function () {
        alert("Item deleted successfully");
    }, function () {
        alert("Ooops, an error occured. Please try again");
    });
}

// Delete Operation
// itemId: the id of the item to delete
// listName: The name of the list you want to delete the item from
// siteurl: The url of the site that the list is in. 
// success: The function to execute if the call is sucesfull
// failure: The function to execute if the call fails
function deleteListItem(itemId, listName, siteUrl, success, failure) {
    getListItemWithId(itemId, listName, siteUrl, function (data) {
        $.ajax({
            url: data.__metadata.uri,
            type: "POST",
            headers: {
                "Accept": "application/json;odata=verbose",
                "X-Http-Method": "DELETE",
                "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                "If-Match": data.__metadata.etag
            },
            success: function (data) {
                success(data);
            },
            error: function (data) {
                failure(data);
            }
        });
    },
   function (data) {
       failure(data);
   });
}

Reference

All Available SharePoint Web Template ID

I found good reference from Praveen Hebbar blog and I don’t want to loose it.

In my scenario, this is very useful for SharePoint branding. I utilize it when feature activating event to apply different custom master page for My Site / Search Site based on the Web Template ID.

function Get-SPWebTemplateWithId
{
 $templates = Get-SPWebTemplate | Sort-Object "Name"
 $templates | ForEach-Object {
  $templateValues = @{
   "Title" = $_.Title
   "Name" = $_.Name
   "ID" = $_.ID
   "Custom" = $_.Custom
   "LocaleId" = $_.LocaleId
  }
  New-Object PSObject -Property $templateValues | Select @("Name","Title","LocaleId","Custom","ID")
 }
}

Get-SPWebTemplateWithId | Format-Table

Results Table

AllAvailableWebTemplateID

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Reference
http://blogs.technet.com/b/praveenh/archive/2013/04/04/get-a-list-of-web-templates-and-ids-in-a-sharepoint-site.aspx

Prevent creating folder in SharePoint Document Library and List

Lately I got requirement to prevent users to create folder in SharePoint Document Library and List throughout site collection.
Then I did quick search in codeplex and found someone already did it

From there, I’ve added / updated items in the solution. Below is the list of steps that I’ve done:

  • 1. Create New SharePoint Empty project, called it “CustomDisableFolder” and deploy it as farm solution.
  • 2. Add New Item > Empty Element > called it “RemoveNewFolderRibbon”. Then populate Elements.xml to:
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <CustomAction Id="CustomIdentifier.Ribbon.Documents.New.NewFolder.Hide" Location="CommandUI.Ribbon" RegistrationType="ContentType" RegistrationId="0x">
        <CommandUIExtension>
          <CommandUIDefinitions>
            <CommandUIDefinition Location="Ribbon.Documents.New.NewFolder">
            </CommandUIDefinition>
          </CommandUIDefinitions>
        </CommandUIExtension>
      </CustomAction>
      <CustomAction Id="Remove.ListItem.NewFolder" Location="CommandUI.Ribbon">
        <CommandUIExtension>
          <CommandUIDefinitions>
            <CommandUIDefinition
              Location="Ribbon.ListItem.New.NewFolder" />
          </CommandUIDefinitions>
        </CommandUIExtension>
      </CustomAction>
    </Elements>
    
  • 3. Add New Item > User Control > called it “AdditionalPageHeadUserControl.ascx”. Populate the ascx file with:
    <%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
    <%@ Assembly Name="Microsoft.Web.CommandUI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
    <%@ Import Namespace="Microsoft.SharePoint" %>
    <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AdditionalPageHeadUserControl.ascx.cs" Inherits="CustomWeltmanDisableFolder.ControlTemplates.CustomWeltmanDisableFolder.AdditionalPageHeadUserControl" %>
    <script type="text/javascript">
        //If there is NO JQuery loaded previously
        //window.onload = function () {
        //    var allinputs = document.getElementsByTagName("input");
        //    for (var i = 0; i < allinputs.length; i++) {
        //        if (allinputs[i].getAttribute('value') != null && (allinputs[i].getAttribute('value') == "RadEnableFoldersYes" || allinputs[i].getAttribute('value') == "RadEnableFoldersNo")) {
        //            allinputs[i].setAttribute("disabled", true);
        //        }
        //    }
        //};
     
        // Assume JQuery loaded in master page
        $(function () {
            // Disable New Folder checkbox settings in List / Library Settings
            $("input[id*='RadEnableFoldersYes']").attr("disabled", true);
            $("input[id*='RadEnableFoldersNo']").attr("disabled", true);
        });
    </script>
    
  • 4. Add New Item > Empty Element > called it “AdditionalPageHeadElement”. Populate the Elements.xml into:
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <Control Id="AdditionalPageHead" Sequence="90" ControlSrc="/_ControlTemplates/15/CustomDisableFolder/AdditionalPageHeadUserControl.ascx"></Control>
    </Elements>
    
  • 5. Add New Item > Event Receiver > ListAdded Event Receiver > called it “ListEventReceiver”. Populate ListAdded event to:
    public override void ListAdded(SPListEventProperties properties)
    {
     base.ListAdded(properties);
     SPSecurity.RunWithElevatedPrivileges(delegate()
     {
      using (SPWeb currWeb = new SPSite(properties.SiteId).OpenWeb(properties.Web.ID))
      {
       SPList currList = currWeb.Lists.TryGetList(properties.ListTitle);
       if (currList != null && currList.AllowDeletion)
       {
        currList.EnableFolderCreation = false;
        currList.Update();
       }
      }
     });
    }
    
  • 6. Add New Item > Event Receiver > ItemAdding Event Receiver > called it “ItemEventReceiver”. Populate ItemAdding event to:
    public override void ItemAdding(SPItemEventProperties properties)
    {
     base.ItemAdding(properties);
     if (properties.List != null && properties.List.AllowDeletion && properties.AfterUrl.IndexOf("/New folder") > 0)
     {
      properties.ErrorMessage = "Folder is not allowed, use metadata instead to provide additional information to a file.";
      properties.Status = SPEventReceiverStatus.CancelWithError;
     }
    }
    
  • 7. Add FeatureActivated Event Receiver to the Feature and set the Feature Scope to Site.
    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    {
     SPSecurity.RunWithElevatedPrivileges(delegate()
     {
      using (SPSite site = new SPSite(((SPSite)properties.Feature.Parent).ID))
      {
       foreach (SPWeb eachWeb in site.AllWebs)
       {
        foreach(SPList list in eachWeb.Lists)
        {
         if (list != null && list.AllowDeletion )
         {
          list.EnableFolderCreation = false;
          list.Update();
         }
        }
       }
      }
     });
    }
    
  • 8. The Solution Explorer will going to look like below.DisableFolder3

Results
List / Library New Folder settings set to No and User will not be able to updated it.
DisableFolder4

New Folder button in ribbon gone.
DisableFolder1
DisableFolder5

Assign SharePoint Item Picker control to External Data / BCS Column

Recently, I need to create visual webpart to display the item picker control like External Data / BCS column in list new or edit form.
Let’s go straight on how to assign the item picker as External Data column.

  • 1. Add Item Picker control in ascx file and initialize OnLoad attributes.
    <SharePoint:ItemPicker ID="myPicker" runat="server" OnLoad="myPicker_Load" CssClass="ms-input" />
    
  • 2. In ascx.cs file and OnLoad item picker events.
    protected void myPicker_Load(object sender, EventArgs e)
    {
     try
     {
      // Set extended data
      myPicker.ExtendedData = GetExtendedData("SystemInstanceName", "EntityName", "PrimaryColumnName", "EntityNamespace");
      // Set other properties
      myPicker.AllowTypeIn = true;
      myPicker.AllowEmpty = false;
      myPicker.AutoPostBack = false;
      myPicker.MultiSelect = false;
     }
     catch (Exception ex)
     {
      // Your error handler
     }
    }
    
    private Microsoft.SharePoint.WebControls.ItemPickerExtendedData GetExtendedData(string systemInstanceName, string entityname, string primaryColumnName, string entityNameSpace)
    {
     ItemPickerExtendedData extendedData = null;
     try
     {
      // Associate Network Affiliate Item Picker
      extendedData = new ItemPickerExtendedData();
      extendedData.SystemInstanceName = systemInstanceName;
      extendedData.EntityName = entityname;
      extendedData.PrimaryColumnName = primaryColumnName;
      extendedData.EntityNamespace = entityNameSpace;
     }
     catch (Exception ex)
     {
      // Your error handler
     }
     return extendedData;
    }
    

The next question is, how are we going to get these values “SystemInstanceName”, “EntityName”, “PrimaryColumnName”, “EntityNamespace” ?

  • 1. Create SharePoint list “MyList”, add new External Data column “MyField” to the list.
  • 2. Create simple SharePoint console application project and populate Main method like below.
    private static void Main(string[] args)
    {
     try
     {
      using (SPSite site = new SPSite("YourSiteURL"))
      {
       using (SPWeb web = site.OpenWeb("YourWeb"))
       {
        SPList listResult = web.Lists.TryGetList("MyList");
        if (listResult == null)
         return null;
    
        foreach (SPField eachField in listResult.Fields)
        {
         if (eachField != null && eachField.Title == "MyField" && eachField is SPBusinessDataField)
         {
          //Read in the field schema so that we can obtain extra values to perform a query against the BCS.
          XmlDocument xmlData = new XmlDocument();
          xmlData.LoadXml(eachField.SchemaXml);
    
          //This get all attributes required for External Data column
          string systemInstanceName = xmlData.FirstChild.Attributes["SystemInstance"].Value;
          string primaryColumnName = xmlData.FirstChild.Attributes["BdcField"].Value;
          string entityNameSpace = xmlData.FirstChild.Attributes["EntityNamespace"].Value;
          string entityname = xmlData.FirstChild.Attributes["EntityName"].Value;
          Console.WriteLine(string.Format("SystemInstanceName:{0}; PrimaryColumnName:{1}; EntityNamespace:{2}; EntityName:{3}", systemInstanceName, primaryColumnName, entityNameSpace, entityname));
         }
        }
       }
      }
     }
     catch (Exception ex)
     {
      Console.WriteLine("ERROR: " + ex.Message);
     }
     Console.ReadLine();
    }
    
%d bloggers like this: