SharePoint In Action

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

Archive for the category “SharePoint 2010 Development”

Error: The Method “GetItems” of the type “List” with id “{Lists’s Guid}” is blocked by the administrator on the server

Hi all,

I was using SharePoint Client Object Model when I got the error above. Basically I was trying to get all items from a list using JavaScript’s get_lists function. It seems the function is inaccessible in anonymous mode. The solution is removing the function GetItems from AnonymousRestrictedTypes using PowerShell:

$web = Get-SPWebApplication -Identity http://your web address
$web.ClientCallableSettings.AnonymousRestrictedTypes.Remove( [Microsoft.SharePoint.SPList],"GetItems")
$web.Update()

and in case you change your mind later, you can addf GetItems to AnonymousRestrictedTypes using commands below:

$web = Get-SPWebApplication -Identity http://your web address
$web.ClientCallableSettings.AnonymousRestrictedTypes.Add( [Microsoft.SharePoint.SPList],"GetItems")
$web.Update()

Hope that was useful!

Cheers,
Nader Heshmat

Batch Updating The Items Of A SharePoint 2010 List

Hi all,

I created a web part for work last week to batch-update the items of a SharePoint 2010 list.
To make it simple I will show how to modify only one column in the whole list using CAML and you can simply expand the idea. My site is called “SampleSite” and the list is “SampleList”. We are modifying the column “SampleColumn”. Here is how the code looks like:

void UpdateList()
        {
            StringBuilder methodBuilder = new StringBuilder();
            string batch = string.Empty;
            string newValue="mmmm";
            string updateColumn = "SampleColumn";


            try
            {
                string batchFormat =    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                                        "<ows:Batch OnError=\"Continue\">{0}</ows:Batch>";
                string methodFormat = "<Method ID='{0}' >" +
                                        "<SetList>{1}</SetList>" +
                                        "<SetVar Name='Cmd'>Save</SetVar>" +
                                        "<SetVar Name='ID'>{2}</SetVar>" +
                                        "<SetVar Name='urn:schemas-microsoft-com:office:office#{3}'>{4}</SetVar>" +
                                        "</Method>";
                
                using (SPSite siteCol = new SPSite("SampleSite"))
                {
                    using (SPWeb web = siteCol.OpenWeb())
                    {

                        // Get the list containing the items to update
                        SPList list = web.Lists["SampleList"];
                        string listGuid = list.ID.ToString();
                        SPListItemCollection allItems = list.GetItems();

                        // Build the CAML update commands.
                        for (int i = 0; i < allItems.Count; i++)
                        {
                            int itemID = allItems[i].ID;
                            methodBuilder.AppendFormat(methodFormat, itemID, listGuid, itemID, updatedColumn, newValue);
                        }
                        web.AllowUnsafeUpdates = true;

                        // Generate the CAML
                        batch = string.Format(batchFormat, methodBuilder.ToString());

                        // Process the batch 
                        string batchReturn = web.ProcessBatchData(batch);
                       
                    }
                    //done
                }
 
            }
            catch (Exception ex)
            {
		//show the error
            }

        }
}

Note how the reference to the field has been made in the CAML command:

<SetVar Name='urn:schemas-microsoft-com:office:office#{3}'>{4}</SetVar>

Also note that you would need to set the web.AllowUnsafeUpdates to true.

Assuming SampleList has 4 items, your generated CAML should look like this:

<?xml version=\"1.0\" encoding=\"UTF-8\"?><ows:Batch OnError=\"Continue\">
	<Method ID='1' ><SetList>6deeec64-95f8-4e26-b5ad-e8770deaae5c</SetList><SetVar Name='Cmd'>Save</SetVar> <SetVar Name='ID'>1</SetVar><SetVar Name='urn:schemas-microsoft-com:office:office#SampleColumn'>mmmm</SetVar></Method>

<Method ID='2' ><SetList>6deeec64-95f8-4e26-b5ad-e8770deaae5c</SetList><SetVar Name='Cmd'>Save</SetVar> <SetVar Name='ID'>2</SetVar><SetVar Name='urn:schemas-microsoft-com:office:office#SampleColumn'>mmmm</SetVar></Method>

<Method ID='3' ><SetList>6deeec64-95f8-4e26-b5ad-e8770deaae5c</SetList><SetVar Name='Cmd'>Save</SetVar> <SetVar Name='ID'>3</SetVar><SetVar Name='urn:schemas-microsoft-com:office:office#SampleColumn'>mmmm</SetVar></Method>

<Method ID='4' ><SetList>6deeec64-95f8-4e26-b5ad-e8770deaae5c</SetList><SetVar Name='Cmd'>Save</SetVar> <SetVar Name='ID'>4</SetVar><SetVar Name='urn:schemas-microsoft-com:office:office#SampleColumn'>mmmm</SetVar></Method>
</ows:Batch>

Cheers,
Nader Heshmat

Error: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.

Hi all,

I just got this error while developing a web part to batch update a SharePoint list. The solution was adding one line of code that allows running the update command on a list without requiring a security validation. This should be place right before your update command.

Consider the code snippet below:

SPSite siteCol = new SPSite(YourSiteURL);
SPWeb web = siteCol.OpenWeb();
SPList list = web.Lists[YourListName];
web.AllowUnsafeUpdates = true;

{your list update code goes here}

Warning:
Setting this property to true opens security risks, potentially introducing cross-site scripting vulnerabilities.

p.s. You can also use web.Site.WebApplication.FormDigestSettings.Enabled = false before your update and set it to true after

Cheers,
Nader Heshmat

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

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

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

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

Post Navigation