Author: Raihan Iqbal

Programmatically Create and Export SharePoint Views

I had a requirement in one of my projects to create custom views on-demand programmatically in my application. This article provides a guide on how to create SharePoint List Views using the SharePoint Object Model and then export its contents to excel.

Generating the CAML Query

To be frank, I’m not a master in the dark art of writing CAML queries. So, before we go ahead and create the view using code, we will have to create a sample view first to extract the CAML query. For my project, I had to be able to generate separate views dynamically based on a specific column which was Survey ID.

All Items View

survey-list-all

 

Items where Survey ID is 4

survey-list-filtered-view

Now, that we have a sample view which will act as guide/template for future views which will be generated dynamically using code. To extract this views CAML query, we will use the CAML Generator. The tool is pretty straight forward so I will not get into the details of its usage. Open up the view you just created and copy the highlighted part of the schema.

caml-generator

 

Creating and exporting the view

SPSecurity.RunWithElevatedPrivileges(delegate(){
	string query = "4";
	SPList surveyResponseList = SPContext.Current.Web.Lists["Custom List"];
	System.Collections.Specialized.StringCollection viewFields = new System.Collections.Specialized.StringCollection();
	viewFields.Add("Name");
	viewFields.Add("Department");
	SPView view = surveyResponseList.Views.Add("View_Name", viewFields, "query", 100, true, false);

	SPListItemCollection exportListItems = surveyResponseList.GetItems(view);
	DataTable dt = new DataTable();
	dt = exportListItems.GetDataTable();
	Export(dt, view.Title);
});

private void Export(DataTable dt, string viewName)
{
    if (dt.Rows.Count > 0)
    {

	//excel file name
	string filename = String.Format("{0}.xls", viewName);

	DataGrid dgGrid = new DataGrid();
	dgGrid.DataSource = dt;
	dgGrid.DataBind();

	System.IO.StringWriter tw = new System.IO.StringWriter();
	System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
	dgGrid.RenderControl(hw);
	HttpContext.Current.Response.Clear();
	HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", filename));
	HttpContext.Current.Response.ContentType = "application/ms-excel";
	HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
	//render the htmlwriter into the response  
	HttpContext.Current.Response.Write(tw.ToString());
	HttpContext.Current.Response.End();
    }
}

So in my case I just had to replace the value 4 in the query with the new Survey ID value each time a view had to be generated. There are other more “neat” ways to export to excel using third party libraries but I leave that to the reader to explore.

Share

Enable app sideloading in SharePoint Online

To be able to deploy solutions from Visual Studio to SharePoint Online, the SideLoading feature must be enabled on your site.

Install and configure SharePoint Online Management Shell

If you haven’t already done so, you can download SharePoint Online Management Shell and install it. If you are running this a client machine like Windows 8, you might have to change the script execution policy. To be sure, type the following command

Get-ExecutionPolicy -List

If the ExecutionPolicy of CurrentUser scope is shown as Undefined then this means your policy is set as Restricted and you will not be able to execute scripts. To read more about the various types of execution policies, visit http://go.microsoft.com/fwlink/?LinkID=135170. Usually the RemoteSigned policy is good enough so type the following command

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Enabling Siteloading on your site

When you are prompted for your site URL, remember to use HTTPS prefix otherwise you will get a 403 Forbidden error.

#CODE STARTS HERE
$programFiles = [environment]::getfolderpath("programfiles")
add-type -Path $programFiles'\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll'
Write-Host 'Ready to enable Sideloading'
$siteurl = Read-Host 'Site Url'
$username = Read-Host "User Name"
$password = Read-Host -AsSecureString 'Password'

$outfilepath = $siteurl -replace ':', '_' -replace '/', '_'

try
{
[Microsoft.SharePoint.Client.ClientContext]$cc = New-Object Microsoft.SharePoint.Client.ClientContext($siteurl)
[Microsoft.SharePoint.Client.SharePointOnlineCredentials]$spocreds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
$cc.Credentials = $spocreds
$site = $cc.Site;

$sideLoadingGuid = new-object System.Guid "AE3A1339-61F5-4f8f-81A7-ABD2DA956A7D"
$site.Features.Add($sideLoadingGuid, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None);

$cc.ExecuteQuery();

Write-Host -ForegroundColor Green 'SideLoading feature enabled on site' $siteurl
#Activate the Developer Site feature
}
catch
{
Write-Host -ForegroundColor Red 'Error encountered when trying to enable SideLoading feature' $siteurl, ':' $Error[0].ToString();
}

#CODE ENDS HERE

That’s it. You will now be able to deploy your solutions from Visual Studio.

Share

Programmatically Upload Files To SharePoint Document Library

I wanted to use SPMetal generated entity classes to upload files but apparently it is not supported. We have to resort to the SharePoint Object Model to achieve this. Here’s a short snippet:

string targetPath = hrEvent.SiteUrl + "HR Event Banners/" + fuBanner.FileName;

SPFolder bannerLibrary = hrEvent.CurrentWebSite.Folders["HR Event Banners"];

// Prepare to upload
Stream fileStream = fuBanner.PostedFile.InputStream;
byte[] contents = new byte[fileStream.Length];
fileStream.Position = 0;
fileStream.Read(contents, 0, (int)fileStream.Length);
fileStream.Close();

// Upload document
SPFile bannerFile = bannerLibrary.Files.Add(targetPath, contents, true);

// Commit 
bannerLibrary.Update();

Its pretty straight forward and self-explanatory.

Share

Configuring SharePoint 2010 User Profiles using AD LDS in Windows 8

Recently I published a series of three articles that provided an in-depth visual guide on how to configure SharePoint User Profiles in a Windows 8 development environment using Active Directory Lightweight Directory Services.

Part 1: Installing & Configuring AD LDS

Part 2: Configuring a web application using Forms Based Authentication and connecting it to AD LDS

Part 3: Importing user profiles from AD LDS

I hope these articles will help developers out there to get the flavor of Active Directory in their development environment without the extra luggage.

Happy SharePointing!

Share

Configuring SharePoint 2010 User Profiles using AD LDS in Windows 8 – Part 3

In Part 2 of this series we configured a web application with FBA and connected it to AD LDS. This post will be a short one as the steps are very simple and self explanatory.

Navigate to Central Administration –> Application Management –> Manage Service Applications. Select the User Profile Service Application and click on Administrators from the ribbon. Add the sp_ups_svc account and provide it Full Control.

2013-02-23 14_01_08-Manage Service Applications

 

SharePoint provides no native method to import profiles from AD LDS. Instead, the only option out of the box is an LDIF import. Download the SharePoint AD LDS Synchronization Solution and follow the documentation. Once your profile import is complete, you will be able to see your profile from your My Profile page.

2013-02-23 14_26_11-SharePoint User 1

Now you can access these profile properties from your code and even InfoPath.

 

Happy SharePointing!

Share

Configuring SharePoint 2010 User Profiles using AD LDS in Windows 8 – Part 2

In Part 1 of this series we looked at how to install and configure AD LDS on a Windows 8 client. In this post I will be deploying a web application in SharePoint with FBA using AD LDS as the authentication provider.

 

Configuring a SharePoint web application with FBA

First, we have to register the Windows account sp_ups_svc which we created in Part 1 as a managed account and we have to create a new Windows account called sp_farm and register that as well. Fire up Internet Explorer as an administrator and navigate to your Central Administrator; If you skip this step, you will find many features in the Central Administration are disabled.

 

2013-02-23 10_54_45-

 

Navigate to Security –> General Security –> Configure Managed Accounts and add the Windows account.

 

2013-02-23 11_10_06-Managed Accounts

 

Navigate to Security –> General Security –> Configure service accounts and assign this account for the User Profile Synchronization Service.

 

2013-02-23 11_14_53-Service Accounts

 

Now create a web application with the following settings:

2013-02-23 11_20_54-Web Applications Management 2013-02-23 11_22_02-Web Applications Management

Please note that I selected sp_farm as the account for the application pool – this is very important. Once the web application has been created, create a top level site collection and assign the currently logged in Windows account as the primary site collection administrator.

2013-02-23 11_22_41-Web Applications Management

 

Next create another site collection under this site collection using the My Sites template which we will later use to host My Sites and My Profile page.

 

2013-02-23 11_31_59-Create Site Collection

 

Navigate to Application Management –> Manage Service Applications and click on your User Profile Service Application. Under My Site Settings, click on Configure Trusted Host Locations and add the new site collection we just created for My Site.

2013-02-23 11_35_40-Add Trusted Host Location

 

Configure AD LDS with FBA

 

This is the part where we tie up FBA with AD LDS. We just need to make a few modifications to the web.config files of the new web application, central administration and the Security Token Service. Make sure to make a backup before you modify them.

Web application:

<PeoplePickerWildcards>
	<clear />
	<add key="AspNetSqlMembershipProvider" value="%" />
	<add key="TechOneGlobalMember" value="*" />
     </PeoplePickerWildcards>
     
     <membership defaultProvider="i">
	<providers>
		<add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
		<add name="TechOneGlobalMember" type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="RaihanIqbal" port="50000" useSSL="false" userDNAttribute="distinguishedName" userNameAttribute="userPrincipalName" userContainer="CN=SharePoint2010,DC=TechOneGlobal,DC=local" userObjectClass="user" userFilter="(ObjectClass=user)" scope="Subtree" otherRequiredUserAttributes="sn,givenname,cn" />
	</providers>
     </membership>
     <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
	<providers>
		<add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
		<add name="TechOneGlobalRole" type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="RaihanIqbal" port="50000" useSSL="false" groupContainer="CN=SharePoint2010,DC=TechOneGlobal,DC=local" groupNameAttribute="cn" groupNameAlternateSearchAttribute="cn" groupMemberAttribute="member" userNameAttribute="userPrincipalName" dnAttribute="distinguishedName" userFilter="&(objectClass=user)(objectCategory=person)" groupFilter="&(objectCategory=Group)(objectClass=group)" scope="Subtree" />
	</providers>
     </roleManager>

Central Administration:

<PeoplePickerWildcards>
	<clear />
	<add key="AspNetSqlMembershipProvider" value="%" />
	<add key="TechOneGlobalMember" value="*" />
    </PeoplePickerWildcards>
    
    <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
	<providers>
		<add name="TechOneGlobalRole" type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="RaihanIqbal" port="50000" useSSL="false" enableSearchMethods="true" groupContainer="CN=SharePoint2010,DC=TechOneGlobal,DC=local" groupNameAttribute="cn" groupNameAlternateSearchAttribute="cn" groupMemberAttribute="member" userNameAttribute="userPrincipalName" dnAttribute="distinguishedName" scope="Subtree" userFilter="&(objectClass=user)(objectCategory=person)" groupFilter="&(objectCategory=Group)(objectClass=group)" />
	</providers>
    </roleManager>
    <membership>
	<providers>
		<add name="TechOneGlobalMember" type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="RaihanIqbal" port="50000" useSSL="false" enableSearchMethods="true" userDNAttribute="distinguishedName" userNameAttribute="userPrincipalName" userContainer="CN=SharePoint2010,DC=TechOneGlobal,DC=local" userObjectClass="user" userFilter="(ObjectClass=*)" scope="Subtree" otherRequiredUserAttributes="sn,givenname,cn" />
	</providers>
    </membership>

Security Token Service (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken):

<system.web>
	<membership>
		<providers>
			<add name="TechOneGlobalMember"
                  type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
                  server="RaihanIqbal"
                  port="50000"
                  useSSL="false"
                  enableSearchMethods="true" 
                  userDNAttribute="distinguishedName"
                  userNameAttribute="userPrincipalName"
                  userContainer="CN=SharePoint2010,DC=TechOneGlobal,DC=local"
                  userObjectClass="user"
                  userFilter="(ObjectClass=*)"
                  scope="Subtree"
                  otherRequiredUserAttributes="sn,givenname,cn" />
		</providers>
	</membership>
	<roleManager enabled="true">
		<providers>
			<add name="TechOneGlobalRole"
                  type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
                  server="RaihanIqbal"
                  port="50000"
                  useSSL="false"
                  enableSearchMethods="true" 
                  groupContainer="CN=SharePoint2010,DC=TechOneGlobal,DC=local"
                  groupNameAttribute="cn"
                  groupNameAlternateSearchAttribute="cn"
                  groupMemberAttribute="member"
                  userNameAttribute="userPrincipalName"
                  dnAttribute="distinguishedName"
                  userFilter="&(objectClass=user)(objectCategory=person)"
                  groupFilter="&(objectCategory=Group)(objectClass=group)"
                  scope="Subtree" />
		</providers>
	</roleManager>
</system.web>

We are almost there! Restart IIS using the command iisreset and navigate to the web application. You should now be able to login using Forms Authentication with the user account you created in AD LDS.

 

2013-02-23 12_38_43-Sign In

 

In Part 3 we will import the user profiles using the User Profile Service Application.

Share

Configuring SharePoint 2010 User Profiles using AD LDS in Windows 8 – Part 1

If you have a SharePoint 2010 development environment setup in Windows 8 but you don’t have Active Directory you can still configure User Profiles in your SharePoint server. The process is very painstaking so get a cup of coffee, roll up your sleeves and read with full attention!

 

Installing and configuring AD LDS

 

From the Windows features list, turn on Active Directory Lightweight Directory Services.

 

2013-02-22 19_12_36-Windows Features

 

Before we proceed with the installation, we will need to create a couple of Windows accounts as we will be needing them later. Remember to uncheck “User must change password at next logon” and check “Password never expires”.

 

2013-02-22 19_53_34-Computer Management

 

Once the installation is done, navigate to Administrative Tools and run the setup wizard.

 

2013-02-22 19_15_10-Administrative Tools

 

Click Next to begin the installation of AD LDS. We will have to create a unique instance since we do not have an instance created.

 

2013-02-22 19_23_23-Active Directory Lightweight Directory Services Setup Wizard

 

We will have to provide a unique name for the instance and this name cannot contain any spaces.

 

2013-02-22 19_25_47-Active Directory Lightweight Directory Services Setup Wizard

 

The LDAP and SSL port number must be available and not used by any other application. Take a note of these port numbers because we will need them later.

 

2013-02-22 19_29_44-Active Directory Lightweight Directory Services Setup Wizard

 

Create an application directory partition with a proper partition name and then proceed to specify the locations to store the data.

 

2013-02-22 19_35_31-Active Directory Lightweight Directory Services Setup Wizard

 

Instead of using the default Network Service account, we will use one of the user accounts that we created earlier. When you click Next, you are prompted to run the account as a service, click Yes.

 

2013-02-22 19_57_37-Active Directory Lightweight Directory Services Setup Wizard

 

If you are logged in as the administrator, you can keep the default selection as the AD LDS Administrator otherwise you will have to specify an account with administrative privileges.

 

2013-02-22 20_08_36-Active Directory Lightweight Directory Services Setup Wizard

 

The last step is to decide which LDIF files to import. For SharePoint, and for AD LDS replication, we have to import the following files:

 

2013-02-22 20_11_00-Active Directory Lightweight Directory Services Setup Wizard

 

Once the setup is complete, fire the ADSI editor using the command adsiedit.msc. In the left panel, right click on ADSI Edit and select Connect To. Provide a friendly name for the connection and under Connection Point type in the partition name which we created earlier during the installation. Under Computer type in the server name in the format Full_Computer_Name:LDS_Port. If you’re unsure about the full computer name, right click on My Computer to get it.

 

2013-02-22 20_15_17-Configuring SharePoint 2010 User Profiles using AD LDS in Windows 8 – Part 1 - W

 

Click once on the connection name and then the naming container to get the following structure.

 

2013-02-22 20_25_20-ADSI Edit

 

Right click on the container and create a new object of class type container with the value User.

 

2013-02-22 20_30_18-Create Object

 

Under the User container, we will add our SharePoint users. Right click on the User container, and create a new object of class User and enter the full name of the user. In my case its “SharePoint Test User 1”. Right click on the user and select Reset Password.

 

2013-02-22 20_34_45-ADSI Edit

 

Now we need set certain properties for the user which will be later imported into SharePoint User Profile. I suggest the following properties be updated with appropriate values:

  • displayName: SharePoint Test User 1
  • department: Information Technology
  • msDS-UserAccountDisabled: FALSE
  • msDS-UserDontExpirePassword: TRUE
  • msDS-UserPasswordNotRequired: FALSE
  • telephoneNumber: 01710000000
  • title: Software Engineer
  • userPrincipalName: sp1 (Cannot contain spaces)

 

2013-02-22 20_49_44-CN=SharePoint Test User 1 Properties

 

Similarly, you can add other users as needed. Click on the Roles container and edit the member property of the Reader role. Add the second Windows account that we created earlier here. Remember to hit Apply in the properties dialogue.

 

2013-02-22 20_54_20-Multi-valued Distinguished Name With Security Principal Editor

 

Congratulations! Your AD LDS is now ready to be used with SharePoint! In Part 2 of this series we will create a new web application and configure Forms Based Authentication and connect it to AD LDS.

Share

SharePoint Designer: The file is no longer checked out or has been deleted

If you have been working with SharePoint designer for a while you must have come across this error at least once while checking in a file.

blog-error-nolongercheckedout

According to Randy Drisgill this error is caused due to SPD’s cache and clearing the cache resolves the issue. You can manually delete the files from those folders or you can just run this batch (.bat) file.

cd "%APPDATA%\Microsoft\Web Server Extensions\Cache"
del *.web /S /Q "%APPDATA%\Microsoft\Web Server Extensions\Cache"
cd "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache\"
rmdir /S /Q "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache\."
mkdir "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache"
dir "%APPDATA%\Microsoft\Web Server Extensions\Cache"
dir "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache"
pause

Happy SharePointing!

Share

Solving the InfoPath 2010 form script error in Internet Explorer

If you are reading this post, it is more likely you have already read some forum threads and come across various solutions to this problem but like me none of them worked.

 

The Problem

If you have a long running script in your InfoPath 2010 form may be due to a rule, you might receive this error message in pre IE 9 browsers.

 

stop-running-script

 

The Solution

Pin point the control on the form that initiates the rule which in turn runs the javascript. In my case it was a dropdown control. Right click on the dropdown control, select Drop-Down List Box Properties, go to the Browser Forms tab and select Always under Postback Settings.

 

SNAGHTML6b0d6232

 

What this does is it forces the control to cause a postback instead of using Ajax to execute the script on the client side. This solution might not work for everyone but its a good way to force the form to execute all rules on the server side.

 

Happy Programming!

Share