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

Tuesday, April 26, 2011

Folder Analyser and Compressor for easy file uploading

After some time since my last post, thought to write a post about this simple tool I have developed today.

Have you ever faced to a situation that you have around 150 image files and you need to email those to a friend of yours. If you take Yahoo your maximum attachment size will be 10MB. In Gmail it's 25MB. So if you want to email all your image files, the manual process would be creating separate folders that can only contain 5MB or 10MB files and check each image file's size and add them to those folders. Then compress them all and email. Not to mention that you will have to suffer a lot when adding files to folders, because it should not exceed the size limit of 5MB or 10MB.

Since I did face the problem and I have created this simple tool.
 Free Download

Folder Analyser and Compressor
First you can choose the Main folder that contains all the images and then select the size of a single zip file to be created.

Then by a single click tool will create you many folders which has the maximum size of given size and they will contain the all images. And finally again by a one single click you can compress them all.

Please feel free to give me your feedback.

Happy Coding.

Regards,
Jaliya

Wednesday, April 6, 2011

Application for Synchronize Folders

Since I am a big lover of music(of course it's classic music), I have my Dell filled with songs and I am always downloading and updating music inventory in my Dell. Last week I have backed up all the files in my Dell into my portable disk drive. And since that day I have downloaded many songs.

Then it came to my mind that, I need all those new songs to be synchronized with the folder where I have backed them up in and it will be a headache to do it manually every time. So thought about writing a application, which will do the synchronization part for me. I only need to give the path of my updated folder and the path of my back up folder. If I want, the application will create me a log file stating all the information about the data transfer between two folders and specially with the no of copied files, their names and synchronized date and time. So I can refer it in future time.

Synchronize Folders


For free download and setup this simple application on your own machine,
 Free Download

Please feel free to give me your feedback.

Happy Coding.

Regards,
Jaliya

Monday, April 4, 2011

Start a SharePoint Designer Workflow using C# and Workflow Status keeps appearing as 'Starting' - SharePoint 2010

Back to SharePoint programming again. I needed to programmatically start a workflow from a InfoPath form using C#, which was designed using Microsoft SharePoint Designer 2010. So started writing the code using Windows SharePoint Services. Wrote the code and it was triggering the workflow nicely.

Code snippet for starting the workflow, I am writing down.

//oListItem is the item I am running the workflow on and "Create Items" is the name of my workflow
oListItem.Web.AllowUnsafeUpdates = true;
SPWorkflowManager workflowManager = oListItem.Web.Site.WorkflowManager;
SPWorkflowAssociationCollection workflowAssociation = oListItem.ParentList.WorkflowAssociations;
foreach (SPWorkflowAssociation Association in workflowAssociation)
{
    if (Association.Name == "Create Items")
    {
         workflowManager.StartWorkflow(oListItem, Association, Association.AssociationData, true);
         break;
    }
}

Of course it was triggering the workflow nicely, so I waited for the workflow to complete. And that's when I noted that the status of workflow keeps appearing as 'Starting'. First I thought it's because of the performance in my Virtual Machine and after waiting for around 2,3 minutes I knew, there is something else that is going wrong. I clicked on the workflow status and in that page there was a message "Due to heavy load, the latest workflow operation has been queued. It will attempt to resume at a later time". I went back to the list and I kept refreshing the page and after around 5 minutes status changed into 'In Process' and then after 2 or 3 minutes status changed into 'Completed'. Then I was pretty sure that something is not working properly. I did some googling and found out some possible reasons.

Possible reasons for this is,
  • SharePoint 2010 Timer service in Windows Services is not running.
  • You are kicking off the workflow from the user account Administrator.
  • The Start option in settings and the poor design of the workflow in SharePoint Designer.
First I checked SharePoint 2010 Timer service in Windows Services to see whether it is down or not. It was up and running. Then my second option was to check workflow kick off user. I checked it, I am not logged in as Administrator, it is some other user(lets say user1) I have created in Active Directory and granted permission to SharePoint server. Then I checked the workflow Start option and the design of the workflow. I have checked 'Allow this workflow to be manually started' and I checked the design of the workflow, to me it is nicely designed and no bottlenecks.

Apart from my situation, I thought I might give you some idea about how a poor design of workflow can decrease the execution speed of workflows. Lets say that you want to trigger off the workflow each time an Item is updated. So in SharePoint designer you can set under the Start options in the workflow to 'Start workflow automatically when an item is changed'. Now you have designed the workflow to Update List Items and you are giving the parameters to update(set field in Current Item). Here there is a important thing, that you will have to consider when designing the workflow. When the first parameter has updated, it has done another change to the item. And now the workflow fires again. So if you have not been careful enough, this will happen repetitively. Because of that your workflow status will be "Starting" when you check the workflow status in the browser. After a timeout it will stop updating that particular field and go to update the next field and the same process repeats again and again for all parameters. So for these kind of situations, the best practice is to test the field for whether has it already been changed to the new value that you are about to change it to. If yes do not update it again, move to the next field. I think now you might have some idea about increasing the execution speed of a workflow specially when the Start option is set to 'Start workflow automatically when an item is changed'.

And back to my situation, Everything seems perfect and still I am getting this status of workflow as 'Starting' for some long time. I was having enough of this and again I started rechecking everything. SharePoint 2010 Timer service is doing good and again checked the kicking off user of the workflow. No, I am not logged in as Administrator. And here something came to my mind that, I might not be logged in as the Administrator. But in the code I have written, I did not give any Authentication details. So there is a possibility that it uses the Administrator privileges. To check that I clicked on the workflow status 'Starting' for the item. I was astonished by one single thing from the page that appeared. That is under Workflow Information the Initiator of workflow is still 'System Account'. First I felt happy, because I knew that this can be the reason for my problem and then my problem was when I am logged in not as the Administrator and I am kicking off the workflow from a different user account and still how can be the Initiator of workflow is 'System Account'? To me, my only explanation is I am not giving the Authentication details in the code, so thought to add the Authentication part for the code to access the list from the user account User1.

Wrote the code and again added a new item to the list from InfoPath form which I have written all the code in. Kept looking at status of the workflow. Again it was 'Starting' and this time it was around for 30 seconds. Then 'In Progress' and then 'Completed'. For the whole process it took less than 1 minute to complete. I felt so happy and at last it did solve my problem.

I am writing the code down for Authentication part.

SPSite oSPSiteGetToken = new SPSite("http://ravanaserver/");
SPUserToken token = oSPSiteGetToken.RootWeb.EnsureUser("user1").UserToken;

using (SPSite oSPSite = new SPSite("http://ravanaserver/", token))
{
     using (SPWeb oSPWeb = oSPSite.OpenWeb())
         {
               //your code
          }
}

So from what I have learned, there is one thing we all should consider when writing codes.
  • Always use Authentication. For example if you are writing a code for CRUD actions on a list item and if you are not doing it as the Administrator, always use the specific user authentication in the code. Because default authentication is the System Account.
So hope someone gets something from this. Feel feel to correct me and give me your feedback.

Happy Coding.

Regards,
Jaliya

IMPORTANT NOTE :

Thursday, June 16, 2011

I just found out another reason that could keep Workflow Status appearing as 'Starting' for long time.
  • In your computer's Services "SharePoint 2010 Timer" service should be started, Startup Type should be "Automatic" and Log On As should be your SharePoint Administrator.

Happy Coding.

Regards,
Jaliya