Monday, December 12, 2011

Script to install SharePoint 2010 in Windows 7

You are ready to install SharePoint 2010 in Windows 7? Then you are at the right place. For the installation you have to download all required and follow the complete MSDN article and then execute step by step. If there is something which do all the steps for you then how it is? good right?
Yah! there is a great script which is written by Ram which installs SharePoint 2010 on windows 7 PC. Go and download and execute guys. Great script.

Get the information here.

How to find Inactive computer accounts in active directory?

Do you know how can we do this? Either we query the AD to get the information by writing code in C# or manually check the AD for the inactive accounts. But, there is another simple way which will get this information without any big efforts. Yes, using Powershell script.
$COMPAREDATE=GET-DATE
$NumberDays=90 
$CSVFileLocation='C:\TEMP\OldComps.CSV' 
GET-QADCOMPUTER -SizeLimit 0 -IncludedProperties LastLogonTimeStamp | where { ($CompareDate-$_.LastLogonTimeStamp).Days -gt $NumberDays } | Select-Object Name, LastLogonTimeStamp, OSName, ParentContainerDN | Sort-Object ModificationDate, Name | Export-CSV $CSVFileLocation 
You have to provide the days - the timeline of inactive accounts and where to save the output of inactive accounts list.

The complete information is available at this post.

Open PDF files directly in browser SharePoint 2010

Here is how you can tell SharePoint 2010 site to open the PDF files in the browser instead of prompting the user to save or open the PDF. This will be a great option to the most of end users. This needs simple Powershell scripting run on the server. Below is the code we should use:
# <# 
# .DESCRIPTION 
#  This script adds new MIME type to "AllowedInlineDownloadedMimeTypes" property list of defined SharePoint 2010 Web Application.
#
#  Script prompts you for MIME type and Web Application URL.
#
#  Code shall run in context of Farm Administrators group member.
# 
# .NOTES 
#       File Name   : Add_MIME_Type.ps1 
#       Author      : Kamil Jurik, WBI Systems a.s. 
#       Created     : 11/12/2011 
# 

If ( (Get-PSSnapin -Name "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null ) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
Get-SPWebApplication
$WebApp = Get-SPWebApplication $(Read-Host "Enter Web Application URL")
Write-Host "Mime Type Examples:""application/pdf, text/html, text/xml"

If ($WebApp.AllowedInlineDownloadedMimeTypes -notcontains ($MimeType = Read-Host "Enter a required mime type"))
{
  Write-Host -ForegroundColor White "Adding" $MimeType "MIME Type to defined Web Application"$WebApp.url
  $WebApp.AllowedInlineDownloadedMimeTypes.Add($MimeType)
  $WebApp.Update()
  Write-Host -ForegroundColor Green "The" $MimeType "MIME type has been successfully added."
} Else {
  Write-Host -ForegroundColor Red "The" $MimeType "MIME type has already been added."
}
The powershell script do the magic for us. Below is the explanation.
  1. It is taking the web application url as input
  2. And if the web application is not allowed the the PDF files MIME type to it's allow downloadable mime types collection then it will add it.
So, once you run the code the files will be open up in the browser instead of prompting the user. The server will not allow PDF files by default as it think PDF files are not secure.

Note: The script should run with the account who has FARM administrator level access.
For more details about it: please check technet article.

Sunday, December 4, 2011

ASP.NET 4.5 new features

The new version of ASP.NET 4.5 has many features integrated and there are many additions to the Visual Studio as well. I am really excited to see all of these features in hand.... These functionality improvements makes applications more easier and faster. The features are added in both Web forms and MVC.

ScottGu's blog has all these features explained in detail as series of posts. Readers, please read all of these and know the new and great features coming for better productivity.

ASP.NET 4.5 New Features

Thursday, October 13, 2011

Get TaskID in SharePoint custom Visual Studio workflows

When you are working with custom workflows implementing in Visual studio, you might be sending the emails when a task is created. By default SharePoint sends an email when a task is assigned to a user. But, if you want to customize the email body and subject, then you will use send mail activity and will give link to the user. Here the problem starts.
In CreateTask activity in Visual Studio you cannot get the taskID as the task is not yet created. What to do??? So, to get the task identifier we have to implement the below approach.
  1. CreateTask Activity
  2. TaskCreated Activity 
  3. SendMail Activity
  4. OnTaskChanged Activity
  5. TaskComplete Activity
Remember, until unless the Activity TaskCreated is executed the TaskID will not be available in workflow context. The main reason behind is, the task created information is not caught by SharePoint workflow anywhere until we run this activity. So, in the TaskCreated activity you can get the AfterProperties of the task and in those properties you will get the recent created task identifier which is integer.

So, note that in custom workflows which are implementing through Visual Studio the only way you can get the TaskID is AfterProperties of the TaskCreated activity. I have wasted hours when I was learning these. Hope you liked it.

The context has expired and can no longer be used–SharePoint and Reporting Services

Error:

"System.Web.Services.Protocols.SoapException: Report Server has encountered a SharePoint error. ---> Microsoft.ReportingServices.Diagnostics.Utilities.SharePointException: Report Server has encountered a SharePoint error. ---> Microsoft.SharePoint.SPException: The context has expired and can no longer be used. (Exception from HRESULT: 0x80090317) ---> System.Runtime.InteropServices.COMException: The context has expired and can no longer be used. (Exception from HRESULT: 0x80090317) --- End of inner exception stack trace --- at Microsoft.ReportingServices.WebServer.ReportingService2005Impl.GetDataSourceContents(String DataSource, DataSourceDefinition& Definition) at Microsoft.ReportingServices.WebServer.ReportingService2006.GetDataSourceContents(String DataSource, DataSourceDefinition& Definition)"

Solution:

This was coming completely due to the sever clock has wrong time set. So, by adjusting the time on the server solved the problem.

Special thanks to "Steve Mann" for finding the solution. It is a great find as it is just by guessing and thinking in different ways. Good one Steve.

Saturday, October 8, 2011

Close SharePoint 2010 Dialog through code

In SharePoint 2010, the new feature is added is the dialog framework. With the help of this, user stays on the same page and able to get the information without go away from the current page. So, there are ways that we can close the dialog from the code in different ways. Below are the mainly used implementations in javascript and code behind.
Javascript:
<script type='text/javascript'>window.frameElement.commitPopup()</script>

The window.frameElement is the node which holds the current dialog window. commitPopup() method which commits the popup and closes the dialog from the page window. So, by simply calling the above method, the dialog window will close automatically.

Code-Behind:
HttpContext context = HttpContext.Current;
if (HttpContext.Current.Request.QueryString["IsDlg"] != null){
context.Response.Write("<script type='text/javascript'>window.frameElement.commitPopup();</script>");
context.Response.Flush();
context.Response.End();
}

The dialog framework recognizes an additional parameter in the request named "IsDlg=1", which says open the page in dialog box. So, in code-behind simply check for query string parameter and if it exists then call the javascript method mentioned above by writing it to browser. So, when it executed the dialog will be closed.

This is a very nice tip which helps in some custom implementations. Hope it helps.

Exception of type 'System.Workflow.ComponentModel.WorkflowTerminatedException' was thrown

This is the error you see when you use the TerminateActivity in Windows workflow foundation/Visual Studio workflow development for SharePoint applications. The main reason behind why this exception is "We are terminating the current running workflow in middle and framework rises the exception that the workflow is terminated".

The main use of this TerminateActivity is for terminating workflow only. But, I do not recommend to use this activity in your workflows as this is a kind of exception which is throwing by WWF framework. Instead we could try

  • Filter the logic by if, else and end the workflow.
  • By throwing the exception from your code and by using the FaultHandler catch the exception and write it to logs.
  • If we want to stop the workflow, we may write the code to stop the workflow by using CancelWorkflow(workflow).
  • Even if you use the activity if you do not want to  see the above exception in the workflow logs then you might do this. From the "Properties" window the attribute "Error" – fill this field with some text like "Workflow terminated as the reviewers not found for the current item" etc. So that user can understand the error clearly instead of the exception details.

Hope it helps.

Saturday, August 20, 2011

Customize ReportViewerWebPart in C# for all SharePoint Zones

This is one of the major milestone I have achieved recently to customize the report viewer web part for SharePoint sites. The issue I was facing: the SharePoint site which I have developed was too complex and it exposed via 3 zones. http://intranetsite, http://extranetsite, https://internetsite
  1. http://intranetsite – which is Windows based authentication site and for intranet people.
  2. http://extranetsite – Which is Windows based authentication site and for extranet people
  3. http://internetsite – Which is Forms based authentication site and for internet people.

For each sub site in our implementation it should show the SSRS dashboard report of the site we are in which will contains all information of the site through reports. But, SSRS reporting services and report viewer web part has a limitation in SharePoint integration mode:

System.Web.Services.Protocols.SoapException: The specified path refers to a SharePoint zone that is not supported. The default zone path must be used. ---> Microsoft.ReportingServices.Diagnostics.Utilities.SecurityZoneNotSupportedException: The specified path refers to a SharePoint zone that is not supported. The default zone path must be used.

e-Filing of Income Tax Returns online INDIA

Yes, using the e-filing process one can file in tax returns just within a few clicks at any time of the day and that too without any hassles. Using this technology all you have to do is fill the form and submit it, online or offline.

This is one of the best option available to us. It is very difficult to file for the income tax returns in regular process. Where as the e-filing process is simple and there is no need to dependent on anyone and you can do yourself with the required documents and information. The very first time you will face simple issue but it will be the nicer process once you get in. So, start using this feature and enjoy.

How to file Income Tax Returns

Process of E-filing of tax returns

The above links are quite enough to do what you are looking for. So, please use them to not miss to get your income tax returns.

Sunday, August 7, 2011

Set Page Layout programatically for a publishing page

If you like to create pages in site through code then you have to set the page layout for the page. Below is the simple code which does that works well.
private static void SetPageLyoutToPublishibPage()
        {
            using (SPSite site = new SPSite("http://SP2010Site"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
                    PageLayout pageLayout = null;
                    foreach (PageLayout p in publishingWeb.GetAvailablePageLayouts())
                        if (p.Name.Equals("BlankWebPartPage.aspx", StringComparison.InvariantCultureIgnoreCase))
                        {
                            pageLayout = p;
                            break;
                        }

                    PublishingPage page = publishingWeb.GetPublishingPage(web.ServerRelativeUrl + "/Pages/Default.aspx");
                    page.CheckOut();
                    page.Layout = pageLayout;
                    page.Update();
                    page.CheckIn("");
                }
            }
        }
Any issues, please post it here.

Set default Page Layout for a SharePoint site

Before reading this post, please take a look at this post: Get default Page Layout for a SharePoint site.
Setting default page layout to a SharePoint site is very important. For example if you are trying to create a new site/web template in SharePoint and from it you like to create sites then do not forget to set default page layout [especially in SharePoint 2010].
private static void SetDefaultPageLayout()
        {
            using (SPSite site = new SPSite("http://SP2010Site"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);                    
                    PageLayout pageLayout = null;
                    foreach (PageLayout p in publishingWeb.GetAvailablePageLayouts())
                        if (p.Name.Equals("BlankWebPartPage.aspx", StringComparison.InvariantCultureIgnoreCase))
                        {
                            pageLayout = p;
                            break;
                        }
                    publishingWeb.SetDefaultPageLayout(pageLayout, true);
                    publishingWeb.Update();
                }
            }
        }
Here, I have set the Blank Web Part page as the default page layout to the SharePoint site. This way you can control the logic as your wish...

Get default Page Layout for a SharePoint site

Sometimes when you are provisioning sites through web/site templates you might miss one thing that setting default page layout for the web. In SharePoint 2010 especially you have to face this issue when you try to browse to the page "Page layouts and Site Templates" from site settings page. If there is no default page layout then there are problems while creating new page as well. So, this could be a major issue in some special cases.

Sometimes you might get the error like "Data at the root level is invalid. Line 1, position 1" because of this.
So, we have to know is there any default page layout set for the site and below is the perfect console application solution for it.
        private static void GetDefaultPageLayout()
        {
            using (SPSite site = new SPSite("http://SP2010Site/"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);

                    PageLayout pageLayout = publishingWeb.DefaultPageLayout;
                    Console.WriteLine(pageLayout.Name + "Url : " + pageLayout.ServerRelativeUrl);
                }
            }
        }
So, this way you can trace easily some kind of problems which create problems to us. :)

Copy users from one SharePoint group to another group

This is one of the question raises from many people who has to copy users from one SharePoint group to another group. There is no direct way you can directly copy users through browser. So, it could be problem to site owners and administrators to add all users again. How to solve these kind problems?

Here are some scenarios of why it is actually needed?
  1. There are so many SharePoint groups in the site and need to copy the users from one group to another group.
  2. Two sites needed same permissions and one site group permissions need to copy to another group.
So, from the ways I know below are the possibilities.

Saturday, July 16, 2011

Activate only selected features while deploying a solution package in Visual Studio 2010

In Visual Studio 2010 SharePoint Developer Tools is what we use to develop quick solutions to SharePoint. With these tools we can quickly deploy into SharePoint environment as well. But, the only issue we see here is, if we are trying to deploy a package which contains a set of 5 features then all of them will be activated by default. But, this might not be a valid behavior for us. We need to activate only 3 features while deploying the package and the other 2 features need to be installed into SharePoint but should not be activated. So, this is not available by default in the SharePoint Development Tools in Visual Studio 2010.

Recently when I was browsing in internet for this, how to deploy only selected features into SharePoint, but not all and found a great Visual Studio 2010 Extension. Which is a great tool to use and works perfect.

Download the extension here.

Once you get his extension, directly run it by double clicking on it. Before you see the changes, close any existing Visual Studio instances and reopen them. The extension will be added to Visual Studio 2010 and ready to use. But, to use it in your SharePoint project, you need to do one more exercise.

Permissions for document 'Move' operation in SharePoint

This might not be a super thing to blog but very important point to note. Through code I have tried to move a document from one document to another document by using file.MoveTo() operation. It was working very fine when I tested as I am administrator in the dev environment. But, when I have given to QA for testing it was failing. I have tried so many combinations of giving different access to them and nothing worked. When I have given them either Owners or site collection administrator access it started working. So, I was not understanding of what was the permission level do they need?
After tried different combinations of permission levels to them one matched and worked perfect. That was Contribute and Approve permission levels. So, for the logged in users who don't have both of these permission levels the code is failing for them and the  result file was not moving successful. [Another note is, I am using publishing site with auto approval of document in document library.]

Code used:
SPFile file = currentItem.File;
file.MoveTo(filePath, true);
For a document move operation the logged in user should need both Contributor and Approve permission levels for publishing web sites in SharePoint.

I am thinking it is correct according to my analysis and research. Please let me know if something is wrong in this post or any better solutions.

Move and Copy operations in SharePoint Lists

Do not know how many of you aware of these important points.

  1. When you move a document/list item from one document library/list to another then the versioning will also be retained in that destination library/list.
  2. When you copy a document/list item from one document library/list to another then the versioning will not be copied to the destination library/list.
  3. When you move a document/list item from one document library/list to another then the metadata will not be copied. To do that you should have same columns in both libraries/lists and they should use same content type [Means they should have same schema].

How to hide a specific div in SharePoint 2010 dialog

The class in styles "s4-notdlg"[means don't show in dialog not+dlg] is what we have to use to not show a specific division on SharePoint 2010 dialog.

For example, there is a banner in the header position of the master page and you do not want to show the banner in the dialog then the only simple option for you is using a simple css class to your banner div. If you add this class to your banner then when no dialog on the page no change to your implementation but when you are on dialog then the division with the class "s4-notdlg" will be forcibly applied to "display:none".

So, the moral of the story it is a good tactic that Microsoft SharePoint team developed to solve some major issues in design on dialogs.

Saturday, July 2, 2011

Upgrade SharePoint 2007 Visual Studio projects to 2010

This will be very helpful for the scenarios where we have custom solutions developed in Visual Studio 2008 for SharePoint 2007 environment and upgraded 2007 site to SharePoint 2010 and now in SharePoint 2010 we like to do some changes to that custom solution files. Simply, we have a SharePoint 2007 site upgraded to SharePoint 2010 and then it has some custom solutions developed like web parts, solution packages, features etc. Now, we are in SharePoint 2010 environment and like to extend the custom web parts, features from the earlier version of SharePoint. So, we need some sort of support to migrate our SharePoint Visual Studio projects from Visual Studio 2008 to Visual Studio 2010 to deploy to SharePoint 2010. I believe you all are clear till this point.

Get the tool here. http://archive.msdn.microsoft.com/VSeWSSImport/Release/ProjectReleases.aspx?ReleaseId=4183

It is simple project and when you build it, you will get executable and installs template to Visual Studio. But, the only preliminary requirement here is, you have to install Visual Studio 2010 SDK to open project.

Once everything is ready, you will see a new template named "Import VSeVSS project" under new project category. Here you go.....

SharePoint workflow staus codes

This is very important for SharePoint devs. Even I have used them many times, but I forget the status codes almost every time. So, might be happening to everyone too and planned to blog in my blog.

The enum SPWorkflowStatus in the namespace "Microsoft.SharePoint.Workflow" in the library "Microsoft.SharePoint" is what we have to use for these status codes.

0
NotStarted
Not Started
1
FailedOnStart
Failed On Start
2
InProgress
In Progress
3
ErrorOccurred
Error Occurred
4
StoppedByUser
Cancelled
5
Completed
Completed
6
FailedOnStartRetrying
Failed on Start (retrying)
7
ErrorOccurredRetrying
Error Occurred (retrying)
8
ViewQueryOverflow
--
9-14
Unknown
Unknown
15
Cancelled
Cancelled
16
Approved
Approved
17
Rejected
Rejected

Hope this is enough for us to get what we needed.  :)

Error occurred in deployment step ‘Recycle IIS Application Pool’: The communication object, System.ServiceModel.InstanceContext, cannot be used for communication because it has been Aborted

When we are developing custom code through Visual Studio 2010 for SharePoint 2010 sites and when we try to deploy the solution then we might see the below error.

"Error occurred in deployment step ‘Recycle IIS Application Pool’: The communication object, System.ServiceModel.InstanceContext, cannot be used for communication because it has been Aborted."

When I see this very first time and did not get any clue of what it is looking for and why it is not able to communicate to SharePoint sites. After doing some trail and error methods and checking Event Viewer, Logs etc... failed in all the ways in deploying the custom piece to SharePoint. Finally, a simple solution worked but didn't find any reason what is the main issue!

Solution:
  1. Sometimes when I do rebuild the project and deploy directly without doing "Package" from Visual Studio it is successful. 
  2. If it is not successful then the only way I see is RESTART your visual studio and deploy.
  3. (From below comments: ) Restarting "Windows Management Instrument" service will work. (I haven't tested).
Frustrated hours come to an end... There is some way always to make our life go smooth! Happy programming.

Thursday, May 19, 2011

Get bytes from Stream in c#

I know you may think what is the need of this post as this is very minor or simple to think and write. But, whenever I need to get bytes from a stream object, I always forgot it. This is simple but most of the times we used to Google. So, planned to write it to remember at least myself next time.
public byte[] GetBytesFromStream(Stream stream)
{
     byte[] buffer = new byte[16 * 1024];
     using (MemoryStream ms = new MemoryStream())
     {
        int read;
        while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
           ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
     } 
}
 

Check list exists in SharePoint site

This is very generic issue all SharePoint developers face at initial stages. As there is no default method available in SharePoint API to check whether if list exists in the SharePoint site, everyone write the below code:
SPList list = web.Lists["Task List"];
If(list != null)
{ 
    //Some code on list.
}
This is not correct to code like this. We all know generics and collections in c#. SPWeb.Lists is a collection and if you want to get one object from collection either we need to pass index or the key. If that didn’t find in the collection it gives us the exception. So, in our example if the Sharepoint site don’t have list named “Task List” then you will give run time exception in the line 1 itself. So, there is no point of checking whether list object is null. So, here is where many people stuck at. As Lists is plain collection object there is no other way of checking for the list exists in collection other than below.
private static bool ListExists(SPWeb web, string listName)
{
try
{
SPList list = web.Lists[listName];
}
catch
{
return false;
}
return true;
}
I know what you are thinking [Is this solution right?]. Yes, unfortunately there is no other way. So, we have to use this to check whether list exists in a SharePoint site.

Saturday, April 16, 2011

How to go to SharePoint Webpart Maintenance page for any page

This is one of the great tips we have in SharePoint. There are many scenarios why we need this. I had very tough time to migrate a SharePoint 2007 site to SharePoint 2010 site. What happened was,
  1. The other team deployed a custom web part 2 years ago.
  2. Used that web part on different pages in that site.
  3. They have taken the site template from the option "save site as template".
  4. After an year, they have removed  that web part from the site collection.
  5. But, with the same site template they have taken in the step #3, they created few sites in the same site collection after they removed the web part from environment.
  6. Remember, the site template still has the references to that custom web part. So, when I try to migrate it always fails..
Sometimes it is very difficult to find what is causing the problem. The sites created were not published sites. So, I cannot go to Edit Properties of the page and go to web part maintenance page from there. As the default.aspx page is directly in the root of the site/web I do not have any other choice to go to web part maintenance page. After a long research I found from Google that the querystring ?contents=1 will do job for me.

Resolution:
In SharePoint, for any web part ASPX page if you append the querystring ?contents=1 then it automatically redirects to the web part maintenance page.

Example: 
For the SharePoint site page
http://mossurl/default.aspx the web part maintenance page url is
http://mossurl/default.aspx?contents=1

Sunday, January 16, 2011

Clear and then disable controls in infopath

This is simple for reading, but difficult to implement in infopath forms. To disable controls we have to use “Conditional Formatting” option of a control. To clear content of a control then we have to use “Rules” option of a control. But, the sequence of execution of these two causes some problems. Take below scenario.
I have a table and each row the first column contains a checkbox and all other 4 columns are having date field, textbox, drop down and date field respectively. Now, the logic should be this.
  1. The default state of checkbox is selected.
  2. When user enter some data in all other 4 fields and now he thought the row should not allowed to enter data then he deselect the checkbox. When user deselects then the first thing should happen is clear the content in all the 4 controls and then all controls should be disabled.
  3. When again user select the checkbox then the controls should be enabled.
This is what to be happen and the first trail when I tried to implement I did below things.
  1. On all other 4 controls I added a rule that when checkbox selected state is false then set the current field to empty.
  2. And then I added a conditional formatting on them to disable when the checkbox state is unchecked.
I did deploy them to SharePoint and when I tested, surprisingly they are not working as expected. The controls are going to disable state but not clearing content in them when I deselect the checkbox. And researched and found that the Rules are not executing. [Didn’t find the reason yet.] And then thought about for alternatives and came up with reverse way. That is, applying rule on the checkbox instead of other controls.
Earlier, I have applied rules on the each and every individual control which needs to be cleared based on checkbox state – Which doesn’t work. Now, I have applied the same logic but applied rule on the checkbox [As there are 4 controls, 4 times I have added set field to empty] and which is working like charm.
So the conclusion I want to tell to you is, when I apply conditional formatting and then rules something is causing problems in the sequence of execution. So, depends on what your control, rules needs to be executed apply the rules on that control only. That should work perfect.

Date validation in Infopath forms

In SharePoint infopath forms I need to implement one thing which was a bit tricky as it is not the default supported by infopath forms. The requirement is like this: The date fields on form should not allow date plus/minus 5 years from current server date. For this, so many people recommended to implement validation events in c#. But, my form contains 40+ date fields. That is not possible to implement events for each control. But, when I looked into all option there is an option called “Data Validation”. But, there is no direct option available to implement this requirement.
After thought about sometime got wonderful ideas. Below is the implementation finally came up with.
  1. Select the date control and right click.
  2. Select the option “data validation”.
  3. Click on Add to add a new validation.
  4. From the window, the first thing we have to check is “Whether the field is blank or not.” Because once it is not blank then only we go further.
  5. And next thing is, validate the expression. User entered date is plus/minus 5 years from current date.
image
If you observe the first condition I have used is an expression as there is no direct way to validate the date according to my requirement.
Expression we have to use: msxsl:string-compare(., xdDate:AddDays(xdDate:Today(), 1825)) > 0 or msxsl:string-compare(., xdDate:AddDays(xdDate:Today(), -1825)) < 0
And second condition is just the field is not blank then only display “Invalid date” error on screen.
Note: Remember, the expression is very simple that adding/subtracting the 1825 days [5 years] to current date. Depends on your requirement please change the value accordingly.
The last reason why I have used the expression instead of the simple statements is the logical operators. The condition should be validated for this requirement is “((selected date > today + 5 years OR selected date < today – 5years) AND field cannot be blank)”. The brackets are very important, the sequence of executing conditions and logical operators are important. So, to achieve this in infopath forms the only way is implementing expressions. Then only it treats it as the way we want. Enjoy the complex and nice series of posts on infopath and sharepoint coding.

Delete event receiver from a SharePoint list

In my previous post, we saw how we added an event receiver to a list. Now, we will see how to delete the existing event receiver on a list.
private void DeleteEventReceiverFromAList(string siteUrl)
    {
        using (SPSite site = new SPSite(siteUrl))
        {
            using(SPWeb web = site.OpenWeb())
            {
                try
                {
                    SPList list = web.Lists["myList"];
                    if (list != null)
                    {
                        string className = "EventReceiverClass";
                        string asmName = "EventReceiverAssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a865f0ecc234ea51";
                        web.AllowUnsafeUpdates = true;

                        int receivers = list.EventReceivers.Count;
                        bool isAddedReceiverExist = false;
                        bool isUpdatedReceiverExist = false;
                        for (int i = 0; i < receivers; i++)
                        {
                            SPEventReceiverDefinition eventReceiver = list.EventReceivers[i];
                            if (eventReceiver.Class == className && eventReceiver.Type == SPEventReceiverType.ItemAdded)
                            {
                                eventReceiver.Delete();
                                break;
                            }
                        }
                    }
                }
                catch { }
                finally
                {
                    web.AllowUnsafeUpdates = false;
                }
            }
        }
    }
In this code also, there is nothing to explain very detail. Please let me know if you have any questions.

Add event receiver to a SharePoint list

This is very generic and everyone knows how to add an event receiver. But, usually we attach the event receiver on a list template, site etc. This post deals with adding event receiver to a specific list.
private void AddEventReceiverToAList(string siteUrl)
{
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
try
{
SPList list = web.Lists["myList"];
if (list != null)
{
int receivers = list.EventReceivers.Count;
string className = "EventReceiverClass";
string asmName = "EventReceiverAssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a865f0ecc234ea51";
web.AllowUnsafeUpdates = true;
bool isAddedReceiverExist = false;
for (int i = 0; i < receivers; i++)
{
SPEventReceiverDefinition eventReceiver = list.EventReceivers[i];
if (eventReceiver.Class == className && eventReceiver.Type == SPEventReceiverType.ItemAdded)
{
isAddedReceiverExist = true;
break;
}
}
if (!isAddedReceiverExist)
list.EventReceivers.Add(SPEventReceiverType.ItemAdded, asmName, className);
}
}
catch { }
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
}
This is very straight forward code and hope you got it.

Hide content types from a SharePoint library through coding

Please read the post here.

Change content type order in NEW button of a SharePoint library

This is continuation of my previous post. After you read that post you get clear understanding of how we added the content types to a library through coding. But, what if there is a requirement we need this content type order to be shown when I select the NEW button from the list tool bar or hide some content types? Then again we need some sort of code which does that for all existing lists as we cannot change manually if there are plenty of webs in a site.
private void ChangeOrHideContentTypesInALibrary(SPList list)
{
list.ContentTypesEnabled = true;

SPFolder folder = list.RootFolder;

List<SPContentType> orderedContentTypes = new List<SPContentType>();
foreach (SPContentType ct in folder.ContentTypeOrder)
{
if (ct.Name.Contains("ContentType1") || ct.Name.Contains("ContentType2"))
orderedContentTypes.Add(ct);
}

folder.UniqueContentTypeOrder = orderedContentTypes;
folder.Update();
}

If you observe the above code, then the variable orderedContentTypes is what having the content types of which we need to show in the NEW button of the list toolbar. In which order we add the content types to this variable, that order they will be added to the list and shown on the toolbar. And second thing is out of 3 content types available in the above logic we have added only two to the variable. So the third content type will be hidden from the toolbar. And the last two lines in the above function are to update the list with the latest content types order.

Hope this gives you clear idea on how to order and hide content types on a list/library.

Add content type to a SharePoint list or library through code

In one of my SharePoint projects, there is a requirement like a SharePoint site has 140+ sub sites and each web has 2 lists which I need to update. There are 2 content types which are inheriting by each list and now I have to add another through coding. It is very difficult to go through all webs and each list in each web and manually add it. So, thought of writing a simple script which will loop through them and update them. So, here is the code I came up with.
private void AddContentTypeToLibraries(string siteUrl)
{
List<SPContentType> contentTypes = new List<SPContentType>();
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
contentTypes.Add(web.ContentTypes["ContentType1"]);
contentTypes.Add(web.ContentTypes["ContentType2"]);
contentTypes.Add(web.ContentTypes["ContentType3"]);
}
foreach (SPWeb web in site.AllWebs)
{
try
{
web.AllowUnsafeUpdates = true;

foreach (SPList list in web.Lists)
{
if (!list.Title.Equals("MyList", StringComparison.InvariantCultureIgnoreCase))
continue;

for (int i = 0; i < contentTypes.Count; i++)
{
AddContentTypeToList(contentTypes[i], list);
}
}
}
catch { }
finally
{
web.AllowUnsafeUpdates = false;
web.Dispose();
}
}
}
}

void AddContentTypeToList(SPContentType ct, SPList list)
{
if (list.ContentTypes[ct.Name] == null)
{
list.ContentTypes.Add(ct);
list.Update();
}
}
The first method is what we are looping through all webs and go to each list and try to add a content type. And the second method is before adding a content type to a list, we are checking whether the content type is already there or not for that list. So, we are checking for that condition and if find the content type is not already attached to the list then only we are adding to the list.

Hope you understand the logic and how we need to implement it.

Saturday, January 15, 2011

UDCX files in Sharepoint Infopath and dynamic queries

Confused? Can we use dynamic queries in the infopath and UDCX combination? UDCX are meant for not writing any code to get data from database and to show it up the retrieved data on the infopath form. They allow only STATIC queries. Just straight SQL or SPROC names  and parameters to it. But, I got a requirement where I need to pass some dynamic values to the query/SPROC at runtime and gets the data and loads the data on the form. Can I achieve that with same UDCX connections and same architecture?
YES, There is a way to do this. The things to note here are:
  1. Using UDCX connections, we have saved all the connection data, query data and credentials data on a single file in SharePoint list/library.
  2. Query should be correct and executing without any issues [Otherwise infopath cannot download the resulted schema]. For example, you want to get the user by user name then you may created SPROC with name "GetUserByUserName" and in your UDCX file you give the query tag as "<udc:Query>EXEC "dbo.GetUserByUserName" 'DEFAULT'</udc:Query>". We know there is no record in database with the name "DEFAULT". But, this is what we have to give as default query. [This is what we will change in the c# code dynamically.]
  3. Read this connection, query in the infopath c# code.
  4. Change the query information in which way you want in code.
  5. Execute the query.
  6. Reset the UDCX connection information back to original.
  7. It will automatically refresh the control data depends on the latest result set after we executed from the C# logic.
So, I believe you got complete picture of what we are going to do. This is very simple but difficult to get the idea. With this implementation I solved the big problems what I had.
To execute the below code I am assuming there is a UDCX connection file available in a SharePoint library and your infopath form is allowing c# code.
//Get the connection details by connection name 
AdoQueryConnection adoConnection = (AdoQueryConnection)DataConnections["Get_User_Details"];
if (adoConnection != null)
{
string orgCommand = adoConnection.Command; //To read original command 
int index = orgCommand.IndexOf("DEFAULT"); //Find where the keyword "DEFAULT" in the command string 
string SPROC = string.Empty;
if (index > -1)
{
try
{
SPROC = orgCommand.Substring(0, index); //Get only the SPROC name. 
adoConnection.Command = string.Format(SPROC + userName + "'"); //Append user name to the query. 
adoConnection.Execute(); //Execute the final query. This is what the command which contains actual parameter value instead of DEFAULT string. 
}
catch { }
finally
{
adoConnection.Command = orgCommand; //Should not forget to write this. We have to do this. 
}
}
}
Things to note:
  1. The connection name "Get_User_Details" is the connection name from infopath form [Managed Data Connections option].
  2. As we are reading from existing UDCX connection file, we are not hard-coded any of the connection strings or queries.
  3. userName is the string variable which holds the user name which comes at run time. You have to write some logic to get these in your code.
  4. Read the query and replace the dummy parameter values with the original values.
  5. Execute the connection.
  6. In finally block, we are resetting the command back to original.
That's it!!! If you are binding this information to the textbox then you should do one final thing as shown in below figure.
image
The checkbox in above figure "Update this value when the result of formula is recalculated" and applies to only if you use the formula.

We are done. The data now comes from database and passed the parameters to database dynamically, used UDCX connection file and did not hard-coded any of the connection, query information in code. Very clean right?

Hope you understood it well and liked it.

Friday, January 14, 2011

Using Variables in TOP clause in T-SQL

This is what I want to post as I heard so many people are facing this issue. We can use variables in T-SQL queries but, there are requirements that we may select only the top 5 rows or 10 rows or n rows from the result set and use them wherever needed. So, below is the implementation we have to use to achieve that.

  1. One way could be using a variable, which saves the complete t-sql query in it and execute that total query.
  2. Second way will be pass the variable dynamically to TOP clause.

I do not think the first way is feasible. So, I prefer to go to second way and below are the implementation details.

SQL SERVER 2005:

DECLARE @TOP INT;
SET @TOP = 10;
SELECT TOP (@TOP) * FROM [User]

If you observe the variable is what storing the value of how many values we need to select. from the table And the last statement is what the final query which does what we needed. Remember the brackets () around the @TOP variable are what must and should. I also failed to write the query very first time as I forgot to place the brackets around the @TOP variable.

Earlier Versions: SQL SERVER 2000:

DECLARE @TOP INT;
SET @TOP = 5;

SET ROWCOUNT @TOP;
SELECT * FROM [User];
SET ROWCOUNT 0; --DO NOT FORGET TO WRITE THIS. VERY IMPORTANT

There is nothing tricky here. Just setting the ROWCOUNT internal variable to the required value is what works for us. And the very important thing is do not forget to reset the value of ROWCOUNT back to 0. Otherwise it effects the other result sets which comes after these T-SQL statements.

I think you got what I am trying to say here and enjoy the nice tips and posts.

Sunday, January 9, 2011

Visual Studio get pubic key token through external tools

This is very needful post. Most of the times in general development we work on class library projects which outputs DLL at the end. To use them we may need to know the Public Key Token of the DLL and use it wherever needed. We can know the Public key token either through the command prompt SN.EXE or by deploy it to GAC. But, what if you have some tool available and displays the Public key token within Visual Studio?

  1. In Visual Studio, go to Tools, and chose External Tools option as shown.'image
  2. You will be open up with a new window and enter the details as shown below.
    1. Title as “Get Public Key Token”
    2. Command as “C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\sn.exe”. Remember, if you installed Windows SDK then the above location works, otherwise please chose the location where SN.EXE presents.
    3. Arguments as “-Tp "$(TargetPath)"”
    4. And uncheck all checkboxes at bottom and check only the option “Use Output Window”.
  3. At the end the settings should look as shown below.
    image
  4. Now, click OK button and go to tools, you will see there is a new menu item added in the list as shown below.image
  5. So, we are all set to use the tool now. Once you build the class library project, then just click on this “Get Public Key Token” option.  From the output window, you will see the BLOB of the DLL and public key token as shown below.image

That’s it. This is very helping one to me. Hope you also like it. Reference