Monday 13 February 2012

SQL Server Reporting Services (SSRS) - Options for Dynamically Setting Report Data Source

I received a call from one of my colleagues in the Oakton Canberra office today who was working at a Federal Government department. He was using a SharePoint-integrated mode of SSRS.
He wanted deployed reports to point to the correct datasource without manually updating the DataSource of the report each time a new site is provisioned. It was not a feasible option for him to be manually changing the report datasources each time a new site in SharePoint was deployed (based on a particular site template that included Reports) - especially when he moved back off site.

I suggested a couple of ways forward - each with their own advantages and disadvantages:
1) Create a custom SQL Reporting Services Reports Extension that can source data dynamically (as outlined here http://msdn.microsoft.com/en-us/library/microsoft.reportingservices.dataprocessing.aspx and here http://msdn.microsoft.com/en-us/library/bb283184.aspx)
2) Using Expression Based Connection Strings
3) Setting the datasource at Deploy Time instead via Powershell or another scripting technology (or as part of a feature event receiver in SharePoint)

The Deploy-time option was the simplest and cleanest option (though it would have a limitation of breaking if the site locations are moved). A script would need to update the datasources as part of the site migration process. This was deemed to be an acceptable tradeoff.
DDK

SharePoint 2010 - When Hosting Custom WCF Services in SharePoint, SPContext is Null due to MultipleBaseAddressBasicHttpBindingServiceHostFactory Bug

The recommended way to expose a WCF Service through SharePoint 2010 is to NOT manipulate the Web.Config manually/through code to set your WCF bindings.

Instead, it is recommended that you use one of the Service factories provided for you as part of the  Microsoft.SharePoint.Client.Services namespace. These generate the neccessary bindings entries for you.
The 3 types of Binding Service Host Factories are as below:
  • SOAP = MultipleBaseAddressBasicHttpBindingServiceHostFactory (WARNING This has Bugs if the site collection is not at the root)
  • REST = MultipleBaseAddressWebServiceHostFactory
  • Data Service = MultipleBaseAddressDataServiceHostFactory 
There appears to be a bug in MultipleBaseAddressBasicHttpBindingServiceHostFactory that means that the endpoints generated by that factory are only correct if the site is hosted in the root. If your site collection is hosted in say /sites/myportal and you deploy your WCF Service there, then the endpoint will be:
http://servername/mycompanyname/_vti_bin/myportal/CommonService.svc when it should really be
http://servername/mycompanyname/sites/myportal/_vti_bin/CommonService.svc

Consequently if you try to query this with the default bindings then the requests will work but they wont have a valid SPContext even though the HTTP Context is valid and has a valid authenticated user (e.g. when calling through SOAPUI, the WCF Test tool or otherwise (e.g. jQuery).

I wondered why the examples that Microsoft provides work (See the "Revert" WCF Sample here http://msdn.microsoft.com/en-us/library/ff521582.aspx) - and it is because the Microsoft samples actually override the bindings in the client side code and use a constructor overload of WCF classes that accepts the bindings and the endpoints as parameters. This is clearly not an option in say jQuery - so it is not an ideal example at all. Take away the endpoints set in code and calls to SPContext will fail.

I confirmed this behaviour by turning off the loopback exclusion in Fiddler and executing the same calls and saw that indeed the WCF service was trying to connect to an invalid location at the root of my server. This is why the SPContext was null when calling my custom SharePoint WCF Services.

Workarounds:
1) Don't use the SOAP binding factory if you need to deploy your WCF services outside the root. You can manually change/script the web.config changes to add the correct bindings there.
2) Use the REST factory as it doesn't suffer from the same issue.

DDK

Monday 6 February 2012

SharePoint 2010 - People Picker works in Central Admin (for adding Farm Administrators) - but it doesn't recognize them in the Site Collection Administrator People Picker

I had a question from a colleague today as to why users from our main corporate domain were not showing up in the People Picker in SharePoint 2010. This has come up 3 times in the last week, so it warranted a blog entry.

In this situation, the SharePoint 2010 instance was installed in my company's corporate development domain. No 2-way trust relationship exists between the main and the development domains. Users from our main  domain were correctly recognized in Central Admin (when adding Farm administrators) - but were not being recognized in the people pickers in site collections.

Why does this happen? By default, the SharePoint 2010 people picker control (at the site collection level) will not search domains other than the one you used to install SharePoint. The one in Central Administration does work as it has the correct properties set by default.

To correct this situation, you need to run the "peoplepicker-searchadforests" command against the site collections for which you want the people picker control to search additional domains.

A sample of this command can be found below. So all paths are correct (for stsadm), you should run the following command from the "SharePoint 2010 Management Shell"):
stsadm.exe -o setapppassword -password [AppPassword]

stsadm.exe -o setproperty -pn "peoplepicker-searchadforests" -pv "forest:ddkonline.com.au,ddkonline\trusteduserinotherdomain,[password];forest:ddkonline.dev.local,[DevDomainAccount],[DevDomainAccountPassword]" -url https://sitename.com.au

The above command adds 2 forests to be queried when using the people picker - both a development domain (ddkonline.dev.local)  and the main corporate domain (ddkonline.com.au).
DDK