SharePoint In Action

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

Archive for the category “C#”

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

Advertisements

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

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

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

Post Navigation