A new EntLibLoggingProxyTraceListener class. This trace listener is designed to be used in WCF’s System.ServiceModel trace source, which is configured within the <system.diagnostics> section. This trace listener receives WCF messages logged to this trace source, wraps them in an XmlLogEntry class, and forward them to the Logging Application Block where it can be processed according to the application block configuration.

A new XmlLogEntry class, which derives from LogEntry but includes a new Xml property that preserves the original XML data provided by WCF.

A new XmlTraceListener class, which derives from the .NET XmlWriterTextWriter class. This class can extract XML data from an XmlLogEntry class

In short, attributes and the interceptor mechanisms of WCF are used to integrate EntLib3 features for validation and exception handling, while logging is just another trace listener. You'll need to understand how to configure all three application blocks to make the WCF integration work. I recommend using the EntLibConfig.exe tool to configure the EntLib3 stuff, and the SvcConfigEditor.exe tool to configure WCF tracingwrt logging. The WCF toolbox is included in the .NET3 SDK.

That is all I have managed to find regarding the WCF features of EntLib3. The online MSDN docs contains mostly "new WCF features added to the ____ Application Block" statements and no code samples.

Tuesday, May 08, 2007

Michael Höhne has an good post on how to change the default view of related entities in MSCRM v3, in which he shows how to gather the info necessary for creating the OnLoad javascript. One of the needed elements is the ID of a combobox inside the <iframe id="areaActivityHistoryFrame">. However, getting at the source of frames is not that easy in MSIE as Michael has discovered. The same goes for seeing the actual content of a modified dynamic HTML page.

Viewing the 'history' source is actually rather simple, follow these steps:

Open the view account form

Press CTRL-N on the keyboard to show the browser chrome including the address bar

Select the 'History' folder to view the related activities

Enter this javascript in the address bar and press enter to view the frame source:

As part of the error information I wanted to write to the Windows Application Event Log was the actual request message causing the service operation exception. Thus, I googled for a solution for how to get the XML of the incoming message, so that I could log it along with the stack trace. There are a lot of options for getting at the message in WCF:

Use CreateMessage internally to get at the Message class methods to reproduce the behind-the-scenes stuff of WCF

The problem of the first option is that I only want to get at the message XML when handling exceptions. The second option is not an option (duh!) as I want my operations to be strongly typed using my data contracts. The third option was more like what I wanted, but it seemed to be unneccessary complicated code.The code to get at the message XML from within an operation is quite simple:

This approach does not work for operations with no RequestContext, such as one-way operations.The logging code is added after creating the fault details, this makes it possible to use fault details data in the log. This is how my WCF exception shielding with logging looks like:public static FaultException<T> NewFaultException<T>(Exception ex)where T : FaultContracts.DefaultFaultContract, new(){return NewFaultException<T>(ex, null);}

Note that I now use an inner private method to create the new fault to be thrown and thus must skip two stack frames to get the details of the original method called. The DEBUG section is there to make it simple to see full exception details in NUnit or with Fiddler when debugging the service. This DEBUG code must never make it into release builds, as this is not exactly exception shielding.I have not looked into the WCF app-blocks integration mechanisms added in the april release of EntLib3, that is next on my task list for quieter days. There is not much info about this to be found, but Guy Burstein provides some samples. Btw, you should check out the Patterns and Practices Guidance site, it contains useful stuff and tutorials about EntLib3.

EntLib3 should do as in Castle Windsor and MonoRail and Ruby on Rails; apply "convention over configuration". In EntLib3 config files, you have to add mandatory attributes to identify the default configuration when there are multiple config options. Using "first is default" as in the Windsor 'constructor injection' mechanism would make configuration simpler and less error prone (see VAB issue below). I understand the reasons for having a default-identifier as a separate attribute, but with the new config override and merging mechanisms in EntLib3, there should be less need for compulsory config "switching" attributes.

The convention "first is default" would prevent silly omission errors such as not setting the default rule set in VAB less drastic. As it is now, if you forget to set the VAB default rule set, no validation will be applied, neither will there be any "no rules" exception - and your code will run as if all validations passed, even if there are plenty of broken rules in the input.

While I'm at it, the caching of connection strings and service URLs in the Settings class and the service proxies, is also really silly; you will not be able to detect that some configuration is missing until you move the solution to an isolated staging environment that has no access to the databases/service resources referenced in the development environment. Most test environments are not that isolated from the development environment, and such config errors can go undetected for a long time during testing. This is one area where it would be better if Microsoft could make configuration compulsory.

Wednesday, May 02, 2007

Today I was asked to look at a puzzling problem with TableAdapters at another project at my current customer. The problem they had was that they could not make the TableAdapter read back the generatedSQL Server identity column values when saving a dataset (ta.Update) to insert new rows.

The first thing I checked was the 'Advanced options' of the TableAdapter to see if the 'Refresh the data table' setting was on. It wasn't. "But, we checked that option when we added the adapter". I checked the option and finished the wizard, then checked the setting again. It wasn't set...

I had noticed that details in the wizard summary page was rather short, so I did the wizard steps and inspected the summary again: "Generated SELECT statement" and "Generated INSERT statement", but no "Generated UPDATE statement" and no "Generated DELETE statement". I suspected that this was the cause of the problem, but what could cause the missing SQL commands ? The UpdateCommand and DeleteCommand of the TableAdapter's property window was empty. According to the online help, these statements "will be generated if there is enough information", but no hints to which information is needed. Really helpful.

Looking at the table definition in SQL Server, I then noticed that the table had no defined primary key. I selected the identity column and applied the "Set Primary Key" action and saved the table definition in SQL Server. After reconfiguring the TableAdapter in Visual Studio, the data table now has a defined primary key and - lo and behold - update/delete commands and refresh data on save.