Monday, July 21, 2014

Connect SharePoint 2013 to SAP via Gateway for Microsoft

SAP initially developed Gateway for Microsoft [GWM] as ‘Duet Enterprise beyond SharePoint’. Allow Gateway OData service consumption in other Microsoft front-end formats, like Microsoft Office clients (Outlook, Excel, Word, PowerPoint). In essence GWM can also be regarded as a trimmed-down Duet Enterprise 2.0 variant; provides some of the same basic integration capabilities, but not all. Question that arises: can you also utilize GWM to connect SharePoint to SAP?
The answer is a firm Yes you can! Which is logical, as SharePoint itself is a .Net application. You can apply multiple approaches to consume the SAP data through a GWM generated reference proxy into SharePoint:
  1. Connect to the Gateway service proxy from a SharePoint web part context [mind you, Microsoft urges us to step away from this SharePoint server-side model; but it is still possible and supported]
  2. Build a custom BCS Connector to connect to the Gateway service proxy, and use that connector from SharePoint to render the received SAP data via standard External List, Business Data WebParts, or a custom build web part that invokes the BCS Api
  3. Build a SharePoint WCF RESTful service to connect to the Gateway service proxy, and consume that service in a browser-based front-end; using a databinding library like knockout.js, Angular.js. This is an example of SharePoint 2013 App model, and can also be applied in Office 365 / SharePoint Online.

SharePoint version

SharePoint 2010 has been build “ages ago”, and has a hard dependency on .Net framework 3.5. In the current year, the .Net framework has progressed to .Net framework 4.5, and the latest version of SharePoint [2013] has catched up with that. And the same holds for Duet Enterprise 2.0 [which is actually for SharePoint 2013, if you have SharePoint 2010 you need the Duet Enterprise 1.0 version], and also GWM: both are .Net Framework 4.x dependent. As consequence, I have to relax my firm statement a bit: Yes, GWM can be used to connect SAP and SharePoint 2013; but not for the older SharePoint versions (2003/2007/2010).

Simple example for Proofing

To demonstrate, I made up a sample scenario to retrieve SAP CRM data via GWM into SharePoint. I used the demo Gateway services as data source (see article by Martin Bachmann for instruction how to get access to the SAP Gateway demo system), and our own SharePoint 2013 environment as front-end. Further I have Visual Studio 2013, and necessarily also the latest GWM sp3 (versions preceeding sp3 will not install in Visual Studio 2013; but they do install in Visual Studio 2010/2012).
I applied the guidance provided in the GWM Developer Guide, but instead of Windows Forms project, choose SharePoint Visual Web Part template.
Next, you first need to add references to .NET WCF and GWM libraries. The easiest way to achieve that is by utilizing the GWM Visual Studio Add-In. Click on ‘Add SAP Service Reference’:
fill in as Service Url the url to GWdemo service, and press ‘Go’:
In the Service Explorer you can explore and inspect the OData entities that the GWdemo service exposes. Select one, and click 'Ok'. Direct result is the inclusion of multiple GWM assemblies (note that they are still named with the older GWPAM naming) in the Visual Studio project references:
Next, open the visual webpart and put in some code to consume the GWM created proxy reference and display received data. As this is merely a short demo to proof the connectivity, I simple display the SAP CRM BusinessPartners through a plain GridView control:
Build the Visual Studio project, and deploy the SharePoint solution. Then browse to your SharePoint site, create a new page, and add the GWM-build web part. And voila, we have SAP data in SharePoint:
All in all, building this took me less than an hour. Of course it is only a simple retrieval example; and no effort spend whatsoever on achieving a good looking and behaving UI. Also for this simple example I relied on basic authentication. For a trustworthy enterprise context, this is not usable and either OAuth, X.509 or SAML must be applied. But still, the outcome is very promising with respect to the SAP/SharePoint interoperability capability of GWM.

Fixes needed to GWM generated code

Issue 1: Microsoft.Sharp not included in references
Solution: Add the missing assembly to the Visual Studio project reference
Issue 2: Configuration Reader tries to read from windows form based path
Solution: avoid the attempt to read from windows-forms based path
Issue 3: The used GWDemo system gives error
Solution: invoke another method…
Honestly: this is an example of why in every SAP interoperability project also domain knowledge is required --> contactpersoncollection is connected to a business partner key, you cannot invoke this without one.

Does GWM replace Duet Enterprise?

The answer to this is a clear No: Duet Enterprise as framework has more capabilities as GWM: SAP workflow integration, SAP BW reports publication, roles synchronization, user profile synchronization. Also Duet Enterprise has complete self-contained support within for Single Sign-On between SharePoint and SAP, while with GWM you need additional infra to achieve this (e.g. X.509 certificates infra in your landscape).
The better question is however: in what scenario’s would GWM be sufficient? Well, it might be sufficient in scenarios where all you need is the connectivity from SharePoint to SAP for data CRUDQ actions, and you already have Single Sign-On supporting infra in your IT landscape.

Thursday, July 10, 2014

HowTo include inline-CSS in SharePoint 2013 CEWP / Disable spellcheck

During the initial elaboration phase of a SharePoint project, CEWP is a handy SharePoint functionality to quickly setup a visual sketch of the application. This enable you to present the end-users a first impression of how the application is going to look and behave like. In these modern days it is thereby key that the content and functionality is rendered in an attractive and user-appealing manner. This is where CSS comes in.
If you include inline-CSS in a CEWP, you might experience that when you save the SharePoint page the CSS is automatically modified aka corrupted. This effect is caused by SharePoint spell check. To avoid this effect, simple wrap the inline-CSS in a HTML element with class 'NoSpellCheck'.
Example:
<div class="NoSpellCheck"> <style type="text/css"> .PeopleClassification { width:100%; margin-top:1px; font-size:12px; } </style> </div>

HowTo login as different user in SharePoint 2013

A SharePoint platform feature that I use a lot during testing of SharePoint functionalities is simulate another user. However, in SharePoint 2013 the menu item 'Sign in as different user...' is no longer available. A simple trick to still get the ability is navigate the browser to:
http://<siteurl>/_layouts/closeConnection.aspx?loginasanotheruser=true
This trick works in all browsers (IE, Safari, Chrome, FireFox).

Saturday, July 5, 2014

Programmatically set decision of Duet Enterprise task

In our award-winning VIEW (Virtual Integrated Enterprise Workplace) concept we include a generic inbox. In the generic inbox tasks are aggregated from multiple sources: SAP, SharePoint, Oracle, proprietary systems, and so on. The user sees in his/her inbox all outstanding tasks from the diverse task backends. And it is also supported to direct handle the tasks from the generic inbox.
To make the generic inbox real also for Duet Enterprise tasks, it is required to programmatically approve them via the inbox instead of via the standard Duet Enterprise task forms. A good start how to achieve this is article ‘how to create Duet SharePoint webparts’ of Ravi Sharma, in which he uses programmatic Duet Enterprise task approval as an example.
The approach Ravi takes in his setup is to directly update the SAP task by invoke via SharePoint BCS Application Programming Interface (API), explict self the wfUpdate method on the DuetEnterprise WorkflowTask External ContentType. And if the SAP task update is successful, also afterwards alter the SharePoint task that functions as reference or placeholder in SharePoint context to that SAP task.
Although this approach works, it has multiple architectural disadvantages:
  • It bypasses the standard Duet Enterprise workflow capability to update the SAP task via the SharePoint task.
  • It effectively duplicates some of the code and working of the internals of Duet Enterprise workflow update. As architect, I very much dislike any code duplication.
  • Per conceptual task update, 2 tasks must be explicit updated: first the SAP task, next the SharePoint task. This makes the task handling more complex.
  • There is a clear difference in the approval of SharePoint tasks that are created via Duet Enterprise workflow capability, versus regular SharePoint tasks (from any SharePoint workflow, e.g. document approval)
I favor the approach to handle all SharePoint tasks, including the ones that are instantiated as result of Duet Enterprise workflow publication, the same. And be ignorant of what happens in the SharePoint context and possible beyond as result of the task decision update. To achieve this, my SharePoint task update code is a variant on the ‘updateSharePointTask’ method of Ravi. And in this approach, I have no need for the ‘updateSAPTask’ method, as this responsibility is handled by the standard Duet Enterprise workflow capability.
There are 2 caveats when programmatically update Duet Enterprise tasks:
  1. Generic for SharePoint tasks: extendedproperties field ‘ows_taskstatus’ must have been set for the task update to be accepted. However, you cannot set this direct self, but set it indirect by this code snippet:
  2. Specific for Duet Enterprise tasks: In ItemUpdating eventreceiver, multiple checks are done to verify that it is indeed the intention to propagate to SAP. One of these checks is that a string-compare is done on both the set status text as status code. If this string-concattenation is not present in the Duet Enterprise task PossibleOutcomes (you specify this when you in SharePoint ‘Configure a new SAP workflow task type’), then the SharePoint task update succeeds, but the update is silently not propagated onto the connected SAP side. To make sure the programatically set status text is in sync with the configured PossibleOutcomes, I derive the status text based on that same configured PossibleOutcomes:
The complete code example to programmatically set the decision on SharePoint task, which via Duet Enterprise workflow capability then propagate the decision made to the connected SAP task:

Thursday, July 3, 2014

Tip - HowTo restore usage of SharePoint tokens in Visual Studio 2013 for webservice entities

I recently setup a new SharePoint 2013 development + demo environment, and a.o. installed the latest and greatest :-) Visual Studio 2013 edition. In a SharePoint 2013 project, I included some RESTful SharePoint services: WCF services, but also (due reuse) the older ASMX webservice version. Within both service variants I aim to use the convenient Visual Studio support for SharePoint design-time replaceable parameters, aka tokens, that will be replaced by Visual Studio at Solution packaging time with their concrete values.
Example of usage in a WCF service:
Service="TNV.VIEW2.Services.ISAPI.TasksWebProxy.TasksRemoteProxy, $SharePoint.Project.AssemblyFullName$"
Example of usage in an ASMX web service:
<%@ WebService Language="C#" Class="TNV.VIEW2.Dashboard.Services.VIEWProcessService, $SharePoint.Project.AssemblyFullName$" %>
However I noticed that after SharePoint solution deployment, the deployed .svc and .asmx files still contain the token instead of the actual assembly fullname.
The explanation is that Visual Studio applies configuration to determine in which Visual Studio project filetypes it must search for and replace the SharePoint tokens. And in its default configuration, Visual Studio 2013 does not include the .svc and .asmx filetypes (but only for the filetypes: xml, aspx, ascx, webpart, dwp, and bdcm). Akward decision if you ask me: WCF REST services are a valid SharePoint architecture option. And although you must doubt the same for .asmx web services, as Visual Studio users we may assume backwards compatibility on the support we receive from this tool.
The disrupted SharePoint development support can easily be restored by augmenting the Visual Studio configuration. You have 2 options here: do it on development system level, so that it applies at build time for all projects that are packaged on the system. Or include the configuration in the individual Visual Studio project(s).
I favor the last: a) this way, it will be effective on EVERY system that opens the Visual Studio project: on the development systems of your peer project members, and more important: on the (e.g. TFS) build server; and b) as for .asmx it is a valid default assumption that this is obsolete technology, it is justifiable that you must explicit and deliberate restore it for that filetype in only those Visual Studio projects in which you still utilize that older technology.
The steps to also include other than the default filetypes for Token replacement are:
  • Open the .csproj file in an editor (in Visual Studio, Notepad(+), …)
  • Locate the line: <SandboxedSolution>False</SandboxedSolution>
    Note that since the project deployes web services, it cannot be a Sandbox solution
  • And after that line, insert the following line: <TokenReplacementFileExtensions>asmx;svc</TokenReplacementFileExtensions>

Wednesday, July 2, 2014

Beware - malicious ScriptLink usage will hang up your SharePoint 2010/2013

SharePoint's ScriptLink is an useful class to include javascript resources within the HTML rendering. ScriptLink can be used declarative - in a masterpage, Visual WebPart, ... - and programmatically - code behind, webpart. But be aware, in case of incorrect usage, ScriptLink will effectively hang up your SharePoint site, both 2010 and 2013 versions!!.
An example of malicious usage is the following code, to include a javascript resource that is provisioned in (subfolder of) Style Library:
protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); ScriptLink.Register(this.Page, "/Style Library/styles/view-core.js", false); }
The issue here is that ScriptLink assumes all relative links to be within the SharePoint layouts folder. The url in the example is runtime by ScriptLink converted into "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\Style Library\styles\view-core.js".
On itself, this incorrect derived url reference will not directly break your SharePoint site; merely disrupt the expected behavior in browser as the javascript would not be found and loaded. However, ScriptLink also server-side validates the calculated script url as a cache safe url, and in case it cannot be validated will end the complete SharePoint Page rendering, not only that of the erroneous SharePoint artifact. The result in browser is an empty/white page:
<script type="text/javascript"> var gearPage = document.getElementById('GearPage'); if(null != gearPage) { gearPage.parentNode.removeChild(gearPage); document.title = "Error"; } </script>
The correct way to include through ScriptLink a javascript resource administrated in (subfolder of) Style Library, is to use the '~sitecollection' keyword:
protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); ScriptLink.Register( this.Page, "~sitecollection/Style Library/styles/view-core.js", false); }