21 September 2010

WCF Service Errors and Serializing Enums

When consuming a WCF service, you may run into this common exception:

System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. ---> System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result) --- End of inner exception stack trace ---

and the server stack trace looks like this:

at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndRequest(IAsyncResult result)

If you're invoking the WCF service from BizTalk, you will probably get the same exception above wrapped by an outer exception that looks like this:

Microsoft.XLANGs.Core.XlangSoapException: An error occurred while processing the message, refer to the details section for more information

with more stack trace info:

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.Channels.IRequestChannel.EndRequest(IAsyncResult result)
at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.RequestCallback(IAsyncResult result)

at Microsoft.BizTalk.XLANGs.BTXEngine.BTXPortBase.VerifyTransport(Envelope env, Int32 operationId, Context ctx)
at Microsoft.XLANGs.Core.Subscription.Receive(Segment s, Context ctx, Envelope& env, Boolean topOnly)
at Microsoft.XLANGs.Core.PortBase.GetMessageId(Subscription subscription, Segment currentSegment, Context cxt, Envelope& env, CachedObject location)
at ETMS.BizTalk.Orchestrations.ImportAutoWindData.segment2(StopConditions stopOn)
at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

It turns out that the return object had a property which was an enumeration which had trouble serializing.
A colleague of mine introduced me to an excellent tool called WCFStorm. Basically it saved me from knocking up a quick client console app to test the WCF service. All I need to do is pass the service wsdl url to the utility. It discovers the types and properties, lets you populate the fields easily and send the request.
That allowed us to quickly deal with real issue, which turned out to be a property of the return type that was an enum. Having a [DataContract] attribute on the enum type itself is not enough, you will need to decorate each enum value with the[EnumMember] attribute:

using System.Runtime.Serialization;
...

[DataContract(Namespace="...")]
public enum PersonalityTypes
{
[EnumMember(Value="Introvert")]
Introvert,
...

After adding this attribute to each enum value, the WCF service will have no problem serializing the object and sending the results back successfully.

07 September 2010

BizTalk Logging

I've read a few blog posts from respected BizTalk experts and the opinions are mixed over the use of debugging/tracing techniques. Some advocate it, others prefer to use BizTalk's suite of monitoring tools and built-in functionality to view what is going on with messages and routing.

My skin has been saved a few times by using explicit tracing and debugging so I'm going to stick with it. One thing I did notice is that often people will write directly to the event log in expression shapes. While that might seem fine, the logging implementation is tightly coupled to the event log. A more flexible approach is to write to the Trace and Debug subsystems (in System.Diagnostics). Listeners can be configured (and modified) in the BTSNTSvc.exe.config file quite easily. Just ensure the BizTalk service account has permissions to write to the target (eg event log or text file) otherwise nothing will show up.


05 September 2010

GACing Assemblies in Windows 7 / .NET 4.0 / Visual Studio 2010

Before an assembly can be GACed, you need a strong name key. Open up the Visual Studio Command Prompt (2010) in administrator mode and type in:

sn -k c:\temp\MyKey.snk

Run Visual Sutdio 2010 in administrator mode and view the project’s properties. Under the Signing tab, check the Sign the assembly checkbox and choose your newly created key. Under the Build Events tab, add this under Post-build event command line:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe" /i
"$(TargetPath)"

Now when you build your project, the assembly will be automatically GACed. Note that you need to run Visual Studio in administrator mode so that the post-build command will run. You can view your GACed assemblies at C:\Windows\Microsoft.NET\assembly\GAC_MSIL.

03 September 2010

Testing BizTalk Maps that use Flat File Schemas

I was testing a BizTalk map that used a flat file schema with a flat file instance input file and ran into this error:

Error 3 Output validation error: Data at the root level is invalid. Line 1, position 1.

Turns out that the map is treating the input file as an XML file. In the map’s property, ensure the TestMap Input is set to Native.

31 August 2010

BizTalk Schema Build Error

I just ran into a rather strange problem when I tried to rebuild my BizTalk solution. A bunch of these errors popped up:

Error 3 Source file 'C:\Source\MyProject\InputFile_XML.xsd.cs' could not be opened ('Unspecified error ')

Turns out the rebuild wipes out *.xsd.cs files. These files are generated by Visual Studio at build time for each schema file but when they are removed, subsequent rebuilds will fail to regenerate these .xsd.cs files and the compilation fails. This seems to be related to TFS because the solution is to check out all the schema files in the project and build again. The .xsd.cs files will be generated again.

31 July 2008

Event Logging

Here's a quick method to log exceptions to the event log:
private void LogException(Exception exception){
EventLogPermission permissions = new EventLogPermission(EventLogPermissionAccess.Administer, ".");

using (EventLog log = new EventLog("Application")){
permissions.PermitOnly();

if (!EventLog.SourceExists("MySourceName")){
EventLog.CreateEventSource("MySourceName", "Application");
}

log.Source = "MySourceName";
log.WriteEntry(exception.ToString(), EventLogEntryType.Error);
}
}
A couple of things to note:
  • The using statement makes sure the EventLog object is disposed without fail
  • The EventLogPermission permits this callee to create an event source if required and to write to the event log

16 July 2008

Using Static Alias

C# developers will be familiar with this syntax:

this.DoSomething();

whereby DoSomething() is some other method and qualifying it with the
this keyword is good practice. But how about static methods? You'll have to qualify it with the class name:

MyClass.DoSomeStaticThing();

I've never felt right qualifying static methods and properties within the class itself (it is of course required when calling from outside the class) and it gets a bit silly for really long class names, eg:

ServiceModelConfigurationSectionGroupCollection.DoSomeStaticThing();

That might be the worst case scenario class name, but when it is used more than once, the code starts looking littered:

MyVeryLongClassName.TryEnterReadLock(MyVeryLongClassName.Timeout, MyVeryLongClassName.IsReadOperation);

One option is to not qualify at all:

DoSomeStaticThing();

but this just doesn't promote good code clarity, especially when there are numerous static methods and/or properties that seem to float around with no qualifiers at all.

What I've started doing is using an alias called "This" which is just a shortcut to my class:

namespace MyNamespace{
using This = MyNamespace.MyVeryLongClassName;
public class MyVeryLongClassName{ ...

Now I can succinctly qualify static methods and properties:

This.DoSomeStaticThing();


There is an analogous distinction (albeit subtle) between
this (instance) and This (static) which is consistent with .NET naming conventions between class types (Pascal case) and instances (Camel case).