Tuesday, June 14, 2011

Everything about SPQuery Class

Every kind of Application or System no matter whether they are simple or complex, they needs their data to be stored in someplace. It can be either a Database, a XML file or simply a text file. And all those applications uses CRUD (Create,Read,Update,Delete) operations to maintain their data. So in SharePoint, one of the major way of Reading or Selecting data is using SPQuery Class in Microsoft.SharePoint Namespace.

Today I am going write about this SPQuery Class. The SPQuery Class is used to represent a query in the list view. Assuming you all know about SQL Select queries, to give you some basic idea on what SPQuery do is, It does what Select query in SQL does but syntaxes are totally different. Since I am hoping to write some examples using SPQuery, I think as we go along with this post you will definetely be able to identify the differences.

Then let's start. I will be using a custom list called Customer List. It contains following columns.
  1. Title - string
  2. Name - string
  3. Field1 - Number
  4. Field2 - Number
First of all, I will write a full simple example. Follwing code will retrieve all the items in the "Customer List" in which Name field equals to "Jaliya Udagedara".

using (SPSite oSPSite = new SPSite("http://ravanaserver/"))
{
     using (SPWeb oSPWeb = oSPSite.OpenWeb())
     {
           oSPWeb.AllowUnsafeUpdates = true;
           SPList oSPList = oSPWeb.Lists["Customer List"];

           SPQuery oSPQuery = new SPQuery();
           
           // your query writes here
           oSPQuery.Query = "<Where><Eq><FieldRef Name='Name'/><Value Type='Text'>Jaliya Udagedara</Value></Eq></Where>";
           SPListItemCollection oSPListItemCollection = oSPList.GetItems(oSPQuery);
           foreach (SPListItem item in oSPListItemCollection)
           {  
                // your code
           }
     }
}

Now I will write example for common scenarios. When modifying, modify only the part where I have put comment "// your query writes here".

  • Retrieve all Items.
    • For this you don't have to write any query. Just modify the above code as follows. This will return the all Items.
           SPQuery oSPQuery = new SPQuery();
           SPListItemCollection oSPListItemCollection = oSPList.GetItems(oSPQuery);

  • Retrieve items that a field matches a given value.
           oSPQuery.Query = "<Where><Eq><FieldRef Name='Name'/><Value Type='Text'>Jaliya Udagedara</Value></Eq></Where>";

  • AND Operator - Retrieve items that matches the following condition,
                                      (Field1 >= 500) AND (Field2 <= 1000)

           oSPQuery.Query = "<Where><And><Geq><FieldRef Name='Field1'/><Value Type='Number'>500</Value></Geq><Leq><FieldRef Name='Field2'/><Value Type='Number'>1000</Value></Leq></And></Where>";

  • OR Operator - Retrieve items that matches the following condition,
                                      (Field1 >= 500) OR (Field2 <= 1000)

           oSPQuery.Query = "<Where><Or><Geq><FieldRef Name='Field1'/><Value Type='Number'>500</Value></Geq><Leq><FieldRef Name='Field2'/><Value Type='Number'>1000</Value></Leq></Or></Where>";

  • BeginsWith, AND, Contains
           oSPQuery.Query = "<Where><And><BeginsWith><FieldRef Name='Name'/><Value Type="Text">Jaliya</Value></BeginsWith><Contains><FieldRef Name="Name" /><Value Type="Text">Udagedara</Value></Contains></And></Where>";

  • IsNull - Retrieve all items Where Name field is empty,
           oSPQuery.Query = "<Where><IsNull><FieldRef Name='Name'></FieldRef></IsNull></Where>";

I think I wrote some examples for most common scenarios. Here is a table of Comparison Operators used in SPQuery Class.

Comparison Operators
General Meaning
Eq
=
Gt
> 
Lt
< 
Geq
>=
Leq
<=
Neq
<> 
Contains
Like
IsNull
Null
IsNotNull
NotNull
BeginsWith
Beginning with word
DateRangesOverlap
compare the dates in a recurring event with a specified DateTime value, to determine whether they overlap


Things to Note

But when writing these queries there is some thing that you all should note about. That is, if your field name contains any spaces for example like "First Name", in your FieldRef Name if you put as 'First Name', you will get a error like "No Matching Field". The reason behind this is when you are leaving spaces in field names, the actual field name changes. You can get the correct field name by opening the List in InfoPath designer and referring the name in that field. For 'First Name', you might get something like 'First_x0020_Name'.

Feel free to give me your feedback.

Happy Coding.

Regards,
Jaliya

Friday, June 10, 2011

How to create a SharePoint 2010 Polling Web Part easily

Today I am going write about how to create a simple and very user friendly SharePoint 2010 Polling web part. Since I am hoping to develop it as a fully customizable Polling web part, in here I am going to explain the concept behind it.

I had a requirement, which will allow SharePoint user's to vote for polls which are published by the SharePoint Administrator. You may think that we can use SharePoint Surveys which is already available in SharePoint 2010 as well as SharePoint 2007. But my thought of Surveys is, there are some limitations in Surveys and not to mention it has nice capabilities too.

If I talk about limitations, for an example I will mention one. Let's say that we want to create a Survey, which a user can vote once. And Survey has a nice optional inbuilt feature to block user from voting more than once. But again to one survey, we can add questions later. So let's take this scenario. Administrator adds a survey which has one question. He blocks user from voting twice. Someone votes and when he try to vote for the second time, SharePoint will not allow it. Then Administrator wants to add a another question to the created Survey. Then the problem arises. User can't answer to that question, because he is blocked from accessing the same Survey twice. So what will happen is, Administrator will have to take all the trouble of creating and configuring another Survey.

Since I did not want to get all the trouble, what I did was created a simple web part that will give the following functionalities.
  • Easy to add a new Poll with one question.
  • Can set a expiry date to the Poll and after it expires, users can't no longer see it or vote it.
  • Each user can't vote more than once.
  • Only the Administrator can view the results.
  • Results can be viewed as Bar Charts or Pie Charts.

Now I am going to explain how I created it. Concept is fairly simple.
  • First create two lists. One is to add Polls and the other is to store user's vote information.
  • Let's call the first list as "Poll List" and the other as "User Poll List".
  • Set "User Poll List" as a hidden list.
  • In "Poll List", create seven additional columns. Title is already there when you have created it. List columns are,
    • Title - string
    • Answers - Check Box, Set Check Box values as Yes,No,Pass. So Poll publisher can select which answers should be there in each question
    • Poll Created By - People Picker
    • Date Started - Date and Time
    • Date Expired - Date and Time
    • Total Yes - Number and this column is disabled
    • Total No - Number and this column is disabled
    • Total Pass - Number and this column is disabled
  • In "User Poll List", create one additional column. Again Title is already there. List columns are,
    • Title - string
    • Voter's Name - string
  • Now Open Visual Studio 2010 and create a Visual Web Part.
  • Put a some labels and set their text to empty and a Button. Let's name it as "Vote".
  • Put a Radio Button List, so later we can fill the answer to it.
  • Write method to get the last item in the "Poll List" which is not expired and call it in the Web Part Load event.
  • Fill labels and fill the radio button list from the received data of the last item.
  • Now in "Vote" Button click event we are going to insert user selected data to both lists.
    • First query the "User Poll List" and check whether there is a item which the 'Title' is the current question and the 'Voter's Name' is the current logged on user's name. If there is, that means current logged on user has already voted for the selected question.
    • If there is no item, that means he/she has not voted for this question yet. So first add a item to the "User Poll List" and then update (increase the value by 1) the 'Total Yes'/'Total No'/'Total Pass' field in the "Poll List" to the relevant question.
  • And that's all. Now you might think that there will be a heavy load in the "User Poll List" as user's votes.
  • For that when a question has expires, we will delete all relevant items in the "User Poll List". By doing that we can avoid getting "User Poll List" by overloading.
I have created a nice Polling Web Part using above steps. If you see any drawbacks of the above method, please feel free to post a comment and appreciating your feedback.

Happy Coding.

Regards,
Jaliya


Update - 06th December 2011

Hello guys, since a lot of people are asking for the source code of my Polling Web Part, I have uploaded the source. You can download it from here. Please note that, I have not uploaded the full source code. But I am pretty sure, you will find the provided source code interesting.

Happy Coding.

Regards,
Jaliya

Sunday, June 5, 2011

Watch For Process Start using C#

I wanted to write a console application, that will watch the system and trigger an event when a new process has started. So did some coding using ManagementEventWatcher Class which comes under System.Management namespace.

I am going to post down the code, but since this can be used to do unethical things like creating a simple virus, I will only write down the two most important methods.

// this method will capture every process start
public static void MonitorForProcessToStart()
{
      // create event query to be notified within 1 second of a change in a service
     WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1),
          "TargetInstance isa \"Win32_Process\"");

      ManagementEventWatcher watcher = new ManagementEventWatcher();
      watcher.Query = query;
      watcher.EventArrived += new EventArrivedEventHandler(ProcessStartEvent);
      watcher.Start();
}

In Here TimeSpan is a timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested, and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered.

// when a new process has started, it will trigger this event
public static void ProcessStartEvent(object sender, EventArrivedEventArgs e)
{
      // when this method has triggered a new process has started.
      // in here you can do what ever you want.
}

Using these two methods, there is a lot a good programmer can do. Not to mention you can do unethical things too. So I will not go deeper about the things you can do.

Feel free to give me your feedback.

Happy Coding.

Regards,
Jaliya

Friday, June 3, 2011

Debugging SharePoint Sandbox Solutions - Process 'SPUCWorkerProcess.exe' is not running?

When you have created for an example SharePoint 2010 Event Receiver as a Sandbox solution using Visual Studio 2010 and when you are going to debug your project, sometimes you might get this error "Process 'SPUCWorkerProcess.exe' is not running."

The reason behind this error is, if you are using SharePoint 2010 on a Domain Controller then by default Sandbox solutions are disabled on it. So if you're running SharePoint 2010 on a DC you will need to add a ACL Access Rule to enable Sandbox Solutions. ACL(Access Control List ) means with respect to a computer file system, a list of permissions attached to an object. So without this Access Rule the Microsoft SharePoint Foundation User Code Service will start but the SPUCWorkerProcess.exe won't. Because by default it is disabled. To enable it, you will need to run the following PowerShell script. Make sure to run PowerShell as Administrator.

$acl = Get-Acl HKLM:\System\CurrentControlSet\Control\ComputerName 
$person = [System.Security.Principal.NTAccount]"Users" 
$access = [System.Security.AccessControl.RegistryRights]::FullControl 
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit" 
$propagation = [System.Security.AccessControl.PropagationFlags]::None 
$type = [System.Security.AccessControl.AccessControlType]::Allow 
$rule = New-Object System.Security.AccessControl.RegistryAccessRule($person, $access, $inheritance, $propagation, $type) 
$acl.AddAccessRule($rule) 
Set-Acl HKLM:\System\CurrentControlSet\Control\ComputerName $acl

Happy Coding.

Regards,
Jaliya

Tuesday, May 31, 2011

Getting the Current User's SharePoint Group Name - SharePoint 2010, InfoPath 2010

Since I did not write a post about SharePoint 2010 for some time, thought to write a pretty interesting post about how to get the logged in user's SharePoint group name using InfoPath functionalities. And for those who don't like to do some coding to get the thing done, they will surely like this approach. Since this is going to to be a longer post, I think it's better to go as a step by step approach, so I will start from Step 01.

Step 01.

Select the Custom List and on Ribbon under List click Customize Form. Then the List will be opening in the Microsoft InfoPath Designer 2010 .

Step 02.

Click on Manage Data Connections in InfoPath Designer. Then add two receiving data connections as following.
  • First we will add a receiving data connection for web service UserProfileService.
Receive Data Connection for UserProfileService
SOAP Web Service
  • In the text box type, http://ServerName/_vti_bin/UserProfileService.asmx.
UserProfileService.asmx?WSDL
  • From the list of web methods, select GetUserProfileByName.
Web Method - GetUserProfileByName
  • Click Next and you'll be asked for set the value for Account Name, leave it blank as doing it would get the current User.
AccountName - Leave it blank
  • Tick Automatically retrieve data when the form is opened.
Tick - Automatically retrieve data when the form is opened
  • Click Finish.
  • Then let's start creating the receiving data connection for web service UserGroup.
Receive Data Connection for UserGroup

SOAP Web Service
  • In the text box type, http://ServerName/_vti_bin/UserGroup.asmx.
UserGroup.asmx?WSDL
  • From the list of web methods, select GetGroupCollectionFromUser.
Web Method - GetGroupCollectionFromUser
  • Click Next. You will be asked to set sample value for UserLoginName. In that screen click Set Sample Value and in the appearing box type domain\Administrator.
userLoginName - Domain\Administrator
  • Click OK and Next. In the appearing screen Untick Automatically retrieve data when the form is opened.
Untick - Automatically retrieve data when the form is opened
  • Click Finish. Now you have successfully created two receiving data connections.

Step 03.

Now we will have to modify the xml schema for GetGroupCollectionFromUser data connection. For that we we will need to extract the InfoPath form. To extract the form, in InfoPath form go to File and Publish and then Export. Select a Folder to export the files and the form will be extracted.

Export

Step 04.

Now when the form has finished exporting, go to the folder you have selected. You will see a list of files that has been created in Export process.  But in our case we only focus on GetGroupCollectionFromUser.xsd (the xml schema for GetGroupCollectionFromUser data connection).

Exported Files
  • First Close the InfoPath Designer. Because you can't edit files when are being used by the InfoPath designer.
  • Open GetGroupCollectionFromUser1.xsd in a text editor (I prefer Notepad++) and edit it as below.
    • Find the following line. Normally it's the 2nd line of the file.
                <s:import namespace="http://www.w3.org/2001/XMLSchema">
    • Add following below above line.
<s:complexType name="GetGroupCollectionFromUserType">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="userLoginName" type="s:string"/>
      <s:element minOccurs="0" maxOccurs="1" name="Groups">
        <s:complexType>
          <s:sequence>
            <s:element maxOccurs="unbounded" name="Group" >
              <s:complexType>
                <s:attribute name="ID" type="s:unsignedShort"></s:attribute>
                <s:attribute name="Name" type="s:string"></s:attribute>
                <s:attribute name="Description" type="s:string"></s:attribute>
                <s:attribute name="OwnerID" type="s:unsignedByte"></s:attribute>
                <s:attribute name="OwnerIsUser" type="s:string"></s:attribute>
              </s:complexType>
            </s:element>
          </s:sequence>
        </s:complexType>
      </s:element>
    </s:sequence>
  </s:complexType>
    • Find the following part.
<s:element name="GetGroupCollectionFromUser">
   <s:complexType>
     <s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="userLoginName" type="s:string">
         </s:element>
</s:sequence>
    </s:complexType>
  </s:element>
    • Replace it with the following code.
<s:element name="GetGroupCollectionFromUser" type="tns:GetGroupCollectionFromUserType">
</s:element>



Step 05.

Now right click on the manifest.xsf and choose Design. Choose GetUserProfileByName data connection and apply rules on the PropertyData field as following.
  • In Fields bar click on Show Advanced view.
Advanced view of Fields
  • Under Fields Select GetUserProfileByName (Secondary).
  • Then Add a rule. 
GetUserProfileByName (Secondary)
  • The rule condition is Name="AccountName", rule type is Action.
Select a field or group
GetUserProfileByName - Name
Type Text
    • Type "AccountName".
Type "AccountName"
  •  The rule actions are:
    • Set field’s value. Under Field, Set Field as follows.
GetGroupCollectionFromUser (Secondary) - Name
    • Then Under Value, Set Value as follows. Click fx and then Insert Field Or Group.
GetUserProfileByName - Value
    • Don't Click OK yet. Click Filter Data. The Click Add.
Select a field or group
GetUserProfileByName - Name
    • Click OK.
Type Text
Type "AccountName"
    • Click OK. Then you will get something like this.
Complete Formula (fx)
    • Click OK.
    • Then add another Action. Action is Query for data from GetGroupCollectionFromUser. 
Query for data - GetGroupCollectionFromUser
    • Click OK.
Step 06.

Now create a formatting rule for a field that you want to disable/hide if current user is not member of a given SharePoint Group. Put a condition as below, where the "LCGD Clerk" is the SharePoint Group Name.

Select a field or group
  • Set the Name in GetGroupCollectionFromUser (Secondary Data source).
GetUserProfileByName - Any occurrence of Name
Type "LCGD Clerk" (SharePoint Group Name)

Step 07.

Now Everything is completed. Final step is Publish the form.

Hope you all got a good idea about how to get the Current User's SharePoint Group Name using InfoPath functionalities. Appreciate your feedback.

Happy Coding.

Regards,
Jaliya

Friday, May 20, 2011

Started using jQuery

jQuery - This thing has been going around and around through my head for some time and thought why not put my hands on it and check what this jQuery really is and do some things using jQuery. Started learning from the scratch few minutes ago and so far so good.

Before started putting my hands on developing, read some articles to get some basic knowledge on what jQuery really is and what are the things that can be done using jQuery. It seems like for web developers and web designers, there is a lot you can do and you will never even imagine how a simple and small code snippet can do such things and thats of course by calling nicely designed functions in jQuery JavaScript library.

jQuery is a cross-browser JavaScript library which will simplify JavaScript programming. All you need is downloading jquery.js file and a simple text editor (well I am using notepad++).

You can download jquery.js from here.

Happy Coding.

Regards,
Jaliya

Wednesday, May 18, 2011

Basics of ASP.NET MVC

If you are developing web applications using ASP.NET, I am sure every one must have gone through this thing called ASP.NET MVC. So for a beginner or even for myself to keep some things remembered about ASP.NET MVC, thought to write this post.

The ASP.NET MVC Framework is a web application framework which is used to develop web applications in Model-View-Controller design pattern (I will briefly describe about the MVC pattern latter in this post). Actully ASP.NET MVC Framework is a part of the ASP.NET Web application framework which comes under Microsoft .NET framework.

There are exactly two different programming models which can be used to create ASP.NET Web Applications. One is ASP.NET MVC and the other is ASP.NET Web Forms. Since in here we are mainly focusing on ASP.NET MVC, we'll move forward with that.

First of all to get a whole imaginary idea of MVC, take a good look at the following image.

ASP.NET MVC
In ASP.NET MVC everything is handled by the above 3 main components which are Model, View and Controller. Let's start with the Model component.

  1. Model Component
    • Model represent the data or activity corresponding to the application. Simply means it represents the state of the application. (Ex: DB)
  2. View Component
    • A View is responsible for rendering a user interface to display information which it accepts from Controller Component. (Ex: Web Pages)
  3. Controller Component
    • A controller handles interactions and then updates the model to reflect a change in state of the application, and then passes information to the View. (Ex: Web Services)
When creating ASP.NET MVC Web Applications, the namespace that contains classes and interfaces that supports the ASP.NET MVC is System.Web.Mvc.

Hope you get something out of this post. Appreciate your feedback.

Happy Coding.

Regards,
Jaliya


Tuesday, May 10, 2011

Silverlight 4 Image Slideshow

Since Silvelight is giving more rather than similar functionalaties when comparing to Adobe Flash, thought to write a post about some simple browser plugin which I have developed using Microsoft Silverlight 4.

First of all Microsoft Silverlight is an application framework somewhat similar to actually based on Microsoft .Net framework for developing browser plugins and rich internet applications.

For More information about Microsoft Silverlight visit,

This plugin is developed using Visual Studio 2010 and Microsoft Silverlight 4.


Please feel free to give me your feedback. And if anyone needs the fully functioning source code please do contact me or leave a comment here.

Happy Coding.

Regards,
Jaliya