Wednesday, April 17, 2013

Get count of sites under a site collection uisng SharePoint Object Model

This article will describe a very simple way to calculate total no. of Sites inside a Site Collection. Below are the steps:

1. We first have to create a Uri object, which will capture the webapplication (SPwebApplication) URL. 

2. Then a Site Collection (SPSite) object can be created by selecting the appropriate site collection from the above web app.

3. Count the number of sites (SPWeb) in this site collection.

//Sample Code

Required Namespaces :

System
System.IO
Microsoft.SharePoint
Microsoft.SharePoint.Administration

       Uri u = new Uri("MyWebAppURL");
       
           SPWebApplication myWebApp= SPWebApplication.Lookup(u);
        
           SPSite siteColName;

           siteColName = myWebApp.Sites["sites/MySiteCol"];

          Console.WriteLine("Total number of sites under this site collection : "  +     siteColName.AllWebs.Count);

Multiple User Conflict in SharePoint: User changes after clicking ok in People Picker/Address book

This happened recently while I was trying to add a user on a SharePoint Site. User A was replaced with User B.


Problem

  • While searching for a user in Address book by typing the name, say "User A", it shows the correct user. But once the user is added by clicking OK, it changes to say "User B". 
  • When searching the user by domain\username (for User A), it only shows two occurrences of "User B".
  • There is only a single letter difference between both of their usernames. E.g : For UserA- domain\samename1, For UserB-domain\samename


Solution:

  • Check in   /_catalogs/users/simple.aspx. Delete both the users from it.
  • Run both full and incremental import of user profiles in SSP.
  • After this, try adding the user again.

Root Cause:

  • The problem was in the user details. Old data was conflicting with new one. Once old data was deleted from  /_catalogs/users/simple.aspx , the user was correctly added.

SharePoint error: File is locked for editing by ‘domain\username'

Sometimes, when we try to edit a document uploaded on SharePoint, we get a file locked error: “File is locked for editing by ‘domain\username’ “, even though the file has been checked in and no one else is editing the file.
 

Usually a file is locked by WSS when a particular user has ‘checked out’ the file for editing purposes. A write lock is created so that no other user can edit this file simultaneously (except in case of versioning).

When the user checks in the file, the write lock is removed and the file is now available for editing by others.  But sometimes, even if the file has been checked in, it still gives a file lock error. There can be numerous reasons for this such as:

         1.    System crashes while the file is still open.

         2.    File has been closed unexpectedly.

         3.    Check in was not successful.

         4.    Network connection is lost while file is still open.

In most of the cases, the write lock still exist for the file so its gives an editing error.

Below are the few workarounds to resolve this error:

          1.    Check whether the file has been properly checked in or not. If not, refresh the page and try to check in the file again.

          2.    Delete the local copy of the file present in the cache folder of the concerned user account (access to user’s PC required).

          3.     Close all the instances of file type opened in the system. E.g. if the file type is excel, then close all the excel files currently opened.

          4.    Also kill the file type service (excel in this case) using the task manager.


Wait for 10-15 minutes and then try to edit the file. The write lock times out after 10 minutes. Users cannot modify the document during the time when the document is locked. 

Once the write locked times out, the file will be available for editing. If the concerned user is not available or the PC is not accessible, then please refer to this article.

Connecting two Web Parts in SharePoint : SharePoint Tutorial #2

This tutorial describes the step to access data by connecting two different Web Parts in a SharePoint Site. In order to do so, three things should be kept in mind:
  • Provider Web Part (that provides the data)
  • Connection Interface (that provides the connection between two Web Parts)
  • Consumer Web Part ( that accepts the data)
But before we go further, one should be aware of how to create and deploy a web part.

Following are the steps :

Creating a Connection Interface
In this step, we create an interface say ‘CommunicationInterface’.  
In this interface, we define a property ‘ parameter1’ for  providing data.  The no. of properties depends on the no. of parameter to be passed.



//Code Part

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


namespace CommunicationInterface
{
    public interface ICommunicationInterface
    {
        string parameter1 { get; }

    }
}

Once this interface is created, compile it and add its DLL to the Global Assembly Cache (C:\Windows\Assembly) in your  system.





Creating a Provider Web Part
The second step is to create a Provider Web Part to pass the data to the interface.
Create a web part and name it say ‘WP_Provider’.  Add reference of the earlier created ‘CommunicationInterface’ DLL. 
Once the reference is added,  implement the ‘ICommunicationInterface’ to ‘WP_Provider’ class.
Then the connection provider property is added and the reference to the communication Interface is returned.
Implement the property defined in the interface.

//Code Part
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using CommunicationInterface;

namespace WP_Provider
{
   
   public class 
   WP_Provider: Microsoft.SharePoint.WebPartPages.WebPart,ICommunicationInterface
    
   {
        Label nm;
        TextBox tbname;
        Button btn=new Button();
       
        RadioButtonList rb = new RadioButtonList();

       
      // Provides connection provider property for the parameters
      [ConnectionProvider("Parameter1 Provider",
                    "Parameter1 Provider")]
        public ICommunicationInterface ConnectionInterface()
        {
         // this returns a reference to the communication interface
            return this;
        }

        protected string _parameter1 = "";


        // Property defined in Interface is implemented
        public string parameter1
        {
            get { return _parameter1; }
        }
       
       
        public WP_Provider()
        {
       
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();



            //Accessing a particular list items

            SPSite mysitecol = SPContext.Current.Site;
            SPWeb mysite = SPContext.Current.Web;
            SPList mylist = mysite.Lists["UpdateList"];
            SPListItemCollection itemcol = mylist.Items;
           
            foreach (SPListItem itm in itemcol)
            {
                string nm = itm["Company_Id"].ToString();
                rb.Items.Add(nm);

            }

            btn.Text = "Send";
            this.Controls.Add(rb);
            this.Controls.Add(btn);
            btn.Click += new EventHandler(btn_Click);
        }

   public  void btn_Click(object sender, EventArgs e)
        {
            // set connection provider property with required textbox info.
           // this._parameter1 = tbname.Text;
            this._parameter1 = rb.SelectedItem.Text;
        }

    }
}

After completing the code, compile and add the DLL in the Global Assembly Cache (C:\Windows\Assembly).
Create the corresponding ‘dwp’ file and add the SafeControl in the web.config of SharePoint Site.



Creating a Consumer Web Part
The third step is to create a Consumer  Web Part to pass the data to the interface.
Create a web part and name it say ‘WP_Consumer’.  Add reference of the earlier created ‘CommunicationInterface’ DLL. 
Then the connection Consumer property is added and the reference to the communication Interface is retrieved.
From this reference, the parameter that is passed from Provider Web Part is obtained.

//Code
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using CommunicationInterface;

namespace WP_Consumer
{
   
    public class WP_Consumer : Microsoft.SharePoint.WebPartPages.WebPart
    {
       //Label lblTitle;
       Label lblname=new Label();
      

    ///// the string info consumer from custom reciever   //
    ICommunicationInterface connectionInterface = null;

    // The consumer webpart  must define a method that
    // would accept the interface as an parameter
    // and must be decorated with ConnectionConsumer attribute     
    [ConnectionConsumer("Parameter1 Consumer",
                        "Parameter1 Consumer")]
    public void GetConnectionInterface(ICommunicationInterface
                                       _connectionInterface)
    {
        connectionInterface = _connectionInterface;
    }
    ///////////////////////////////////////////////////////// 

    public WP_Consumer()
    {
       
    }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            
            this.Controls.Add(lblname);
           
        }


        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (connectionInterface != null)
            {
                lblname.Text = connectionInterface.parameter1 +
                " is recieved!";
               

             }
            else
            {
                lblname.Text = "nothing is recieved!";
            }
           
        }

     
          
     }

       

  }
}

After completing the code, compile and add the DLL in the Global Assembly Cache. (C:\Windows\Assembly)
Create the corresponding ‘dwp’ file and add the SafeControl in the web.config of SharePoint Site.


Uploading the web parts, Adding the web parts and Connecting the web parts

Once the above steps are completed, upload the web part.
The last and the final step is to connect two web parts. Click on web part edit arrow, then select the connection part.
 
The web parts are connected. Now send and the receive the required data.

Creating a custom web part in SharePoint : SharePoint Tutorial #1

Web part is a server control that is added in SharePoint site to perform some operations on the run such as displaying a list, displaying a web page, adding content to the site, etc.  A web part is added to a web part zone present on the particular web page. 

While there are a number of predefined web parts in SharePoint that can be used out of box; we can create our own custom web parts to perform operations that are not possible with existing web parts.

  Following are the steps to create a custom web part:

1.    Create a class file to write web part code:


a)    Create a new Visual Studio project say ’MyTestWebpart’ and add a class file say ‘MyTestWebpart’ to it.  After this add ‘Windows SharePoint Service’ reference to this project (Right click on project, select add reference, select the required dll under .NET components).

b)    Inherit the web part class(Mircosoft.SharePoint.WebPartPages.WebPart)  and ‘System.Web’ in ‘MyTestWebpart’

c)    Over ride ‘CreateChildControl ‘ and ‘RenderControl’ method in the above class. ‘System.Web’ class has to be inherited as both these method are in ‘System.Web’ Class.

 ‘CreateChildControl’ method is to create and initialize objects. ‘RenderControl’ method is used to render the controls created in the ‘CreateChildControl’ method.
If you are not creating any control and just have to write something using web part, you can use the ‘Render’ method. In this ‘Writer.write’ can be used to display the required info.

using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Text;

namespace MyTestWebpart
{
    public class MyTestWebpart:Microsoft.SharePoint.WebPartPages.WebPart
    {
       

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            writer.Write("Hello World");

        }

    }
}


2.    Sign the project with strong key:

Sign the project with a strong key name. Right click on the project, Select properties, Go to Signing tab. Under Signing tab-> Choose a strong key file->New key.  Enter the new key name say ‘MyTestWebpart’, uncheck the password option and click ok. Save and close.

3.    Deploying the web part dll:

Open Assembly( Type assembly in run and hit enter) and deploy the project dll (in this case ‘MyTestWebpart.dll ) in the Assembly( drag and drop the dll in assembly).

4.    Create a dwp file:  (DWP is the webpart extension to be uploaded in the webpart gallery)

Add an xml file to the project and rename the extension as dwp. Add the required info to below tags.

<?xml version="1.0" encoding="utf-8" ?>
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
  <Title>MyTestWebpart</Title>
  <Description>This is a Test Webpart</Description>
  <Assembly>MyTestWebpart, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=9f4da00116c38ec5</Assembly>
  <TypeName>MyTestWebpart.MyTestWebpart</TypeName>
  <!-- Specify initial values for any additional base class or custom properties here. -->
</WebPart>

<Assembly >name should be the name of the project dll. Rest of the assembly details such as version , culture and public key token can be obtain from the properties of the particular dll in the assembly.
<Type name > should be in the form of ‘AssemblyName.ClassName’.

5.    Add Safe Control Entry in application web.config file:

Open the web.config of the application(C:\Inetpub\wwwroot\wss\VirtualDirectories\)  and add a safe control entry for this webpart.

    <SafeControl Assembly="MyTestWebpart, Version=1.0.0.0, Culture=neutral,                   PublicKeyToken=9f4da00116c38ec5"Namespace="MyTestWebpart"
    TypeName="MyTestWebpart" Safe="True" />


6.    Upload the dwp file in the web part gallery:

Click on Site Settings, Select web part under ’Gallaries’.  Next, click on upload and upload the dwp file of this webpart.


7.    Reset IIS/ Application pool


8.    Add the custom web part to required web page