Navigation Bar

Monday 13 August 2012

Provisioning custom html/javascripts/css in Content Editor WebPart through code

If you want to provision custom html/javascripts/css in Content Editor webpart through Feature code here it is:

1. Get SPLimitedWebPartManager from SPWeb
2. Create instance of ContentEditorWebPart class
3. Set all properties to that instance
4. Load your contents using CDATA section of xml in XmlDocument
5. Assign XmlElement type to yourwebPartInstance.Content
6. Ask WebPartManager to add that instance to your webpart zone
7. Call SaveChanges of SPLimitedWebPartManger class.

Here is the code

SPLimitedWebPartManager wpManager = web.GetLimitedWebPartManager("YourPageUrl", System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

//create new webpart object ContentEditorWebPart webPartInstance = new ContentEditorWebPart();

//set properties of new webpart object
webPartInstance.ZoneID = "YourWebPartZone";
webPartInstance.Title = "Some Title"; webPartInstance.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal; webPartInstance.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.None;

//Load your contents using CDATA section of xml
XmlDocument doc = new XmlDocument(); doc.LoadXml(@" <![CDATA[ <input onlcick="javascript:sayHello();" type="button" value="Say Hello" /> ]]> ");

//Get the contents as XmlElement
XmlElement contentsElement = (XmlElement)doc.SelectSingleNode("//Contents");

webPartInstance.Content = contentsElement;

//add new webpart object to webparts collection
wpManager.AddWebPart(webPartInstance, "YourWebPartZone", 0); wpManager.SaveChanges(webPartInstance);

//update spWeb object
web.Update();


That's it. Enjoy

Friday 10 August 2012

SharePoint and IoC container

I was given a task to write a timer job that needs to read data from SharePoint list. My colleague has written a timer job for that purpose but the code was reading data directly from the database. So when I tried to use but could not because it was tight couple.

So I decided to modify that code in a plug-able way so that I can choose various data sources to be used with the same timer job for different clients. I implemented OCP (Open Closed Principal).

I have used StructureMap as IoC container to inject my dependency to SharePoint timer job. Because it is easy to use and other reason was it allows us to configure dependencies in a separate configuration file so I don't need to touch OWSTIMER.config file.

I wrote an interface called IRepository, and configured my timer job to pick the implementation from IoC container.
The container was configured with the concrete implementation class. If I want my timer job to read data from csv file, I just need to change the settings/configuration in IoC config.

Below is my project structure:




You can see there is a project called "Masood.SharePoint.ProcessingTimerJob.Interfaces" and it has got IRepository interface.

And Masood.SharePoint.ProcessingTimerJob.Repositories has got actual implementation of IRepository class.

So I can distribute Masood.SharePoint.ProcessingTimerJob.wsp to anyone who wants to use it, they  just need to implement that interface and timer job is read to process from your data source. You can download full source code from Codeplex.

Below is structure map config file that is use to inject actual implementation



Some output




That's it.

Friday 3 August 2012

Developing First App for SharePoint 2013

Today finally I got my vm configured for development of Apps for SharePoint. I had couple of issues while configuring the vm that I want to share with you.

The first challenge was setting up app domain and the other was installing tools for SharePoint apps.

Following are the steps I performed to get my vm configured for apps development:

1) Installed SharePoint 2013 Preview (i.e obvious)
2) Created a site at http://myserver using Developer Site Template template
3) Enable and Restart SharePoint Administration Timer service
4) If you are running it twice or you have already created 'SettingsServiceApp' and 'AppServiceApp' service app then you have to delete it before running this script.
5) Ran the script, I will share that script with you

To install developer tools, you need to install sharepointclientcomponents_x64.msi first and then OfficeToolsForVS2012RCPreview.3f.3f.3fnew.exe

Here is the script that I used in step 4:
start of script
#--------------------------------------------
write-host "starting admin and timer service"
net start spadminv4
net start sptimerv4
write-host "setting apps.mmasood.com app domain..."
Set-SPAppDomain "apps.mmasood.com"
write-host "Ensuring that the SPSubscriptionSettingsService and AppManagementServiceInstance services are running..."
Get-SPServiceInstance | where{$_.GetType().Name -eq "AppManagementServiceInstance" -or $_.GetType().Name -eq "SPSubscriptionSettingsServiceInstance"} | Start-SPServiceInstance
Get-SPServiceInstance | where{$_.GetType().Name -eq "AppManagementServiceInstance" -or $_.GetType().Name -eq "SPSubscriptionSettingsServiceInstance"}
write-host "Checking managed account..."
$account = Get-SPManagedAccount | where {$_.UserName -eq "myserver\Administrator"}
if($account -eq $null){
 write-host "Creating new managed account"
 $account = New-SPManagedAccount
 write-host "Managed account created."
}
else{
 write-host "Managed account already exists."
}

$appPoolSubSvc = Get-SPServiceApplicationPool | where {$_.Name -eq "SettingsServiceAppPool"}
if($appPoolSubSvc -eq $null){
 write-host "Creating SettingsServiceAppPool..."
 $appPoolSubSvc = New-SPServiceApplicationPool -Name SettingsServiceAppPool -Account $account
 write-host "Creating SettingsServiceAppPool...done"
}
else{
 write-host "SettingsServiceAppPool already exists."
}
$appPoolAppSvc = Get-SPServiceApplicationPool | where {$_.Name -eq "AppServiceAppPool" }
if($appPoolAppSvc -eq $null){
 write-host "Creating AppServiceAppPool..."
 $appPoolAppSvc = New-SPServiceApplicationPool -Name AppServiceAppPool -Account $account
 write-host "Creating AppServiceAppPool...done"
}
else{
 write-host "AppServiceAppPool already exists."
}
write-host "creating service apps 'SettingsServiceApp'..."
$appSubSvc = New-SPSubscriptionSettingsServiceApplication –ApplicationPool $appPoolSubSvc –Name SettingsServiceApp –DatabaseName SettingsServiceDB
$proxySubSvc = New-SPSubscriptionSettingsServiceApplicationProxy –ServiceApplication $appSubSvc
write-host "creating service apps 'SettingsServiceApp'...done"
write-host "creating service apps 'AppServiceApp'..."
$appAppSvc = New-SPAppManagementServiceApplication -ApplicationPool $appPoolAppSvc -Name AppServiceApp -DatabaseName AppServiceDB
$proxyAppSvc = New-SPAppManagementServiceApplicationProxy -ServiceApplication $appAppSvc
write-host "creating service apps 'AppServiceApp'...done"
write-host "creating service apps...done"
write-host "setting tenant..."
Set-SPAppSiteSubscriptionName -Name "app" -Confirm:$false
write-host "setting tenant...done"
#----------------------------------------------------------

After that I created a HelloworldApp (the default provided by VS) and successfully deployed.

Updated:
You may need to disable loopback check if you are using hosts file for DNS routing. Please follow steps from http://support.microsoft.com/kb/896861 to disable loopback check.
You can find more details at http://msdn.microsoft.com/en-us/library/fp179923(v=office.15).aspx

That's it.