Wednesday, July 22, 2009

Silverlight and WCF Faults

The WCF FaultContract behaviour is a nice functionality to report functional faults to the invoking client. The WCF service implements this by throwing a FaultException<T> instance. The proxy side catches this, and extracts the functional error.

Well, that's the general idea. With a standard .NET WCF proxy client this works perfectly. However, in Silverlight you ran into some problems. At first, the generic version of FaultException is not available. So you cannot catch and distinguish at WCF client side a FaultException<T>, but must resort to catching generic FaultException. But the real problem is that Silverlight treats all WCF Fault HttpResponse as general CommunicationException iso SOAP FaultResponse. The underlying cause of this is that the WCF service side default sets the HTTP status code to 500 in case of an unhandled exception, even in case of the SOAP FaultException. At Silverlight side (and also Flash) any non-200 HTTP response is generally treated as a communication error. Thereby ignoring/loosing the functional fault information that is responded by the WCF service:
Several posts suggest to prevent this situation by modifying the WCF service side to not return HTTP 500 errorcode for a WCF Fault. This will work if you yourself also have the control over the WCF service. Still, personally I feel this is the wrong approach. The problem is namely at Silverlight side, so you should correct it there. Additional benefit is that you are so also prepared for SOAP faults of external webservices (WCF or other).
My solution would be to implement a custom channel for Silverlight. I thankfully used the example code on this blog for the initial setup. Next I wanted to hook into the proper place in the custom channel to convert 500 HTTP status codes into 200 codes.
However, I've to admit I failed to correct the problem at the Silverlight client side. The reason is that the HTTP transfer is handled up in the stack via inaccessible Silverlight internal clients (System.Net.BrowserHttpRequest, InternalWebRequest, ...), and that all information of the HTTP Response is lost when reaching the context of the channel. Even Reflection cannot give an helping hand here, since the responsestream is closed already when returning to the channel context.
So for now I have to satisfy with letting the own WCF service also return HTTP status code OK (200) when a functional fault is thrown. The bigger drag is the inconsistency in all of this between Silverlight versus standard .NET CLR; in the latter the SOAP response for s:fault is always given priority above the HTTP status code. I think this is as it should be. Moreover given the ongoing discussion what is the correct and standard HTTP status code in case of SOAP FAULT (SOAP and HTTP status codes (200 vs 500 etc), Issue #12: HTTP Status Codes 500 v 200).

Tuesday, July 21, 2009

Tip - solve DateTimeControl's datepickerframe positioning fault for IE8

The SharePoint DateTimeControl uses clientside javascript to runtime position the datepickerframe nearby the imagebutton. When browsing via IE8, the frame is however positioned incorrect, at a visually unrelated position.

I inspected the SharePoint datepicker.js client library from the 12hive\layouts folder to locate the cause of this. At first I had the impression that it was due to the usage of dynamic properties (pixelTop, pixelLeft, pixelRight). As of IE8, DynamicProperties are namely no longer supported to comply with CSS standards.
The real cause however is the usage of the offsetParent method to calculcate the display position for the popped-up datepickerframe. It appears that IE8 returns another value for this method than earlier IE versions for hidden objects: they all return the document.body object as their offsetParent. This causes the pickerdateframe to be displayed at an unexpected place.

A quick fix is to force the browser in IE7 emulation mode in the HTML header:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

A more elegant fix is correctly position the frame by circumventing the offsetParent malfunctioning. I solved the problem by runtime extending the standard 'clickDatePicker' method, and so make sure that for IE8 the datepickerframe.style.display is unequeal 'none' upon requesting it's offsetParent.

Friday, July 17, 2009

Studying Single Sign-On approaches for SAP and Microsoft

In todays typical heterogenous enterprise IT environment, an end-user works with multiple IT products and applications which have varying authentication mechanisms. In such situations a well-desired functionality is to have Single Sign-On (SSO) enabled. The last days I (re)did some research into this area.
The concept of SSO has a direct and narrow relationship with Identity Management. At the area of IM several interesting new developments are lately either done or announced. Sun (almost Oracle nowadays) has its OpenSSO Enterprise flagship, Microsoft recently gave indepth insight into it's forthcoming "Geneva" initiative. Both technologies/products are representatives of the so-called Claims-Based Identity model. And the beauty is that both IM technologies conform to the Security Assertion Markup Language (SAML) federation standard as a basis for interoperability and ease of collaboration. In a joint co-operation, Sun and Microsoft have produced a whitepaper that discusses the interoperability possibilities between the 2 Identity Federation approaches, and gives answers on typical questions. Microsoft and Sun also have some working showcases to demonstrate the interoperability.
For the specific area of SSO in an heterogenous SAP / Microsoft IT landscape, the SAP-Microsoft alliance has an excellent overview whitepaper available: Unleash the Power of Single Sign-On with Microsoft and SAP. A sidemark is that this document appeared in september 2007. Later developments as the mentioned OpenSSO and "Geneva" are therefore not included. Still, to my opinion the whitepaper is not outdated, but simple no longer complete. The description and positioning of the included SSO approaches is still valid and useful. And you can easily complement yourself the 2007-temporal overview of SSO alternatives with the new technologies and products.
Tags: SAP NetWeaver Microsoft SharePoint integration interoperability SSO Identity Management IDM IAM SPNego OpenSSO

Thursday, July 16, 2009

Tip - Silverlight's AsyncCallbackException on invoking WCF service

A Silverlight application deployed to the testserver gave a browser error upon invoking a WCF service. This WCF service is running on the same testserver. The error message is:
Error: Unhandled exception in Silverlight2 application [AsyncCallbackException]
According to the callstack, the error occurred somewhere in the completion of the asynchronous WCF call. This makes the bug analysis somewhat trickier, since you cannot simple use System.Windows.Browser.HtmlPage.Window.Alert then. The call completion namely does not run at the UI thread. However, searching around gave me an idea of the problem cause: I forgot to deploy a clientaccesspolicy.xml file within the folder of the deployed WCF service. Copied it there, and the call from the Silverlight client executes successfully.

Tip - jQuery setExpression and IE8

I ran today into a jQuery exception when testing a WebPart on a system with IE8 installed. In the custom WebPart I apply jQuery a.o. to round buttons and grid-headers. I'm utilizing jquery.corner.js for this. It appears that of IE8, Internet Explorer no longer supports dynamic properties. To prevent the Javascript exception, I made a small modification into 'jquery.corner.js' to check on the IE-version:


if (($.browser.msie) && ($.browser.version < 8.0))
    ds.setExpression('width', 'this.parentNode.offsetWidth');

Wednesday, July 15, 2009

Silverlight app errors when WCF Contract Has Sync Operations

For a WCF service, it does not matter what type of client is invoking it. .NET, Java, PHP or whatever based, as long has the consumer conforms to the W3* standards. For a WCF proxy however, it does matter what type of .NET client is using it to invoke WCF operations. Although a regular CLR-based client supports both synchronous and asynchronous invocations of the WCF service, a Silverlight client only allows asynchronous operations. In a Proof-of-Concept setup in which I have both a regular WebPart (server side operation) and a Silverlight application (client side operation) hosted in a SharePoint portal, I dealt with this by letting the Silverlight strictly use the asynchronous methods. This worked perfectly in my development environment. However, running at the remote test-server, I get an error indication in the browser when trying to invoke from the Silverligth client an asynchronous method on the WCF proxy. Even although the Silverlight code only uses the asynchronous methods, the Silverlight runtime checks at forehand whether the proxy contract also supports synchronous operations, and if so errors out:
Error: Unhandled Error in Silverlight2 Application [ContractHasSyncOperations]
Arguments:IExpensesHandlingAsync
The quick fix in the PoC is to exclude the synchronous methods when compiling the interface/contract for Silverlight client usage, and included in the .xap package. This can be done through a check on the conditional symbol SILVERLIGHT. This way, it is still possible to code-reuse and share a single interface sourcefile, both for non-Silverlight and Silverlight clients.

Tip - Generic robust approach for disposing both normal object as WCF proxy

Situation: a consumer object invokes a provider object to access functionality. The consumer operates against an interface to decouple it at compile-time from the actual implementation(s) of the provider side. The provider is runtime injected via Dependency Injection. After usage, the provider instance may have to be disposed, typical to release native resources (e.g. network or database connections). However, not all provider types need to have the IDisposable interface implemented. To prevent the consumer class from being cluttered with checks on IDisposable being implemented, I delegate this to an utility class in our framework. An example of the consumer usage is now:

In the implementation of the DisposableDecorator class the check is done whether the decorated/encapsulated object implements the IDisposable interface, and if so the Dispose method is propagated on to the encapsulated object. Simple, and it keeps the consumer code clean and focussed. However, when the encapsulated object is actually a WCF proxy, something special needs to be accounted for. The standard application of the using block may then result in an undesired effect. This occurs when an exception is thrown on the channel, putting the proxy in the Faulted state. When next trying to dispose the proxy, the closing of the proxy results in throwing a new CommunicationObjectFaultedException. The latter exception hides the original exception, which has put the proxy in the Faulted state. The solution is to first check whether the encapsulated object is a WCF proxy, and if so if it's communication state is Faulted. If that's the case, then invoke the Abort method on the proxy. Otherwise just maintain the Dispose propagation.