Monday, April 7, 2014

Service Application Proxies runtime reported with locale-dependent TypeName

The SharePoint architecture enables shared usage of service applications across farms. A typical setup is a Shared Services farm that hosts the service applications, and multiple consumer / front-end farms that host the webapplications. In the consumer farm(s), each individual webapplication is associated with the service applications it requires. For instance, webapplication A is associated with Secure Store and Business Connectivity Services, and webapplication B is associated with Secure Store and Secure Token service applications.
In a distributed SharePoint architecture you cannot programmatically access the service applications in the local farm. Instead you must access via the service application proxy that is associated with the webapplication. The retrieval model of this is weakly-typed, you retrieve the desired service application proxy by string-comparision (!) on the proxy TypeName. This weakly-typed usage model is errorprone; you can easily make a typo error that goes unnoticed at compile time. But you will be immediately aware upon the first runtime test of the code.
However, this weakly-typed model incorporates another strange behavior: the reported TypeName is locale dependent! In my local SharePoint image, I tested against an EN-US sitecollection to retrieve the BCS service proxy, filtering on TypeName:
BdcServiceApplicationProxy proxy = webApplication.ServiceApplicationProxyGroup.Proxies.SingleOrDefault( p => p.TypeName == "Business Data Connectivity Service Application Proxy" ) as BdcServiceApplicationProxy;  
With above code, I successfully retrieve the BCS service application proxy.
But the same code running against a webapplication in the integration-test farm does not select the BCS service application proxy. In Central Admin I verified that the webapplication is associated with the BCS service application. So what is the problem here? The cause rather surprised me: the sitecollection in the integration-test environment is provisioned via a Dutch-locale site definition. And as unexpected side-effect the TypeName of the associated service application proxies are now all reported in their Dutch localization name:
Fix for the above code is to make it locale-independent. For BCS this is possible by filtering on TypeName pattern ‘Business Connectivity Service’;
BdcServiceApplicationProxy proxy = webApplication.ServiceApplicationProxyGroup.Proxies.SingleOrDefault( p => p.TypeName.Contains("Business Data Connectivity") ) as BdcServiceApplicationProxy;  
For other service application proxies it might be required to compare the TypeName against the established Resources value:
private static string _BCSApplicationProxyTypeName = null; // Derived from Microsoft.SharePoint.CoreResource static string BCSApplicationProxyTypeName { get { if (String.IsNullOrEmpty(_BCSApplicationProxyTypeName)) { Assembly _aIntl = Assembly.Load("Microsoft.SharePoint.intl, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c"); ResourceManager _BusinessDataRM = new ResourceManager("Microsoft.BusinessData.strings", _aIntl); _BCSApplicationProxyTypeName = _BusinessDataRM.GetString( "ApplicationRegistry_BdcServiceApplicationProxy_TypeName"); } return _BCSApplicationProxyTypeName; } } BdcServiceApplicationProxy proxy = webApplication.ServiceApplicationProxyGroup.Proxies.SingleOrDefault( p => p.TypeName == BCSUtility.BCSApplicationProxyTypeName ) as BdcServiceApplicationProxy;  

No comments:

Post a Comment