SharePoint In Action

An attempt to share my day-to-day SharePoint experience

Updating a SharePoint ListItem With No Trace In Item Version!

Hi,

Case:
Today I had to write a method to update a SharePoint list every 30 mins but since it had the versioning on, I needed to turn the versioning off when the list was updated programmatically. The versioning needed to be on for manual updates.

Solution:
I had to change the SPListItem.Update() with SPListItem.SystemUpdate()

Details:
Basically SPListItem.Update() updates the database along with “Modified” and “Modified By” fields and the modifications will be added in the Change and Audit logs. It also updates the item version.
In order to leave no trace on those fields and item version you would need to use SPListItem.SystemUpdate() which does all behind the scene works except updating those fields and the item version.

You can also use UpdateOverwriteVersion() to avoid adding a new item version but note that it WILL update the “Modified” and “Modified By” fields.

Cheers,
Nader Heshmat

Advertisements

error: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding

Hi,

I just got an error in my client application that uses a wcf method to extract some data from a SQL Server database. The error was:

“Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding”

Obviously it’s a timeout issue due to complexity of the query. To fix this you would need to take alook at your binding settings in the App.config file. Typically there are a few timeout settings that you can modify there. Look under section and locate and then . You should see the settings for your timeouts like below:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="your service interface name" closeTimeout="00:18:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:18:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    .
                    .
                    .
                    .
                </binding>
             </basicHttpBinding>
         </bindings>
</system.serviceModel>

The sendTimeout shows how long the client will wait till it gets the response from WCF service. The format is hours:minutes:seconds. It shows the total time of sending a message through your service including receiving the reply message in a wcf request-reply case.
The closeTimeout shows how long you will wait before you close the connection before an exception is thrown. Usually this disposes the client WCF proxy.

In my case, I just increased the sendTimeout and closeTimeout and the problem was gone.

Cheers,
Nader Heshmat

Retrieve A Deployed SharePoint 2010 WSP Package

Hi all,
I was just asked to retrieve a few installed WSP packages from our SharePoint 2010 farm. Since this is not available through Central Admin I used this script to retrieve each package using SharePoint PowerShell console:

Step 1- Get a reference to your farm

$myFarm = Get-SPFarm

Step 2- Get the solution file

$solutionFile = $farm.Solutions.Item("mySolution1.wsp").SolutionFile

Step 3- Save the file on your disk

$file.SaveAs("C:\Deployed solutions\mySolution1.28Nov.wsp")

Cheers,
Nader Heshmat

Consolidating SharePoint 2010 Application Pools

Hi All,

SharePoint 2010 recommends maximum of 10 application pools per server. Let’s assume that you place each of your web applications in a different application pool. This will assign one instance of w3wp.exe process per application pool. Considering the fact that each of these processes will use about 100MB of your server’s memory, you might lose some performance on your server due to improper memory management.
One solution is to consolidate the App pools using PowerShell script below using dummy “SharePoint App Pool – 8000” and “http://mywebapp:8000″”http://mywebapp:8000&#8221;

$BucketAppPool = [Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplicationPools | where {$_.Name -eq "SharePoint App Pool - 8000" }
$webapp = get-spwebapplication -Identity "http://mywebapp:8000"
$webapp.Applicationpool = $BucketAppPool
$webApp.Update()
$webApp.ProvisionGlobally()
iisrest

Cheers,
nader Heshmat

SharePoint BCS Error – “There is no Business Connectivity Service associated with the current web context.”

Hi all,

I got this error when I was trying to create a SharePoint 2010 BCS external type:

“There is no Business Connectivity Service associated with the current web context.”

The error:

The Error

The reason was that Iyou need to enable the BCS connectivity service for each Web Application you intend to crerate the BCS for. In order to do that follow the below steps:

Go to Central Admin –> Manage Web Applications –> Select your Web Application –> Click Service Connections in the top Ribbon and check the BDC service

Go to the list of your Web Applications:

SharePoint Web Applications

SharePoint Web Applications

and check the BDC service:

Cheers,
Nader Heshmat

How To Determine If A site Is A SharePoint Publishing Site

Hi all,

Sometimes in order to customize the navigation for your site, you would need to determine if your site is a publishing site or a non-publishing one. The reason is that the navigation customization options for a publishing site are more extensive than those available for a non-publishing site.Here is all you would need to do: 

Go to “Site Actions” menu –> Site Settings –> Look and Feel

  • If you see a link titled Navigation, then you are working with a publishing site and you can customize your site using the Site Navigation Settings page.
  • If you see links titled Top link bar and Quick Launch, then you are working with a non-publishing site and you have a more limited set of navigation configuration options available to you. 

Cheers,

Nader Heshmat

Image

Image

Validating Site Admins Against Active Directory

Hi all,

I was asked to create a SharePoint 2010 web part which would verify all site admins against the company’s Active Directory.

Here is a screen-shot of  the web part I have created:

SharePoint 2010 Web Part To Verify Site Admins Against Active Directory

SharePoint 2010 Web Part To Verify Site Admins Against Active Directory

Here is the method to get and verify the site admins:

void VerifyUser()
        {
            bool distinct = cbDistinct.Checked;
            bool overload;
            SPWebApplication oWebApplication;
            int counterSiteCollectopns=0;
            int counterWebs=0;
            int counterSiteAdmins=0;
            List<SPUser> invalidAdmins;
            oWebApplication = SPWebApplication.Lookup(new Uri(txtSiteUrl.Text));


            try
            {
                foreach (SPSite oSite in oWebApplication.Sites)
                {
                    counterSiteCollectopns++;
                    lblCounterSC.Text = counterSiteCollectopns.ToString();
                    foreach (SPWeb oWeb in oSite.AllWebs)
                    {
                        counterWebs++;
                        lblCounterWeb.Text = counterWebs.ToString();
                        foreach (SPUser user in oWeb.SiteAdministrators)
                        {
                            IList<SPPrincipalInfo> users =
                            SPUtility.SearchWindowsPrincipals(
                                      oWebApplication,
                                      user.LoginName,
                                      SPPrincipalType.User,
                                      3,
                                      out overload);
                             if (users.Count == 0)
                                 invalidAdmins.Add(user);
                             counterSiteAdmins++;
                             lblCounterAdmins.Text = counterSiteAdmins.ToString();
                         }
                       }
                    }
                }
            }
            catch(Exception ex)
            {

            }
        }

        

Cheers,
Nader Heshmat

Implementing the IEquatable Interface for Objects Equality Methods in C#

In C#, unlike value types (int, double, struct, DateTime,..) we cannot use operator “==” for objects to check the equality. In order to check the equality of two reference variables, we need to implement the interface:  IEquatable. This interface can be well used for generic collection objects like Dictionary<TKey, TValue> or List<T>

This interface is used when you want to implement your own “Equals” method for your object. Once you implement it, it will be used when you are checking for equality in methods like Contains, IndexOf, LastIndexOf or Remove.

For more info please go to http://msdn.microsoft.com/en-us/library/ms131187.aspx

An example of this can look like this: (I will use this class in my next post)


using System;
using System.Collections.Generic;

namespace ValidateSiteOwners
{
    class OwnerInfo : IEquatable<OwnerInfo>
    {
        private string _name;
        private string _role;
        private bool _isAdmin;
        string _siteUrl;
        private bool _distinct;
        public string Name
        {
            get { return _name;}
            set { _name = value;}
        }

        public string Role
        {
            get { return _role; }
            set { _role = value; }
        }

        public bool IsAdmin
        {
            get { return _isAdmin; }
            set { _isAdmin = value; }
        }

        public bool Distinct
        {
            get { return _distinct; }
            set { _distinct = value; }
        }

        public string SiteUrl
        {
            get { return _siteUrl; }
            set { _siteUrl = value; }
        }

        public OwnerInfo()
        {
            _name = string.Empty;
            _role = string.Empty;
            _siteUrl = string.Empty;
            _isAdmin = false;
        }

        public OwnerInfo(string name, string role, bool isAdmin, string siteUrl, bool distinct)
        {
            _name = name;
            _role = role;
            _isAdmin = isAdmin;
            _siteUrl = siteUrl;
            _distinct = distinct;
        }

        public bool Equals(OwnerInfo other)
        {
            if (this.Distinct)
                if (this.Name.ToLower() == other.Name.ToLower() && this.Role.ToLower() == other.Role.ToLower() && this.IsAdmin == other.IsAdmin)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            else
                if (this.Name.ToLower() == other.Name.ToLower() && this.Role.ToLower() == other.Role.ToLower() && this.IsAdmin == other.IsAdmin && this.SiteUrl == other.SiteUrl)
                {
                    return true;
                }
                else
                {
                    return false;
                }
        }

        public override bool Equals(Object obj)
        {
            if (obj == null)
                return false;

            OwnerInfo ownerObj = obj as OwnerInfo;
            if (ownerObj == null)
                return false;
            else
                return Equals(ownerObj);
        }

        public static bool operator ==(OwnerInfo owner1, OwnerInfo owner2)
        {
            if ((object)owner1 == null || ((object)owner2) == null)
                return Object.Equals(owner1, owner2);
            return owner1.Equals(owner2);
        }

        public static bool operator !=(OwnerInfo owner1, OwnerInfo owner2)
        {
            if (owner1 == null || owner2 == null)
                return !Object.Equals(owner1, owner2);
            return !(owner1.Equals(owner2));
        }
    }
}

Please note that my class implements IEquatable by overriding the implementation of IEquatable<T>.Equals, Object.Equals

Cheers,

Nader Heshmat

Programmatically Read Versions Of A SharePoint List Item

Here I will show how you can read all versions of a list item programmatically. As you know, in SharePoint you can turn on the versioning for a list so whenever you modify an item in your list, it keeps track of all your changes so you can revert back to a specific version.

Note:
To Enable the Versions for a Sharepoint list, you’d need to go to “List Settings” and go to “Versioning Settings” and then change the value of “Create a version each time you edit an item in this list?” to Yes.

To better demonstrate this, imagine we have a list item as below:

Employee Vacation Days Comment
Person or Group Single Line of Text Single Line of Text

We turn on the versioning for the list and make the comment field mandatory. So whenever someone modifies the list item, they have to leave a comment and versioning will take care of the rest.

Now we want to read all the comments for an item and show the history in a grid let’s say. In my code I have created a simple class called “Comment“:

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;</code>

namespace Test
{ 
    public class Comment
    {
        private string body ;
        private int order;
        private DateTime date;
        private SPUser author;

         #region Properties

        internal SPUser Author
        {
            get { return author; }
            set { author = value; }
        }

        internal DateTime Date
        {
            get { return date; }
            set { date = value; }
        }

        internal string Body
        {
            get { return body; }
            set { body = value; }
        }

        internal int Order
        {
            get { return order; }
            set { order = value; }
        }

        #endregion
         #region Constructors

        internal Comment(): base()
        {
            this.order = 0;
            this.author = SPContext.Current.Web.CurrentUser;
            this.body = string.Empty;
            this.date = DateTime.Now.Date;
        }
      

        #endregion
    }
}

and here is a simple method that loops through the versions of an item. Please note that I am passing the item to my method as well as using “SPListItemVersionCollection”:

private List&lt;Comment&gt; EmployeeTimeOffDays(SPListItem item) 
{
         List&lt;Comment&gt; cmnts = new List&lt;Comment&gt;();
         if ((item.Versions!= null) &amp;&amp; (item.Versions.Count &gt; 0))
        {
                     SPListItemVersionCollection versions = item.Versions;
                     for (int i = 0; i &lt; versions.Count - 1; i++)
                    {                   
                            if (versions[i]["Comment"] != null)
                            {
                                     Comment cmnt = new Comment();
                                     cmnt.Body = versions[i]["Comment"].ToString();
                                     cmnt.Author = (SPUser)(versions[i].ListItem, "Created By");
                                     cmnt.Date = DateTime.Parse(versions[i]["Created"].ToString());
                                     cmnts.Add(cmnt);
                               }
                       }
                   }
      return cmnts;
}

Cheers,
Nader Heshmat

Converting Person/Group Field to SPUser

Hi,

I was trying to work with Person/Group field in SharePoint and I needed to convert it to SPUser in order to work with it in back-end.  I passed the list item and column name to this method:

public SPUser GetSPUserFromItem(SPListItem item, string fieldName)
{
     SPFieldUser spfu = (SPFieldUser)item.Fields[fieldName];
     SPFieldUserValue user = (SPFieldUserValue)spfu.GetFieldValue(item[fieldName].ToString());
     return user.User;
}

Cheers,
Nader Heshmat

Post Navigation