SharePoint 2013 – A quick guide to use Search

When you think in SharePoint Search are coming many Search concepts then is important to understand the structure and components to use the Search feature in SharePoint 2013.

Normally you need to organize the site information into categories or groups, then you think in Taxonomies… next you need to show these information enabling the users to query, filter and sort the information according to their needs.

Below you will find the most important Search concepts:

  • Service Applications: Group of services can be shared by the farm through Web Application
    • Search:  Provide the search services as: Result sources, content sources, search timer jobs, mapped properties, query rules etc.
    • Managed Metadata: Publish the term store to be share for site collections.
  • Taxonomy:  Formal classification system to organize some information.
  • Content Type: Reusable collection of fields.
  • Result Source: Search provider to get search results.
  • Content Source: Collection of URLs of the content that you configure to crawl.
  • Result Search Web Part: Web part of Search to show the search results using a specific Result Source.
  • Refiner Search Web Part: Web Part to configure the results filter.
  • Result Display Template:  
    • Display Control:  Template to show the structure the overall layout for how present the search results.
    • Display Item: Template to show the search results of a query, the way  of how each item in the result set is displayed.
  • Refinement Search Web Part:  Web Part to configure the results refinements.
  • Refinement Display Template: Template to show the design of the refinement.

Continue reading “SharePoint 2013 – A quick guide to use Search”

Activating Publishing Features by PowerShell script

In a SharePoint 2010 Site, I had some problems activating the Publishing features on Site and Web levels, because for some reason some lists doesn´t exist. I tried by UI in ManageFeatures page, but I could not. Then I tried by PowerShell script and I could, but is important that you include all 6 Publishing features, please check the scripts to activate and deactivate Publishing features in a SharePoint 2010 Site:

To activate

stsadm -o activatefeature -filename publishing\feature.xml -url http://nana-pc:90 -force
stsadm -o activatefeature -filename publishingresources\feature.xml -url http://nana-pc:90 -force
stsadm -o activatefeature -filename publishingSite\feature.xml -url http://nana-pc:90 -force
stsadm -o activatefeature -filename publishingweb\feature.xml -url http://nana-pc:90 -force
stsadm -o activatefeature -filename publishinglayouts\feature.xml -url http://nana-pc:90 -force
stsadm -o activatefeature -filename navigation\feature.xml -url http://nana-pc:90 -force

To deactivate:

stsadm -o deactivatefeature -filename publishing\feature.xml -url http://nana-pc:90 -force
stsadm -o deactivatefeature -filename publishingresources\feature.xml -url http://nana-pc:90 -force
stsadm -o deactivatefeature -filename publishingSite\feature.xml -url http://nana-pc:90 -force
stsadm -o deactivatefeature -filename publishingweb\feature.xml -url http://nana-pc:90 -force
stsadm -o deactivatefeature -filename publishinglayouts\feature.xml -url http://nana-pc:90 -force
stsadm -o deactivatefeature -filename navigation\feature.xml -url http://nana-pc:90 -force

Performance practices to use the Items from large SPList

A large list is a list that has many items and/or many columns, in this case you need take care using this object, because you can cause performance issues, for example querying the fields or the items.

Here are some best practices that can help to use better the SPList object:

Never use SPList.Items, because select all items from all subfolders, and all fields in the list. Instead, you can select only that you need from de SPList, fields and items that you need.

Here some recommendations for each task over list:

Get items from List:


Use SPList.GetItems(SPQuery query). SPQuery allow apply filters, define only the fields you need to make more efficient the select. If the list contains more than 2000 items, you need to paginate the list. Before to use SPQuery object, please check the properties and members that you can use (SPQuery). Check the example:

SPQuery query = new SPQuery();
SPListItemCollection spListItems;

    // Include only the fields you need
    query.ViewFields = "<FieldRef Name=\"ID\"/><FieldRef Name=\"Title\"/>";   
        
    // Only select the top 20
    query.RowLimit = 20; 
      
    // If need, include items in subfolder
    query.ViewAttributes = "Scope=\"Recursive\"";
      
    // Use StringBuilder to create the filter and order clause 
    StringBuilder sb = new StringBuilder();
    sb.Append("<Where><Eq>");
    sb.Append("<FieldRef Name=’Status’/>");
    sb.Append("<Value Type=’CHOICE’>Not Started</Value>");
    sb.Append("</Eq></Where>");
    sb.Append("<OrderBy>");
    sb.Append("<FieldRef Name=’DueDate’ Ascending=’TRUE’ />");
    sb.Append("<FieldRef Name=’Priority’ Ascending=’TRUE’ />");
    sb.Append("</OrderBy>");                   

    query.ViewFields = string.Concat(
                    "<FieldRef Name=’AssignedTo’ />",
                    "<FieldRef Name=’LinkTitle’ />",
                    "<FieldRef Name=’DueDate’ />",
                    "<FieldRef Name=’Priority’ />");

query.Query = sb.ToString();
    
// Here you can find only the fields and items that need 
spListItems = spList.GetItems(query);

Check the options to use SPList.GetItems:

    Sometimes, SPQuery is not the best way to query a SharePoint List, please check the other options in order to identify your scenario:

GetItems(String[]):

Returns a collection of items from the list but includes only the specified field (columns), for example:
SPListItemCollection items = list.GetItems("LinkTitle", "Created", "Status");

GetItems(SPQuery):

Gets a collection of items from the list based on the specified query, for example:
SPListItemCollection items = list.GetItems(query);

GetItems(SPQuery, String):

Gets a collection of items from the list based on the specified query and view name, for example:
SPListItemCollection items = list.GetItems(query, "My Tasks");

GetItems(SPView):

Returns a collection of items from the list based on the defined view, for example:
SPView view = list.Views["My Tasks"];
SPListItemCollection items = list.GetItems(view);

Enjoy!

Using parameters in Event Receivers instead to instance objects

When you use Event Receivers, normally you need some SharePoint objects inside the event, in order to update or implement something, then you need take care when you instance the objects. Never instantiate an SPWeb, SPSite, SPList, or SPListItem objects within an event receiver, because it cause several issues, instead always you can use the instances passed via event properties, for example:

  • Good practice: Retrieve SPWeb and SPListItem from SPItemEventProperties
  •           Example:

             SPWeb web = properties.OpenWeb();
             SPListItem item = properties.ListItem;

  • Bad practice: SPWeb and SPListItem from a new instance of SPSite
  •           Example:

             using (SPSite site = new SPSite(properties.WebUrl))
             {
                    using (SPWeb web = site.OpenWeb())
                    {
                           SPList list = web.Lists[properties.ListId];
                           SPListItem item = list.GetItemByUniqueId(properties.ListItemId);

 

Always try to use the SPItemEventProperties properties listed here:

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spitemeventproperties_properties(v=office.14).aspx

Farm Permissions to configurations by code

Sometimes when you need to do some farm configurations programmatically, for example configuring Send To Connections, rules for Records Management or other Farm Configurations, you are not enable to do these configurations by code (Access Denied message is generated, even though you’re Farm Administrator!). But there is a solution: before that you run your code (maybe a Feature), you can execute this Power Shell script, in order to allow to Administrator, to execute these changes, this is the script:

$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService

$contentService.RemoteAdministratorAccessDenied = $false

$contentService.Update()


Now, you can execute your code, in order to implement the farm configurations programmatically !!!

Generating a PDF File in a SharePoint WebPart using iTextSharp library

This WebPart creates a PDF file in memory (appear Open or Save option in button click event), please review the code and change the parts for include your customization, for example to query some information of your site (example: list or library data):

1. First, you need download the iTextSharp library:
itextsharp.dll

2. Second, you must create a SharePoint project in VS 2010, and add this reference to the project.

3. Third, you must create a class for example FileInfo.cs (this class manage the PDF file object) with the code:

using System;
using System.Text;
using System.Collections.Generic;

namespace Nana.PDF.Samples
{
    public class FileInfo
    {
        public FileType Type { get; set; }
        public string Name { get; set; }
        public byte[] Bytes { get; set; }

        public bool FileNameContainsExt
        {
          get
          {
          return !String.IsNullOrEmpty(Name) && Name.EndsWith("." + Type.ToString());
          }
        }

        public string FileNameWithoutExt
        {
            get
            {
                if (String.IsNullOrEmpty(Name))
                    return "no_name";
                int indexOfDot = Name.LastIndexOf('.');

                return (indexOfDot != -1) ? Name.Remove(indexOfDot) : Name;
            }
        }
    }
}

4. Now, you can create your WebPart for example GeneratePDF a WebPart with the below code:

using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;

namespace Nana.PDF.Samples
{
    public partial class GeneratePDFUserControl : UserControl
    {
        public FileInfo SamplePDFFile { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (SamplePDFFile != null)
            {
                RenderFile(SamplePDFFile.Bytes, SamplePDFFile.Type.ToString(), 
                           SamplePDFFile.FileNameWithoutExt);
                return;
            }            
        }

        protected void btnGenerate_Click(object sender, EventArgs e)
        {
            SamplePDFFile = GeneratePDFFile("This is a test of PDF File!");
        }

        public void RenderFile(byte[] fileBytes,string fileType,string fileName)
        {
            string contentType = null;
            switch (fileType.ToLower())
            {
                case "pdf":
                    contentType = "application/x-pdf";
                    break;
            }

            Response.Clear();
            Response.ContentType = contentType;
            Response.AddHeader("content-disposition", 
                               string.Format("attachment; filename={0}.{1}", 
                               fileName, fileType));
            Response.BinaryWrite(fileBytes);
            Response.End();
        }

        public FileInfo GeneratePDFFile(string sampleText)
        {
            try
            {
                Document doc = new Document();
                MemoryStream ms = new MemoryStream();

                PdfWriter writer = PdfWriter.GetInstance(doc, ms);

                doc.SetPageSize(PageSize.A4);
                doc.SetMargins(72, 72, 110, 72);
                doc.AddAuthor("Nana");

                TableHeader th = new TableHeader();
                writer.PageEvent = th;
                doc.Open();

                iTextSharp.text.Font myfont = new iTextSharp.text.Font(
                               FontFactory.GetFont(FontFactory.COURIER, 10, 
                               iTextSharp.text.Font.ITALIC));

                Paragraph myParagraph = new Paragraph(sampletext, myfont);
                doc.Add(myParagraph);

                //Add here your customizations about the PDF Content
                //for example using html template for fill some values

                doc.Close();

                return new FileInfo()
                {
                    Bytes = ms.ToArray(),
                    Type = FileType.pdf,
                };
            return null;
        }

    }
}

5. Deploy your SPSolution and test the WebPart and enjoy it!

Creating and developing custom lists of easy maintenance in SP2010

There are several ways to create lists in SharePoint, but you must keep in mind that the lists must be maintainable, so I recommend the following steps to make your lists and columns are maintainable


a.       Create a file of fields so that they can reuse:


   <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

             <Field ID="{07E875FB-FE9D-49DE-B073-91DD124DFBB4}"

                    Name="CarColor"

                    DisplayName="Car Color"

                    Type="Text"

                    Required="TRUE"

                    TextOnly="TRUE"

                    Group="Nana Test Columns"/>

 

             <Field ID="{931B40A4-4F95-495A-9F47-CF884198F6E9}"

                    Name="CarModel"

                    DisplayName="Car Model"

                    Type="Text"

                    Required="TRUE"

                    TextOnly="TRUE"

                    Group="Nana Test Columns"/>

 

             <Field  ID="{4C1FC9B5-2A97-402A-BA8B-E4657BA8EB69}"

                     Name="CarDescription"

                     DisplayName="Car Description"

                     Type="Note"

                     Mult="FALSE"

                     Required="TRUE"

                     RichText="TRUE"

                     NumLines="10"

                     RichTextMode="FullHtml"

                     Group="Nana Test Columns" />

       </Elements>

 

 

b.      Create a content type

       <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

        <!– Parent ContentType: Item (0x01) –>

        <ContentType ID="0x01002a07ee8c4fe042dca6a4fc9677803cb4"

               Name="CarData"

               Group="Nana Test Content Types"

               Description="Configuration Content Type"

               Inherits="TRUE"

               Version="0">

         <FieldRefs>

            <FieldRef ID="{07E875FB-FE9D-49DE-B073-91DD124DFBB4}" Name="CarColor"
                      DisplayName
="CarColor" Required="TRUE"
/>  

            <FieldRef ID="{931B40A4-4F95-495A-9F47-CF884198F6E9}" Name="CarModel" 
                      DisplayName
="CarModel" Required="TRUE"
/> 
            <FieldRef ID="{4C1FC9B5-2A97-402A-BA8B-E4657BA8EB69}"
                      Name
="CarDescription" DisplayName="CarDescription"
                      Required
="TRUE"
/>

         </FieldRefs>

        </ContentType>

      </Elements>

 

c.      Create a custom list definition

Elements

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

    <!– Do not change the value of the Name attribute below. If it does not match
         the folder name of the List Definition project item, an error will occur 
         when the project is run.
–>

    <ListTemplate

        Name="ListDefCarData"

        Type="10003"

        BaseType="0"

        OnQuickLaunch="FALSE"

        SecurityBits="11"

        Sequence="410"

        DisplayName="Car data List Definition"

        Description="Car data List Definition"

        Image="/_layouts/images/car.png"/>

</Elements>

 

Schema

<List xmlns:ows="Microsoft SharePoint" Title="Car data List Definition" EnableContentTypes="TRUE" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/CarDataListDefinition" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">

  <MetaData>

    <ContentTypes>

      <ContentTypeRef ID="0x01002a07ee8c4fe042dca6a4fc9677803cb4" />

    </ContentTypes>

    <Fields />

    <Views>

      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">

        <Toolbar Type="Standard" />

        <XslLink Default="TRUE">main.xsl</XslLink>

        <RowLimit Paged="TRUE">30</RowLimit>

        <ViewFields>

          <FieldRef Name="LinkTitleNoMenu">

          </FieldRef>

        </ViewFields>

        <Query>

          <OrderBy>

            <FieldRef Name="Modified" Ascending="FALSE">

            </FieldRef>

          </OrderBy>

        </Query>

        <ParameterBindings>

          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />

          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />

          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />

        </ParameterBindings>

      </View>

      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">

        <Toolbar Type="Standard" />

        <XslLink Default="TRUE">main.xsl</XslLink>

        <RowLimit Paged="TRUE">30</RowLimit>

        <ViewFields>

          <FieldRef Name="Attachments">

          </FieldRef>

          <FieldRef Name="LinkTitle">

          </FieldRef>

          <FieldRef ID="{07E875FB-FE9D-49DE-B073-91DD124DFBB4}" Name="CarColor"
                    DisplayName
="CarColor"
/>

          <FieldRef ID="{931B40A4-4F95-495A-9F47-CF884198F6E9}" Name="CarModel" 
                    DisplayName
="CarModel"
/> 
          <FieldRef ID="{4C1FC9B5-2A97-402A-BA8B-E4657BA8EB69}"
                    Name
="CarDescription" DisplayName="CarDescription"
/>

        </ViewFields>

        <Query>

          <OrderBy>

            <FieldRef Name="ID">

            </FieldRef>

          </OrderBy>

        </Query>

        <ParameterBindings>

          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />

          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />

        </ParameterBindings>

      </View>

    </Views>

    <Forms>

      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />

      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />

      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />

    </Forms>

  </MetaData>

</List>

 

d.      Create a list instance

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <ListInstance Title="Car Data List"

                OnQuickLaunch="FALSE"

                TemplateType="10003"

                Url="Lists/CarDataList"

                Description="Car data List">

  </ListInstance>

</Elements>

 


With this procedure, you can update easy any field in your list  Smile

Using Media WebPart without activate Publishing Feature


I have found many post to use the Media WebPart in SharePoint 2010 is not possible without activating the Publishing Features, but this is possible🙂
I describe below the steps you take to deploy this WebPart:


1.       Go to the SharePoint 2010 Server

2.       Open the file C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\FEATURES\PublishingResources\ProvisionedFiles2.xml

Copy this Module:

    <Module Name="WCMWebParts14" List="113" Url="_catalogs/wp" Path="dwp" RootWebOnly="TRUE">

        <File Url="Media.webpart" Type="GhostableInLibrary">

            <Property Name="Group" Value="$Resources:core,AuthoringWebPartGroup;"></Property>

            <Property Name="QuickAddGroups" Value=";#Default;#" />

        </File>       

    </Module>

3.    Open the file C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14
        \TEMPLATE\FEATURES\PublishingResources\ProvisionedFiles3.xml

Copy this Module:

    <Module Name="MediaPlayerStyles" Url="Style Library" Path="" RootWebOnly="TRUE">

        <File Url="AlternateMediaPlayer.xaml" Name="Media Player/AlternateMediaPlayer.xaml" Type="GhostableInLibrary" />

        <File Url="AudioPreview.png" Name="Media Player/AudioPreview.png" Type="GhostableInLibrary" />

        <File Url="VideoPreview.png" Name="Media Player/VideoPreview.png" Type="GhostableInLibrary" />

        <File Url="MediaWebPartPreview.png" Name="Media Player/MediaWebPartPreview.png" Type="GhostableInLibrary" />

    </Module> 

 

4.    Open the file C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14
        \TEMPLATE\FEATURES\PublishingLayouts\ProvisionedUI.xml

Line 329 Copy the CustomActions tags with IDs:

Ribbon.Media
Ribbon.Media.InsertMediaWP
Ribbon.Media.InsertMediaRTE
InsertMediaRTE.Blogs
Hide.Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromSharePoint.Blogs

Control Tag: AdditionalPageHead.

Add the custom actions need for ribbon tab Media Option works fine:

  <CustomAction

    Id="Ribbon.Media" …

<CustomAction

    Id="Ribbon.Media.InsertMediaWP" …

<CustomAction

    Id="Ribbon.Media.InsertMediaRTE" …

<CustomAction

    Id="Hide.InsertMediaRTE.Blogs" …

<CustomAction

        Id="Hide.Ribbon.EditingTools.CPInsert.Media.Image.Menu.Image.FromSharePoint.Blogs" …

  <Control

                Id="AdditionalPageHead" …

 

5.   Create a Module in Visual Studio in your SharePoint project and include these tags at the end as shown below:

  <Module Name="WCMWebParts14" List="113" Url="_catalogs/wp" Path="SitePages\dwp" RootWebOnly="TRUE">

    <File Url="Media.webpart" Type="GhostableInLibrary">

      <Property Name="Group" Value="$Resources:core,AuthoringWebPartGroup;"></Property>

      <Property Name="QuickAddGroups" Value=";#Default;#" />

    </File>

  </Module>

  <Module Name="MediaPlayerStyles" Url="Style Library/Media Player" Path="SitePages\dwp" RootWebOnly="TRUE">

    <File Url="AudioPreview.png" Type="GhostableInLibrary" />

    <File Url="VideoPreview.png" Type="GhostableInLibrary" />

    <File Url="MediaWebPartPreview.png" Type="GhostableInLibrary" />

  </Module>

 

clip_image002[4]

6.   Deploy WebPart in the _catalogs\wp

7.   Insert the WebPart resources at the your site Style Library.

8.   This picture shows the Ribbon Media Option working fine on a Site without Publishing
       Features Activated, for example a Team Site:

clip_image004[4]

clip_image006[4]


9.    Note that the Site Collection feature: “SharePoint Server Publishing Infraestructure” is not
       activated:

      SITE COLLECTION FEATURES

clip_image008[4]

10.   Note that the Site feature: “SharePoint Server Publishing” is not activated:

    SITE FEATURES

clip_image010[4]


Now, you can use the Media WebPart in your site. We only had to configure the WebPart to deploy it and to be able to use =)

Set properties to a WebPart programmatically

For assign some properties of a WebPart programmatically, you can use the follow code for the WebPart, this has two custom properties Code and Owner Name:

[ToolboxItemAttribute(false)]

public class ExampleWebPart : WebPart

{

    // Visual Studio might automatically update this path when you change

       the Visual Web Part project item.

    private const string _ascxPath =

                          "~/_CONTROLTEMPLATES/ExampleWebPartUserCtr.ascx";

       

    [WebBrowsable(true),

    Category("Custom Properties"),

    Personalizable(PersonalizationScope.Shared),

    WebDisplayName("Code"),

    DefaultValue("100"),

    WebDescription("Set the code value.")]

    public string Code { get; set; }

 

    [WebBrowsable(true),

    Category("Custom Properties"),

    Personalizable(PersonalizationScope.Shared),

    WebDisplayName("Owner Name"),

    DefaultValue("nana"),

    WebDescription("Set the owner name.")]

    public string OwnerName { get; set; }

 

    protected override void CreateChildControls()

    {

        ExampleWebPartUserCtr control = (ExampleWebPartUserCtr)

                                        Page.LoadControl(_ascxPath);

        if (control != null)

            control.WebPart = this;

        Controls.Add(control);

    }

}

Include html code in ErrorMessage attribute of an asp:Validator

You can include html code for formatting your message in a Validator. First you create the html message with the format that you want, next you can assign this to the ErrorMessage attribute, let me show an example:


<asp:RegularExpressionValidator ID="txtCodeVal" runat="server"

Display="Static" ControlToValidate="txtCode"

ErrorMessage="<div class=’divFormatError’><div style=’float: left; vertical-align: middle; margin: 5px;’><img alt=” src=’..\Images\error.jpg’ style=’vertical-align: middle;’ /></div><div class=’blackErrorMessage’> Please enter a valid code in the format: XXX01234-00 </div></div>"

ValidationExpression="[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]-[a-zA-Z0-9][a-zA-Z0-9]" ForeColor="Black" /> 


Note that the characters “”(double) were changed by ‘’ (simple). The validator will show this message only if the attribute ErrorMessage has a valid html code. You can use classes css too.

Have a happy new year Smile