Sivarajan's Blog

SharePoint | Office 365 | Azure | JavaScript

SharePoint 2013 Search Refinements for External Content Type (BCS) data

In my previous post, I have done the complete walkthrough that how to bring the external data into search index and presenting the data into publishing portal using Content Search WebPart. We will see here that how to filter the content search web part data using search refinement web part. Overview: In my previous post, we saw that how to bring the movie table into search results and now we are going to filter the movies list based on Genre or Production Company. This is the data model I am going to use. And this is the final output for this post.     Stage 1: Understand the data model We can not use the same database relationships inside the SharePoint search and we have to bring the Genre and Production Company data along with Movie data. But each movie item has more than one Genres or Production companies. Our search results will be duplicate if we use the above query. So I have created two user defined functions “CombineMovieProductionCompanies” and “CombineMovieGenres” and modified the existing view  “GetMovie” and the result will be look like below. Stage 2: Refresh the External Content Types Now the data is ready and we have created a External content type Movie in the previous post. Here we are going to add the two more columns with existing content type. Open the SharePoint Designer and edit the Movie external content type. Double click the GetMovieRead Item and include the Genres and ProductionCompanies column. Like that, double click the GetMovieRead List and repeat the step 2. Step 3: Creating a Managed Properties In the previous post, we have created a content source for movie external content type. In addition to that, we are going to create two more Managed Properties. Full crawl the Movie content source. Now Crawled Properties will be available to create a Managed Properties. Go to Search Application –> Search Schema and create the property MovieGenres and set the Allow multiple values to true. And map the Mapping to crawled properties to  GetMovieRead ListElement.Genres Repeat the step 3 and 4 to create the managed property for MovieProductionCompanies and map with GetMovieRead ListElement.ProductionCompanies Step 4: Create a content enrichment web service I am not going to explain about content enrichment web service callout. you can find the detailed walkthrough here. Custom content processing with the Content Enrichment web service callout How to: Use the Content Enrichment web service callout for SharePoint Server For our case, while crawling the data, custom WCF service will be invoked and the managed properties will be passed as parameter.  GenreEnrichmentService private readonly ProcessedItem processedItemHolder = new ProcessedItem         {             ItemProperties = new List<AbstractProperty>()         };               public ProcessedItem ProcessItem(Item item)         {             var genreProperty = item.ItemProperties.Where(p => p.Name == "MovieGenres").FirstOrDefault();             Property<List<string>> genreCol = genreProperty as Property<List<string>>;             if (genreCol != null && genreCol.Value.Count > 0)             {                 string[] propValues = genreCol.Value.First().Split('#');                 genreCol.Value.Clear();                 foreach (string value in propValues)                 {                     genreCol.Value.Add(value);                 }                 processedItemHolder.ItemProperties.Add(genreCol);             }             return processedItemHolder;         }   For example, the input data will be Adventure#Fantasy#Action#Science Fiction#Family and the output of the above code will be multiple items. So each movie will have multiple Genres instead of single value. Like that, we have to create a another service called ProductionCompaniesEnrichmentService. Step 5: Configure the Refinement Web Part Open the publishing site and edit the page. Go to Ribbon –> Web Part –> Search and add Refinement web part. Edit web part and make sure the Refinement Target to Content Search – Default. Move the MovieGenres, MovieProductionCompanies and MovieVoteAverage to selected refiners After adding the refiners, set the DisplayName for each items. Now Save the page and try the refiners. Movie lists will be filtered based on refiners. Summary In this post, we saw that how to handle one to many relationships External Content Type (BCS) data with Search Refinement WebPart using Content Enrichment Web Service callout. This web service will be available only in SharePoint 2013 Enterprise.

How to crawl the specific lists in SharePoint foundation 2013

I had a chance to work with search functionalities in SharePoint foundation 2013. In SharePoint server 2013, we have a lot of options are available for crawl restrictions but we do not have many options in foundation. Scenario I have created two lists “Users” and “Articles” in my site collection and SharePoint search should crawl only “Articles” list. Steps 1. Open the Central Administration 2. In Application Management, select “Manage service applications” Note : If the Search Service Application is not available, please configure the search service using configuration wizards again. 3. Select the “Crawl Rules” in the left panel 4. Click “Add Crawl Rule” and create the exclude rule for whole site   5. Again click the "Add Crawl Rule” to include rule for “Articles” list 6. Now select the “Content Sources” and full crawl the “Local SharePoint sites” 7. After successful crawl, try the few keyword search in your site collection. 8. You can able to see the search results which is only related to “Articles” list not “Users” list. Summary I hope that this is a easiest way to control content crawl in foundation. Like that we can write lot of rules using regular expression to improve our search crawl qualities.

SharePoint 2013 Chart WebPart Using HTML 5 RGraph with WCF REST Services

Overview Chart WebPart is not available in SharePoint Server 2013 and we have to use excel services as a alternative to this. But it will be available only with enterprise edition. For SharePoint foundation / standard edition, we can use the ASP.NET charts or third party chart controls. In this walkthrough, we will see that how to leverage the RGraph for SharePoint charts implementations. What is RGraph? RGraph is a HTML5 charts library that uses the HTML5 canvas tag to draw and supports over twenty different types of charts and click here for more information about RGraph and also you can download the javascript libraries here. What is the Advantage of using RGraph with SharePoint? Currently I am working lot of charts related implementations in SharePoint 2013 and I found that it is more flexible and fastest one while comparing with ASP.NET chart controls. The main advantage is that it is 100% client side rendering and easily change the data source / chart types without post back. Chart Data Source For this walkthrough, I am using SharePoint foundation 2013 and I have created a list called “Income Tracker” Now the chart data source is ready and we have a multiple options to expose the data to client. SharePoint Client Object Model (ECMA Scripts) ListData.svc Custom WCF Services I am going to use the custom WCF service for data retrieval. Because I have done the detailed walkthrough for custom WCF services earlier and you can find the step by step walkthrough here. SharePoint Solution Structure I have created the solution structure like below, You can find the complete code implementation below, public class GraphData     {         public List<string> ChartLabels { get; set; }         public List<int> IncomeValues { get; set; }         public List<int> ExpenseValues { get; set; }         public GraphData()         {             ChartLabels = new List<string>();             IncomeValues = new List<int>();             ExpenseValues = new List<int>();         }              } [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]       public class TrackerService : ITrackerService     {         public GraphData Get()         {             GraphData graphData = new GraphData();             SPList incomeTracker = SPContext.Current.Web.Lists["Income Tracker"];             if(incomeTracker != null)             {                 foreach (SPListItem item in incomeTracker.Items)                 {                     graphData.ChartLabels.Add(item.Title);                     graphData.IncomeValues.Add(Convert.ToInt32(item["Income"]));                     graphData.ExpenseValues.Add(Convert.ToInt32(item["Expense"]));                                 }             }             return graphData;         }     } function RenderChart(graphData) {     var data = mixArrays(graphData.IncomeValues, graphData.ExpenseValues);     var bar = new RGraph.Bar('cvs', data);     bar.Set('chart.labels', graphData.ChartLabels);     bar.Set('chart.gutter.left', 65);     bar.Set('colors', ['#058DC7', 'Gradient(#50B332:#B1E59F)', 'Gradient(#EC561B:#F59F7D)']);     bar.Set('hmargin', 15);     bar.Set('strokestyle', 'white');     bar.Set('linewidth', 2);     bar.Set('shadow', true);     bar.Set('shadow.offsetx', 1);     bar.Set('shadow.offsety', 0);     bar.Set('shadow.blur', 1);     ClearAndRedraw(bar); } function ClearAndRedraw(obj) {     RGraph.ClearAnnotations(obj.canvas);     RGraph.Clear(obj.canvas);     obj.Draw(); }   Deploy the solution and add the VisualChart web part in site pages. The chart will be rendered like below. Summary Currently I am doing lot of fun with RGraph and surely I will write some more posts regarding RGraph integrations related challenges with SharePoint. Download Source Code

How to enable page level permission in SharePoint 2013

Overview Currently I am working a internet facing site using SharePoint 2013 with the mixed contents (secured and unsecured). In my earlier post, I have explained on how to enable the mixed authentications (Windows and Custom FBA). In this post, we will see that how to enable the permissions at item level / page level. In Site Pages list, all the pages will be available to every user groups. Instead of that, we will see here on how to show or hide the pages based on user groups. 1. Create two groups “Parents” and “Students” and added few users in that groups for testing purpose.         2. Create the new Wiki library “AuthPages” and create the few pages. For example, I have created the pages like “StudentPage1.aspx”, “ParentPage1.aspx” and “CommonPage.apsx”. 3. Create a SharePoint 2013 Empty solution 4. Add the new feature called “PageLevelPermission” and also add the event receiver for your feature. 5. Add the below method to remove all the item level permissions from the “AuthPages” list. private static void RemoveAllPermissions(SPListItem CurrentlistItem)         {             CurrentlistItem.BreakRoleInheritance(true);             SPRoleAssignmentCollection SPRoleAssColn = CurrentlistItem.RoleAssignments;             for (int i = SPRoleAssColn.Count - 1; i >= 0; i--)             {                 SPRoleAssColn.Remove(i);             }         }   7. Like that use the below method to enable the item level permission to your list. private static void GrantPermission(SPListItem CurrentListItem, SPWeb oSPWeb, SPRoleType SPRoleType, SPPrincipal SPPrincipal)         {             SPRoleDefinition oSPRoleDefinition = oSPWeb.RoleDefinitions.GetByType(SPRoleType);             SPRoleAssignment oSPRoleAssignment = new SPRoleAssignment(SPPrincipal);                          oSPRoleAssignment.RoleDefinitionBindings.Add(oSPRoleDefinition);                          CurrentListItem.RoleAssignments.Add(oSPRoleAssignment);                          CurrentListItem.Update();                     } 6. Then Remove the access for “Anonymous User” group. This is will applicable if you enabled anonymous access for your site.   list.BreakRoleInheritance(true);                     list.AnonymousPermMask64 = SPBasePermissions.EmptyMask; 7. Final code for apply the permission public override void FeatureActivated(SPFeatureReceiverProperties properties)         {             if (properties.Feature.Definition.Scope == SPFeatureScope.Site)             {                 SPWeb currentWeb = ((SPSite)properties.Feature.Parent).OpenWeb();                 if (currentWeb != null)                 {                     string[] studentPages = new string[]{"CommonPage.aspx","StudentPage1.aspx"};                     string[] parentPages = new string[] { "CommonPage.aspx", "ParentPage1.aspx" };                     SPList list = currentWeb.Lists["AuthPages"];                     //Remove the existing permissions                     foreach (SPListItem item in list.Items)                     {                         RemoveAllPermissions(item);                     }                     //Break the permission to hide the list for Anonymous users.                     //The AuthPages will be available for authenticated users.                     list.BreakRoleInheritance(true);                     list.AnonymousPermMask64 = SPBasePermissions.EmptyMask;                     if (currentWeb.SiteGroups["Students"] != null && currentWeb.SiteGroups["Parents"] != null)                     {                         //Add the new permissions                         foreach (SPListItem item in list.Items)                         {                             if (studentPages != null && studentPages.Contains(item.Name))                                 GrantPermission(item, currentWeb, SPRoleType.Reader, currentWeb.SiteGroups["Students"]);                             if (parentPages != null && parentPages.Contains(item.Name))                                 GrantPermission(item, currentWeb, SPRoleType.Reader, currentWeb.SiteGroups["Parents"]);                         }                     }                 }             }   8. Login the system using credentials for “Students” or “Parents” and just try to access the pages. If you are login as "Students”, you can not access the “ParentPage1.aspx”. Conclusion In my previous post, we saw that how to create the site with mixed mode authentication and here we saw that how to provide the page level (item level) permission to list. Even though, some one can able to access the “Site Contents”, “Lists and Libraries”. In the next post, we will see that how to control this based on Groups.