Monthly Archives: April 2013

Custom User Control in SharePoint 2010

In this post, I would like to show you how easy to implement Custom User Control in SharePoint 2010. Actually, this is not only for SharePoint 2010, but it can only be useful for other SharePoint versions.

The goal is to create simple custom user control to display carousel images from image library and place the user control in master page top banner.

uc2
uc3

Below is the list of step by step guide:

  1. Upload images to your Image Library on root site and set the title to start with “light”.
    uc6
  2. Open Visual Studio 2010 > File > New > Project > Select Empty SharePoint Project. Enter the project name and location. Then click OK.
    uc4
  3. In SharePoint Customization Wizard, Enter your local site URL and Select Deploy as farm solution. Then click Finish.
  4. Right click the project in solution explorer, select Add > New Item > User Control > Enter the User Control Name. Then click Add.
    uc1
  5. Rename the Custom User Control folder under ControlTemplates to MyCustomUserControl.uc5
  6. Add Literal Control to the MyUserControl.ascx in Source code mode.
    <%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
    <%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.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=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyUserControl.ascx.cs" Inherits="MyCustomUserControl.ControlTemplates.MyCustomUserControl.MyUserControl" %>
    <asp:Literal ID="Literal1" runat="server"></asp:Literal>
    
  7. Ensure jQuery and jqFancyTransitions plug-ins added to your master page, I’ve showed how to add it in previous article about Custom SharePoint 2010 Branding.
  8. Update Page_Load method to look like below. It will query the Image library with title contains “light” and use images results to display the carousel banner.
    using System;
    using System.Web.UI;
    using Microsoft.SharePoint;
    using System.Text;
    
    namespace MyCustomUserControl.ControlTemplates.MyCustomUserControl
    {
        public partial class MyUserControl : UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                StringBuilder sb = new StringBuilder();
    
                using (SPWeb web = SPContext.Current.Site.RootWeb)
                {
                    SPList lstImage = web.Lists["Images"];
                    if (lstImage != null)
                    {
                        SPQuery query = new SPQuery();
                        query.Query = "<Where><Contains><FieldRef Name='Title' /><Value Type='Text'>light</Value></Contains></Where>";
                        SPListItemCollection coll = lstImage.GetItems(query);
                        if (coll.Count > 0)
                        {
                            sb.AppendLine("<script>");
                            sb.AppendLine("$(document).ready( function(){ ");
                            sb.AppendLine("$('#slideshowBannerHolder').jqFancyTransitions({ width: 849, height: 112, strips: 1, delay: 5000, stripDelay: 50, titleOpacity: 0, navigation: false }); ");
                            sb.AppendLine("});");
                            sb.AppendLine("</script>");
                            sb.AppendLine("<div id='slideshowBannerHolder'>");
                            foreach (SPListItem eachImage in coll)
                            {
                                sb.AppendLine(String.Format("<img src='{0}' alt='{1}' />", web.Url + "/" + eachImage.File.Url, eachImage.Title));
                            }
                            sb.AppendLine("</div>");
                        }
                    }
                    else
                    {
                        sb.Append("<div id='slideshowBannerHolder'>Image list NOT found.</div>");
                    }
                    Literal1.Text = sb.ToString();
                }
            }
        }
    }
    
  9. Register and Place the user control to your custom master page.Register your custom user control on the top section of master page.
    <%@ Register TagPrefix="MyUserControl"  TagName="CUS" Src="~/_controltemplates/MyCustomUserControl/MyUserControl.ascx" %>
    

    In top navigation section, place your custom user control.

                <div id="TopBanner">
                    <MyUserControl:CUS id="MyUserControl1" runat="server" />
                </div>
    
  10. Build and Deploy your solution.

Results

Yeah … you have carousel banner in your SharePoint site.

uc2
uc3

Advertisements

Custom SharePoint 2010 Branding

In this article, I would like to share my experience in applying custom branding for SharePoint 2010. Below is the step by step guide to create custom branding in SharePoint 2010.

  1. Open Visual Studio 2010 > File > New Project > Empty SharePoint Project, enter the Project Name and Location. Then click OK.
    branding1
  2. In SharePoint Customization Wizard, Enter your local site URL and Select Deploy as sandboxed solution. Then click Finish.
    branding2
  3. Right click on the project in Solution Explorer, then select Add > New Item > Module. Then enter the Module Name is MasterPage.
    branding5
  4. Remove sample.txt from MasterPage module and add clean SharePoint 2010 master page from codeplex. Then rename the master page file to MyMasterPage.master
  5. Update Elements.xml in MasterPage module.
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <Module Name="MasterPage" Path="MasterPage" Url="_catalogs/masterpage">
        <File Url="MyMasterPage.master" Type="GhostableInLibrary" >
          <Property Name="UIVersion" Value="4" />
          <Property Name="ContentTypeId" Value="0x010105" />
        </File>
      </Module>
    </Elements>
    
  6. Right click on the project in Solution Explorer, then select Add > New Item > Module. Then enter the Module Name is Style Library. Create Folders structure to be like below and Add files required like images, java scripts and css.
    branding3
  7. Update Elements.xml in Style Library module.
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <Module Name="Style Library" Path="Style Library\MyCustomBranding" Url="Style Library/MyCustomBranding">
        <File Path="MyCustomStyle.css" Url="MyCustomStyle.css" />
        <File Path="Scripts\jqFancyTransitions.1.8.min.js" Url="Scripts/jqFancyTransitions.1.8.min.js" />
        <File Path="Scripts\jquery-1.8.1.min.js" Url="Scripts/jquery-1.8.1.min.js" />
      <File Path="Images\Logo.jpg" Url="Images/Logo.jpg" />
    </Module>
    </Elements>
    
  8. Add Event Receiver to your MyCustomBranding Feature to apply custom branding, alternative css and logo when feature activated. Also, revert back to default when feature deactivating.
    using System;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Security;
    
    namespace MyCustomBranding.Features.MyCustomBrandingFeature
    {
        ///
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
        ///
        ///
        /// The GUID attached to this class may be used during packaging and should not be modified.
        ///
    
        [Guid("27a7158e-9b23-48d3-bc77-0b33345a71cb")]
        public class MyCustomBrandingFeatureEventReceiver : SPFeatureReceiver
        {
            public override void FeatureActivated(SPFeatureReceiverProperties properties)
            {
                SPSite siteCollection = properties.Feature.Parent as SPSite;
                if (siteCollection != null)
                {
                    SPWeb topLevelSite = siteCollection.RootWeb;
    
                    // Calculate relative path to site from Web Application root.
                    string WebAppRelativePath = topLevelSite.ServerRelativeUrl;
                    if (!WebAppRelativePath.EndsWith("/"))
                    {
                        WebAppRelativePath += "/";
                    }
    
                    // Enumerate through each site and apply branding.
                    foreach (SPWeb site in siteCollection.AllWebs)
                    {
                        site.MasterUrl = WebAppRelativePath + "_catalogs/masterpage/MyMasterPage.master";
                        site.CustomMasterUrl = WebAppRelativePath + "_catalogs/masterpage/MyMasterPage.master";
                        site.AlternateCssUrl = WebAppRelativePath + "Style%20Library/MyCustomBranding/MyCustomStyle.css";
                        site.SiteLogoUrl = WebAppRelativePath + "Style%20Library/MyCustomBranding/Images/Logo.jpg";
                        site.UIVersion = 4;
                        site.Update();
                    }
                }
            }
    
            public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
            {
                SPSite siteCollection = properties.Feature.Parent as SPSite;
                if (siteCollection != null)
                {
                    SPWeb topLevelSite = siteCollection.RootWeb;
    
                    // Calculate relative path of site from Web Application root.
                    string WebAppRelativePath = topLevelSite.ServerRelativeUrl;
                    if (!WebAppRelativePath.EndsWith("/"))
                    {
                        WebAppRelativePath += "/";
                    }
    
                    // Enumerate through each site and remove custom branding.
                    foreach (SPWeb site in siteCollection.AllWebs)
                    {
                        site.MasterUrl = WebAppRelativePath + "_catalogs/masterpage/v4.master";
                        site.CustomMasterUrl = WebAppRelativePath + "_catalogs/masterpage/v4.master";
                        site.AlternateCssUrl = "";
                        site.SiteLogoUrl = "";
                        site.Update();
                    }
                }
            }
        }
    }
    
    
  9. We have to apply branding when user create a sub site, so we need to create event receiver when web provisioned. Right click on the project in Solution Explorer, then select Add > New Item > Event Receiver. Then enter the Event Receiver Name is ChildSiteInit.
    branding6
  10. In SharePoint Customization Wizard, Select Web Events for event receiver type and A site was provisioned for the event source.
    branding8
  11. Override WebProvisioned method in ChildSiteInit.cs.
    using System;
    using System.Security.Permissions;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Security;
    using Microsoft.SharePoint.Utilities;
    using Microsoft.SharePoint.Workflow;
    namespace MyCustomBranding.ChildSiteInit
    {
        ///
    /// Web Events
        ///
        public class ChildSiteInit : SPWebEventReceiver
        {
           ///
    /// A site was provisioned.
           ///
           public override void WebProvisioned(SPWebEventProperties properties)
           {
               SPWeb childSite = properties.Web;
               SPWeb topSite = childSite.Site.RootWeb;
               childSite.MasterUrl = topSite.MasterUrl;
               childSite.CustomMasterUrl = topSite.CustomMasterUrl;
               childSite.AlternateCssUrl = topSite.AlternateCssUrl;
               childSite.SiteLogoUrl = topSite.SiteLogoUrl;
               childSite.Update();
           }
        }
    }
    
  12. Set Feature Scope to Site and move all modules to be included in the Feature.
    branding4
  13. Build and Deploy the solution.

Results

branding7

References

Fix: No available sandboxed code execution server could be found.

Cause

I realize this error is quite common especially when SharePoint 2010 installed fresh and we have sandbox solution to deploy. The error “No available sandbox code execution server could be found” will occurred when sandbox solution needs to be deployed and sandbox code service is not running.

Resolution

  1. Go to SharePoint Central Administration site > System Settings > Manage services on server.
  2. Look for Microsoft SharePoint Sandboxed Code Service and click Start to start the service.
  3. If you found the service started already, it doesn’t hurt to Restart the service again.

 

 

Create Custom SharePoint Timer Job

In this article, I would like to show you on steps to create Custom SharePoint Timer Job in SharePoint 2010.

Below is step by step guide to implement Custom SharePoint Timer Job:

  1. Start your Visual Studio 2010 > File > Project > Empty SharePoint Project, Enter project name and  location. Click OK.
    timer1
  2. In SharePoint Customization Wizard, Select Deploy as farm solution. Click Finish.
    timer2
  3. Right click on the project and select Add New Item and Enter Class Name to MyTimerJob.
  4. Inherits MyTimerJob class from SPJobDefinition class and override Execute method.
    using System;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    
    namespace TimerJobProject
    {
        class MyTimerJob : SPJobDefinition
        {
            public MyTimerJob() : base()
            {
            }
    
            public MyTimerJob(string sJobName, SPService service, SPServer server, SPJobLockType targetType) : base(sJobName, service, server, targetType)
            {
            }
    
            public MyTimerJob(string sJobName, SPWebApplication webApplication) : base(sJobName, webApplication, null, SPJobLockType.ContentDatabase)
            {
                this.Title = "My Custom Timer Job";
            }
    
            public override void Execute(Guid contentDbId)
            {
                // Get the current site collection's content database
                SPWebApplication webApplication = this.Parent as SPWebApplication;
                SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
    
                // Get a reference to the "ListTimerJob" list in the RootWeb of the first site collection in the content database
                SPList Listjob = contentDb.Sites[0].RootWeb.Lists["ListTimerJob"];
    
                // Add a new list Item
                SPListItem newList = Listjob.Items.Add();
                newList["Title"] = DateTime.Now.ToString();
                newList.Update();
            }
        }
    }
    
  5. Add Feature to install and delete MyTimerJob. Set Feature Scope to Site scope.timer3
  6. Add Event Receiver to Override Feature Activated and Feature Deactivating methods.
    timer4

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    
    namespace TimerJobProject.Features.MyTimerJobFeature
    {
        /// <summary>
        /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
        /// </summary>
        /// <remarks>
        /// The GUID attached to this class may be used during packaging and should not be modified.
        /// </remarks>
    
        [Guid("a35939eb-23a2-4d0e-8437-19526c9c04c6")]
        public class MyTimerJobFeatureEventReceiver : SPFeatureReceiver
        {
            const string List_JOB_NAME = "ListLogger";
    
            // Uncomment the method below to handle the event raised after a feature has been activated.
            public override void FeatureActivated(SPFeatureReceiverProperties properties)
            {
                SPSite site = properties.Feature.Parent as SPSite;
    
                // Delete the job if already registered
                foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
                {
                    if (job.Name == List_JOB_NAME)
                        job.Delete();
                }
    
                // Install the timer job
                MyTimerJob listLoggerJob = new MyTimerJob(List_JOB_NAME, site.WebApplication);
                SPMinuteSchedule schedule = new SPMinuteSchedule();
                schedule.BeginSecond = 0;
                schedule.EndSecond = 59;
                schedule.Interval = 5;
                listLoggerJob.Schedule = schedule;
                listLoggerJob.Update();
            }
    
            // Uncomment the method below to handle the event raised before a feature is deactivated.
            public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
            {
                SPSite site = properties.Feature.Parent as SPSite;
    
                // Delete the timer job
                foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
                {
                    if (job.Name == List_JOB_NAME)
                        job.Delete();
                }
            }
    
            // Uncomment the method below to handle the event raised after a feature has been installed.
            //public override void FeatureInstalled(SPFeatureReceiverProperties properties)
            //{
            //}
    
            // Uncomment the method below to handle the event raised before a feature is uninstalled.
            //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
            //{
            //}
    
            // Uncomment the method below to handle the event raised when a feature is upgrading.
            //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
            //{
            //}
        }
    }
    
  7. Build and Deploy Solution.
  8. Go to SharePoint Central Administration site > Monitoring > Review job definitions, you could see your Custom Timer Job there.timer5
    timer6

Now its time to Test it.

  1. Go and grab cup of coffee before you check your work.
  2. Go to SharePoint site > Site Actions > View All Site Content > Look for ListTimerJob list.
  3. Few items should be populated after more than 5 minutes and new item will be added every 5 minutes.timer7

Debug your solution.

  1. Attach your solution to process OWSTIMER.
    timer8
  2. Put a break point inside your Execute method in the MyTimerJob class.
    timer9
  3. Wait until it hits the break point.
%d bloggers like this: