Source Code C#

Get Secure String Pass CSOM

Posted on Updated on

private static SecureString GetPass(string pass)
{
    // Instantiate the secure string.        
    var secureStr = new SecureString();
    if (pass.Length <= 0) return secureStr;
    foreach (var c in pass.ToCharArray()) secureStr.AppendChar(c);
    return secureStr;
} 

Provisionate MasterPage and CSS with Feature

Posted on Updated on

Sometimes, when you don’t want to use Powershell, you can set your branding from a Feature, it’s the old procedure but very “elastic”.

In the bellow sample, I’ll give you the option to change you master page to Front Office and Back Office, you can also define your CSS File.

I’m processing all Sub Webs also, just change what you want. This is a Feature SCOPE Site

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    using (var site = properties.Feature.Parent as SPSite)
    {
        if (site == null) return;
        using (var web = site.OpenWeb())
        { 
            var masterUrl = web.Site.ServerRelativeUrl == "/" ? 
                "/_catalogs/masterpage/YOURCustomFO.master" : web.Site.ServerRelativeUrl + 
                                                            "/_catalogs/masterpage/YOURCustomFO.master";
            var customMasterUrl = web.Site.ServerRelativeUrl == "/" ? 
                "/_catalogs/masterpage/seattle.master" : web.Site.ServerRelativeUrl + 
                                                         "/_catalogs/masterpage/seattle.master";
            //string cssUrl = web.Site.ServerRelativeUrl == "/" ? "/Style Library/xx.css" : web.Site.ServerRelativeUrl + "/Style Library/xx.css";

            #region MasterPage e CSS

            // Define Master page for FO and BO
            web.CustomMasterUrl = masterUrl;
            web.MasterUrl = customMasterUrl;

            //Alternate CSS URL 
            //web.AlternateCssUrl = cssUrl;

            // inheritance settings
            web.AllProperties["__InheritsMasterUrl"] = "True";
            web.AllProperties["__InheritsCustomMasterUrl"] = "True";
            //web.AllProperties["__InheritsAlternateCssUrl"] = "True";

            web.Update();

            foreach (SPWeb subWeb in web.Webs)
            {
                try
                {
                    ProcessSubWebs(subWeb);
                }
                finally 
                {
                    if (subWeb != null)
                        subWeb.Dispose();
                }
            }
            #endregion
        }
    }
} 

Enterprise Keywords TaxKeyword Tag Cloud

Posted on Updated on

In this post, i will help you to generate a Tag Cloud based on the TaxKeyword, the default enterprise TAG for SharePoint. This sample is for OOTB or not. I’m using SharePoint Search.

Let’s roll to the search method:

Now that we have the DataTable let´s get the Tags from the TAGS Field

/// <summary>
/// Executes the key word search.
/// </summary>
/// <param name="queryText">The query text.</param>
/// <param name="siteUrl"></param>
/// <param name="queryLimit"></param>
/// <returns></returns>
public DataTable ExecuteKeyWordSearch(string queryText, string siteUrl, int queryLimit)
{
    var retResults = new DataTable(); 
    using (var site = new SPSite(siteUrl))
    {
        using (var query = new KeywordQuery(site))
        {
            query.QueryText = queryText;
            query.KeywordInclusion = KeywordInclusion.AllKeywords;
            query.RowLimit = queryLimit;

            query.SelectProperties.Add("Tags");

            var se = new SearchExecutor();
            var rtc = se.ExecuteQuery(query);
            if (rtc.Count <= 0) return null;
            var results = rtc.Filter("TableType", KnownTableTypes.RelevantResults);
            var resultTables = results as IList<ResultTable> ?? results.ToList();
            if (results != null && resultTables.Count() == 1)
                retResults.Load(resultTables.First(), LoadOption.OverwriteChanges);
            return retResults;
        }
    }
}

Let’s replace all “L0|#” and remove all Guid’s

public List<string> GetSafeTagName(string tag)
{
    tag = tag
        .Replace("L0|#", "");
    tag = Regex.Replace(tag, @"([a-z0-9]{8}[-][a-z0-9]{4}[-][a-z0-9]{4}[-][a-z0-9]{4}[-][a-z0-9]{12})", ""); 
    char[] delimiter = { ';' };
    var parts = tag.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
    return parts.ToList();
} 

 
var list = new List<string>(); 
foreach (var refiners in from dr in _dt.AsEnumerable()
                         where dr["Tags"].ToString() != string.Empty
                         select GetSafeTagName(dr["Tags"].ToString()))
{
    list.AddRange(refiners);
}
 

After having our tags, let’s take a count for each TAG, I’m taking 11 for my render

var q = (from x in list
 group x by x
     into g
     let count = g.Count()
     orderby count descending
     select new { Value = g.Key, Count = count }).Take(11); 
 

So? Let´s render. I’m having a bug :), but let´s remove the first 2 characters

foreach (var x in q)
{
    x.Value.Substring(2)
    x.Count
} 
 

THE TAG CLOUD

This is an example, but you can refine it. I’m taking the total, that is 11, and passing the xCount

private static string TagLogic(double xCount, double xTotal)
    {
        string ret;
        var count = xCount;
        var percent = (count / xTotal) * 100; 
        if (percent < 20)
        {
            ret = "10";
        }
        else if (percent < 50)
        {
            ret = "20";
        }
        else if (percent < 70)
        {
            ret = "50";
        }

        else
        {
            ret = "70";
        }
        return ret;
    }
} 

Metadata Navigation, the Server Side code

Posted on Updated on

Using metadata navigation in SharePoint 2013, although all problems identified and documented over the Net, is very powerful. As in all features, this one is no exception, as to be configured properly.

Narahari Patro, have a sample for creating with Powershell, i made some small modifications bellow, see original post.

This samples are based in 2 Levels, change for more, this is only to provide a sample of it, enjoy

#change these variables based on environment
$siteName = "http://yoursite.local" 
$termStoreName = "Managed Metadata Service"
$termGroupName = "For Group"
$termsetName = "Term Name"
$appendUrl = "http://yoursite.local" 
function CreateTerm( $parent, $name, $url )  
 {  
  Write-Host "Adding term $name to parent $parent.Name"  
   $term = $parent.CreateTerm("$name", 1033)  
  $term.IsAvailableForTagging = $true    
  $newUrl = $url
  if(!$url.ToLower().Contains("http"))
  {  
  # Logic to append site url to relative path to create complete url which is needed for Simple Link Navigation
    $newUrl = $appendUrl + $url
  }
  $term.SetLocalCustomProperty("_Sys_Nav_SimpleLinkUrl", $newUrl)   
  return $term  
 } 

# NAVEGAÇÃO INICIAL

$site = Get-SPSite -Identity $siteName
$session = Get-SPTaxonomySession -Site $siteName
$termStore = $session.TermStores[$termStoreName]
$group = $termstore.CreateGroup($termGroupName)
$group.Description = "Navegação Global"
$termStore.CommitAll()

Write-Host "TermGroup - $termGroupName created successfully" 

$termsetName = "Navegação Global"
$termSet = $group.CreateTermSet($termsetName,2070)
$termSet.Description = "Navigation TermSet description"
$termSet.IsAvailableForTagging = $false
$termSet.IsOpenForTermCreation = $false
$navigationSet = $group.TermSets[$termsetName]
$navigationSet.SetCustomProperty("_Sys_Nav_IsNavigationTermSet", "True")
$termStore.CommitAll()

Write-Host "TermSet - $termsetName created successfully" 

# create terms for My site

$areaTrabalhoTerms = CreateTerm $termSet "R1" "/work"
$colaboradoresTerm = CreateTerm $termSet "R2" "/users"
$empresaTerm = CreateTerm $termSet "R3" "/corp"

$termStore.CommitAll()

$termSet.CustomSortOrder = $areaTrabalhoTerms.id.ToString()+":"+$colaboradoresTerm.id.ToString()+":"+$empresaTerm.id.ToString()

# create sub terms for My site

$term1 = CreateTerm $areaTrabalhoTerms "Root1" "/work/work1"
$term2 = CreateTerm $areaTrabalhoTerms "Root2" "/work/work2"
$term3 = CreateTerm $areaTrabalhoTerms "Root3" "/work/work3"

$term4 = CreateTerm $colaboradoresTerm "Root4" "/users/users1"
$term5 = CreateTerm $colaboradoresTerm "Root5" "/users/users2"

$term7 = CreateTerm $empresaTerm "SubRoot1" "/corp/corp1/"
$term8 = CreateTerm $empresaTerm "SubRoot2" "/corp/corp2"
$term9 = CreateTerm $empresaTerm "SubRoot3" "/corp/corp3"
$term10 = CreateTerm $empresaTerm "SubRoot4" "/corp/corp4"
$term11 = CreateTerm $empresaTerm "SubRoot5" "/corp/corp5"
$term12 = CreateTerm $empresaTerm "SubRoot6" "/corp/corp6"
$term13 = CreateTerm $empresaTerm "SubRoot7" "/corp/corp7"
$term14 = CreateTerm $empresaTerm "SubRoot8" "/corp/corp8"

$areaTrabalhoTerms.CustomSortOrder = $term1.id.ToString() +":"+ 
    $term2.id.ToString() +":"+ 
    $term3.id.ToString()
$colaboradoresTerm.CustomSortOrder = $term4.id.ToString() +":"+ 
    $term5.id.ToString() +":"+ 
    $term6.id.ToString()
$empresaTerm.CustomSortOrder = $term7.id.ToString() +":"+ 
    $term8.id.ToString() +":"+ 
    $term9.id.ToString() +":"+ 
    $term10.id.ToString() +":"+ 
    $term11.id.ToString() +":"+ 
    $term12.id.ToString() +":"+ 
    $term13.id.ToString() +":"+ 
    $term14.id.ToString()
$termStore.CommitAll()

Write-Host "Terms for TermSet - $termsetName created successfully"  
 

The advantages are enormous, like you can deprecate one item without delete it, then can be reused. I made a sample with c# Server Side to read this items.

image

protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            var site = SPContext.Current.Site;
            var session = new TaxonomySession(site); 
            if (session.TermStores.Count == 0) return;
            var termStore = session.TermStores["Managed Metadata Service"];
                foreach (var  group in  termStore.Groups)
                {
                    if (@group.Name != "Your Group Name") continue;
                    foreach (var termSet in  @group.TermSets)
                    {
                        if (termSet.Name != "Your Root TermSet") continue;
                        foreach (var term in termSet.Terms)
                        {
                            if (term.IsDeprecated == false)
                            {                                        
                                 Console.Write(term.Name)

                                foreach (var t in term.Terms)
                                {
                                    if (t.IsDeprecated == false)
                                    {
                                        var url = t.LocalCustomProperties["_Sys_Nav_SimpleLinkUrl"];
                                        Console.Write(url + t.GetDefaultLabel(2070) 
                                    }
                                }
                            }
                        }
                    }
                }
        });
    }
    catch (Exception ex)
    {
        //Log
    }
} 

Working with Property Bags Programmatically

Posted on Updated on

Property Bags are very powerful, they can store information in an Hash Table in IIS at several levels

Property Bags can be defined in the following levels:

Farm (SPFarm class)
Web application (SPWebApplication class)
Site collection (SPSite class)
Site (SPWeb class)
List (SPList class)

I wrote an Article for 2010 in here, take a look

//Add
protected static void AddProperty(SPWeb web, string key, string value)
{
    web.AllowUnsafeUpdates = true;
    web.Properties[key] = value;
    web.AllProperties[key] = value;
    web.Update();
    web.Properties.Update();
} 
//Remove
protected void RemoveProperty(SPWeb web, string key)
{
    web.AllowUnsafeUpdates = true;
    web.AllProperties.Remove(key);
    web.Properties[key] = null;
    web.Update();
    web.Properties.Update();
}

//Get
protected string GetPropertyValue(SPWeb web, string key)
{
    return web.AllProperties.ContainsKey(key) ? web.AllProperties[key].ToString() : null;
} 

Create Terms in Metadata Service Programmatically

Posted on Updated on

Working with Taxonomy Fields that created in Visual Studio without OOTB, it’s not a peace of cake. You have to follow some rules:

  1. In a Feature Receiver, Scoped SITE use the bellow Override
  2. Then you have to activate your field  (Bind) to a specific GUID, if you not it become disabled “Grayed”
    1. Use class bellow “Taxonomy”
  3. For XML Declarative find here you may find other options also
using UTIL = ChangeYourNameSpace.Utils; 
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    try
    {
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            var site = properties.Feature.Parent as SPSite;
            var session = new TaxonomySession(site);

            if (session.TermStores.Count == 0) return;
            var termStore = session.TermStores["Managed Metadata Service"];

            if (termStore.Groups.All(x => x.Name != "MY TAGs"))
            {
                //TAGS
                var group = termStore.CreateGroup("MY TAGA");
                var termSetTag = group.CreateTermSet("TAGs");
                termSetTag.CreateTerm("Tag 1", 1033);
                termSetTag.CreateTerm("Tag 2", 1033);
                termSetTag.CreateTerm("Tag 3", 1033);                
                termSetTag.IsAvailableForTagging = true;
                termSetTag.IsOpenForTermCreation = true;
                termSetTag.Contact = "intranet@yourcorp.pt";
            }

            if (termStore.Groups.All(x => x.Name != "MY Documentos"))
            {
                //Tech Documents
                var groupDoc = termStore.CreateGroup("MY Documentos");

                var termSetDocTec = groupDoc.CreateTermSet("My Docs 1");
                termSetDocTec.CreateTerm("Tag 1", 1033);
                termSetDocTec.CreateTerm("Tag 2", 1033);
                termSetDocTec.CreateTerm("Tag 3", 1033);
                termSetDocTec.IsAvailableForTagging = true;
                termSetDocTec.IsOpenForTermCreation = true;
                termSetDocTec.Contact = "intranet@yourcorp.pt";

                var termSetDocCorp = groupDoc.CreateTermSet("My Docks 2");
                termSetDocCorp.CreateTerm("Tag 1", 1033);
                termSetDocCorp.CreateTerm("Tag 2", 1033);
                termSetDocCorp.CreateTerm("Tag 3", 1033);               
                termSetDocCorp.IsAvailableForTagging = true;
                termSetDocCorp.IsOpenForTermCreation = true;
                termSetDocCorp.Contact = "intranet@yourcorp.pt";
            }

            termStore.CommitAll();

            //TAGGING
            UTIL.Taxonomy.ActivateTaxField(site, "{9358ED54-0957-4A56-8047-F940C60D2024}", "TAG's", "TAGs");

            //Documents
            UTIL.Taxonomy.ActivateTaxField(site, "{ECA6E20C-20E0-433C-8D3C-667AD9C25E99}", "Documents", "My Documents");
        });
    }
    catch (Exception ex)
    {
        //Log
    }
}

public static class Taxonomy
{
    public static void ActivateTaxField(SPSite site, string taxonomyGuid,
        string taxonomyGroup, string taxonomyTerm)
    {
        try
        {
            var fieldId = new Guid(taxonomyGuid);
            if (!site.RootWeb.Fields.Contains(fieldId)) return;

            var session = new TaxonomySession(site);

            if (session.TermStores.Count == 0) return;
            var termStore = session.TermStores["Managed Metadata Service"];
            var group = termStore.Groups[taxonomyGroup];
            var termSet = @group.TermSets[taxonomyTerm];

            var field = site.RootWeb.Fields[fieldId] as TaxonomyField;

            if (field == null) return;
            field.SspId = termSet.TermStore.Id;
            field.TermSetId = termSet.Id;
            field.TargetTemplate = string.Empty;
            field.AnchorId = Guid.Empty;
            field.Update();
        }
        catch (Exception ex)
        {
            //Log
        }

    }
} 

Good Luck 😉

Add Enterprise Keywords to List with Receiver

Posted on Updated on

Let’s see, a easy tag field is the “TaxKeyword”, the default for “Enterprise Keywords”. The advantage is that he is already at the Search Schema an Indexed, so you can use in all objects that you want, Page Layouts for Publishing Pages, Lists, whatever.

How to do it in a SharePoint Feature Receiver?

SCOPE: Web

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    var web = properties.Feature.Parent as SPWeb;
    AddDocs(web);
}

private void AddDocs(SPWeb web)
{
    if (web == null) return;
    var list = web.Lists.TryGetList("Documents");
    if (list != null)
    {
        var field = list.ParentWeb.AvailableFields["Enterprise Keywords"];
        if (!list.Fields.ContainsField("Enterprise Keywords"))
        {
            list.Fields.Add(field);
            list.EnableModeration = true;
            list.EnableVersioning = true;

            var view = list.Views[0];
            view.ViewFields.Add(field);
            view.Update();

            list.Update();
            web.Dispose();
        }
        else
        {
            //Log
        }
    }
    else
    {
        //Log
    }
} 

 

How to add it to a Page Layout?

<%@ Register TagPrefix="Taxonomy" Namespace="Microsoft.SharePoint.Taxonomy" Assembly="Microsoft.SharePoint.Taxonomy, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>


 <Taxonomy:TaxonomyFieldControl FieldName="TaxKeyword" InputFieldLabel="My Custom Tags" runat="server"></Taxonomy:TaxonomyFieldControl>