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”

Advertisements

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