Monthly Archives: January 2014

Get and Set External Data / BCS column in SharePoint List

Following from my previous article to configure filtering in Business Connectivity Services, I would like to show you how to get and set External Data / BCS column in SharePoint List.

Get External Data column

private void GetItemByIndex(SPList mylist, int index)
{
    try
    {
        if(mylist.Items.Count < index)
           return;

        SPListItem existingItem = mylist.Items[index];
        string title = existingItem["Title"].ToString();
        string networkAffiliate = existingItem["NetworkAffiliate"].ToString();
        // If you select networkf affiliate Id column to display in external data column (NetworkAffiliate)
        string networkAffiliateId= existingItem["NetworkAffiliate_x003a__x0020_Id"].ToString();
    }
    catch (Exception ex)
    {
        // Error Exception handling
    }
}

Set External Data column
To set the actual external data column itself is straight forward, but it is more complicated to set the secondary external data columns if you included it in external data column settings.

private void InsertNewItem(SPList mylist, string title, string valueId)
{
    try
    {
        SPListItem newItem = mylist.Items.Add();
        newItem["Title"] = title;
        SPBusinessextdataField extdataField = newItem.Fields["NetworkAffiliate"] as SPBusinessextdataField;
        IEntityInstance entityinst = GetEntityInstance(extdataField, valueId, mylist.ParentWeb.Site, newItem);
        SetSecondaryFields(newItem, extdataField, entityinst);
        newItem.Update();
    }
    catch (Exception ex)
    {
        // Error Exception handling
    }
}

private IEntityInstance GetEntityInstance(SPBusinessDataField dataField, string entityId, SPSite site, SPListItem item)
{
    IEntityInstance entInstance = null;
    try
    {
        IEntity entity = GetEntity(site, dataField);
        ILobSystemInstance LobSysteminstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value;

        // Get methods collection 
        foreach (KeyValuePair<string, IMethod> method in entity.GetMethods())
        {
            // Get current method’s instance 
            IMethodInstance methodInstance = method.Value.GetMethodInstances()[method.Key];
            // Execute specific finder method. 
            if (methodInstance.MethodInstanceType == MethodInstanceType.SpecificFinder)
            {
                Identity id = null;

                if (EntityInstanceIdEncoder.IsEncodedIdentifier(entityId))
                {
                    object[] oIDList = EntityInstanceIdEncoder.DecodeEntityInstanceId(entityId);
                    id = new Identity(oIDList[0]);

                    // Execute specific finder method and get the entity instance 
                    entInstance = entity.FindSpecific(id, entity.GetLobSystem().GetLobSystemInstances()[0].Value);
                    item[dataField.RelatedField] = entityId.ToString();
                }
                else
                {
                    object oID = GetTypedIDValue(entityId, entity);
                    id = new Identity(oID);
                    string encodedIdentifier = EntityInstanceIdEncoder.EncodeEntityInstanceId(new object[] { oID });
                    // Execute specific finder method and get the entity instance 
                    entInstance = entity.FindSpecific(id, entity.GetLobSystem().GetLobSystemInstances()[0].Value);
                    item[dataField.RelatedField] = encodedIdentifier;
                }
            }
        }
    }
    catch (Exception ex)
    {
        // Error Exception handling
    }
    return entInstance;
}

private IEntity GetEntity(SPSite site, SPBusinessDataField dataField)
{
    IEntity result = null;
    try
    {
        SPServiceContext context = SPServiceContext.Current; //SPServiceContext.GetContext(site);
        IMetadataCatalog catalog = null;
        BdcService bdcService = SPFarm.Local.Services.GetValue<BdcService>(String.Empty);
        if (null != bdcService && dataField != null)
        {
            catalog = bdcService.GetDatabaseBackedMetadataCatalog(context);
            if (catalog != null)
                result = catalog.GetEntity(dataField.EntityNamespace, dataField.EntityName);
        }
    }
    catch (Exception ex)
    {
        // Error Exception handling
    }
            
    return result;
}

private object GetTypedIDValue(string sID, IEntity oEntity)
{
    object oID = null;
    try
    {
        IIdentifierCollection type = oEntity.GetIdentifiers();
        String sIdentifierType = type[0].IdentifierType.FullName.ToLower().Replace("system.", String.Empty);
                
        //find the instance value based on the given identifier type
        switch (sIdentifierType)
        {
            case "string":
                oID = sID;
                break;
            case "datetime":
                oID = DateTime.Parse(sID, CultureInfo.CurrentCulture);
                break;
            case "boolean":
                oID = Boolean.Parse(sID);
                break;
            case "int64":
                oID = Int64.Parse(sID);
                break;
            case "int32":
                oID = Int32.Parse(sID);
                break;
            case "int16":
                oID = Int16.Parse(sID);
                break;
            case "double":
                oID = Double.Parse(sID);
                break;
            case "char":
                oID = Char.Parse(sID);
                break;
            case "guid":
                oID = new Guid(sID);
                break;
            default:
                oID = sID;
                break;
        }
    }
    catch (Exception ex)
    {
        // Error Exception handling
    }
    return oID;
}

private void SetSecondaryFields(SPListItem listItem, SPBusinessDataField dataField, IEntityInstance entityInstance)
{
    try
    {
        // Convert the entity to a formatted datatable
        System.Data.DataTable dtBDCData = entityInstance.EntityAsFormattedDataTable;

        // Set the BCS field itself (Display Value)
        listItem[dataField.Id] = dtBDCData.Rows[0][dataField.BdcFieldName].ToString();

        // Get the specific finder method to get the columns that returns
        IMethodInstance method = entityInstance.Entity.GetMethodInstances(MethodInstanceType.SpecificFinder)[0].Value;
        ITypeDescriptorCollection oDescriptors = method.GetReturnTypeDescriptor().GetChildTypeDescriptors()[0].GetChildTypeDescriptors();

        // Set the column names to the correct values
        foreach (ITypeDescriptor oType in oDescriptors)
        {
            if (oType.ContainsLocalizedDisplayName())
            {
                if (dtBDCData.Columns.Contains(oType.Name))
                {
                    dtBDCData.Columns[oType.Name].ColumnName = oType.GetLocalizedDisplayName();
                }
            }
        }

        // get the secondary field display names; these should be set
        string[] sSecondaryFieldsDisplayNames = dataField.GetSecondaryFieldsNames();

        // loop through the fields and set each column to its value
        foreach (string columnNameint in sSecondaryFieldsDisplayNames)
        {
            Guid gFieldID = listItem.Fields[String.Format("{0}: {1}", dataField.Title, columnNameint)].Id;
            listItem[gFieldID] = dtBDCData.Rows[0][columnNameint].ToString();
        }
    }
    catch (Exception ex)
    {
        // Error Exception handling
    }
}
Advertisements

SharePoint 2013 New Event Receivers for Groups, Users, Roles and Inheritance

Recently, I’ve come across SharePoint 2013 New Event Receivers for Groups, Users, Roles and Inheritance article while doing some investigation for my other issue. Straight away in my mind, I wished they’ve could done it in SharePoint 2010 and solve my nightmare 2-3 years ago.

How

The way to implement the SPSecurityEventReceiver event receiver is a bit unusual.

  1. Class needs to be created and inherited from SPSecurityEventReceiver.
  2. Then, you need to override desired SPSecurityEventReceiver available methods inside the class.
  3. Finally on FeatureActivated, the SPSecurityEventReceiver needs to be attached to the current web.

You could see more detail in one of my reference links.

Available Methods

SharePoint Group Events:

  • GroupAdded
  • GroupAdding
  • GroupDeleted
  • GroupDeleting
  • GroupUpdated
  • GroupUpdating

SharePoint User Events:

  • GroupUserAdded
  • GroupUserAdding
  • GroupUserDeleted
  • GroupUserDeleting
  • RoleAssignmentAdded
  • RoleAssignmentAdding
  • RoleAssignmentDeleted
  • RoleAssignmentDeleting
  • RoleDefinitionAdded
  • RoleDefinitionAdding
  • RoleDefinitionDeleted
  • RoleDefinitionDeleting
  • RoleDefinitionUpdated
  • RoleDefinitionUpdating

Inheritance Events:

  • InheritanceBreaking
  • InheritanceBroken
  • InheritanceReset
  • InheritanceResetting

Reference

Powershell to determine Features activated / deactivated for all sites inside site collection

Recently, I’ve created power shell script to loop through all sites withing site collection and list all Features activated / deactivated.

Add-PsSnapin Microsoft.SharePoint.PowerShell

## SharePoint DLL
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

$webApplicationURL = $args[0]
$outputFile = $args[1]

$webApp = Get-SPWebApplication $webApplicationURL
set-variable -option constant -name out -value $outputFile

if($webApp -ne $null)
{
 foreach($siteColl in $webApp.Sites)
 {
  if($siteColl -ne $null)
  {
   foreach($subWeb in $siteColl.AllWebs)
   {
    if($subWeb -ne $null)
    {
     # Print each Subsite
     "Site: " + $subWeb.Url | Out-File $outputFile -Append

     # Site Collection Features
     if($subWeb.Url -eq $webApplicationURL)
     {
      $siteFeatures = Get-SPFeature | Where-Object {$_.Scope -eq "Site" }
      if ($siteFeatures -ne $null)
      {
       foreach ($feature in $siteFeatures)
       {
	    # Actived feature
        if ((Get-SPFeature -Site $subWeb.Url | Where-Object {$_.Id -eq $feature.id}) -ne $null)
        {
         "SiteCollFeatureId: " + $feature.Id + "; SiteCollFeatureName: " + $feature.DisplayName + " activated" | Out-File $outputFile -Append
        }
	    # DeActived feature
        elseif ((Get-SPFeature -Site $subWeb.Url | Where-Object {$_.Id -eq $feature.id}) -eq $null)
        {
         "SiteCollFeatureId: " + $feature.Id + "; SiteCollFeatureName: " + $feature.DisplayName + " deactivated" | Out-File $outputFile -Append
        }
       }
      }
     }

	 # Site Features
     $siteFeatures = Get-SPFeature | Where-Object {$_.Scope -eq "Web" }
     if ($siteFeatures -ne $null)
     {
      foreach ($feature in $siteFeatures)
      {
	   # Actived feature
       if ((Get-SPFeature -Web $subWeb.Url | Where-Object {$_.Id -eq $feature.id}) -ne $null)
       {
        "SiteFeatureId: " + $feature.Id + "; SiteFeatureName: " + $feature.DisplayName + " activated" | Out-File $outputFile -Append
       }
	   # DeActived feature
       elseif ((Get-SPFeature -Web $subWeb.Url | Where-Object {$_.Id -eq $feature.id}) -eq $null)
       {
        "SiteFeatureId: " + $feature.Id + "; SiteFeatureName: " + $feature.DisplayName + " deactivated" | Out-File $outputFile -Append
       }
      }
     }
    }
    else
    {
     #Echo $subWeb "does not exist"
     $subWeb + "does not exist" | Out-File $outputFile -Append
    }
   }
   $siteColl.Dispose()
  }
  else
  {
   #Echo $siteColl "does not exist"
   $siteColl + " does not exist" | Out-File $outputFile -Append
  }
 }
}
else
{
 #Echo $webApplicationURL "does not exist, check the WebApplication name"
 $webApplicationURL + " does not exist" | Out-File $outputFile -Append
}

Remove-PsSnapin Microsoft.SharePoint.PowerShell

#Echo Finish
$webApplicationURL + " finish" | Out-File $outputFile -Append
"" | Out-File $outputFile -Append

Save the above power shell script as GetFeaturesInsideSiteCollection.ps1
To run the power shell script, you need to pass the site collection URL and output file path.

.\GetFeaturesInsideSiteCollection.ps1 http://yoursiteurl.com D:\temp\output.txt
%d bloggers like this: