Posts archived in .NET

Edit: This post was linked from Stack Overflow – you might want to check back there for more/better discussion about the topic.

Recently Jeff Attwood wrote about how they are using ELMAH to get more information about the types of errors occurring in Stack Overflow.

Effectively ELMAH is designed as a ‘drop in’ fault capturing system for ASP.NET. It works really well there, and for many situations you can get along just fine without even needing to recompile your application (it does need some editing of the web.config though).

I wanted a way to capture more detail about the faults occurring in our dev and production environments, especially when working with WCF – since a lot of error detail tends to be hidden, or is difficult to reproduce.

Dropping in ELMAH into a WCF application will by default mean you miss the vast majority of errors – WCF swallows the error, and doesn’t let it get back up to ASP.NET.

There’s two ways you can go about fixing this:
Side Note: If you’re not hosting WCF in ASP.NET, then Option 2 may not be directly possible for you without some modification.

#1 – Wrap everything in try/catch blocks (if you didn’t already) and sprinkle this line around everywhere:

Elmah.ErrorSignal.FromCurrentContext().Raise(YourExceptionHere);

#2 Add a HttpHandler, and Decorate your Service(s) with an Error Handling attribute.

I borrowed the ServiceErrorBehaviourAttribute code from somewhere else, and I can’t find the source of it at the moment. Effectively this was so I could manipulate the HTTP Status Codes going back to the client when there was an error. It just so happens that this is a great way of capturing Exceptions and sending them to ELMAH at the same time.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Collections.ObjectModel;
using System.Net;
using System.Web;
using System.IO;
using Elmah;
namespace YourApplication
{
	/// <summary>
	/// Your handler to actually tell ELMAH about the problem.
	/// </summary>
    public class HttpErrorHandler : IErrorHandler
    {
        public bool HandleError(Exception error)
        {
            return false;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            if (error != null ) // Notify ELMAH of the exception.
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(error);
            }
        }
    }
	/// <summary>
	/// So we can decorate Services with the [ServiceErrorBehaviour(typeof(HttpErrorHandler))]
	/// ...and errors reported to ELMAH
	/// </summary>
	public class ServiceErrorBehaviourAttribute : Attribute, IServiceBehavior
    {
        Type errorHandlerType;

        public ServiceErrorBehaviourAttribute(Type errorHandlerType)
        {
            this.errorHandlerType = errorHandlerType;
        }

        public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
        }

        public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection parameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            IErrorHandler errorHandler;
            errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
                channelDispatcher.ErrorHandlers.Add(errorHandler);
            }
        }
    }
}

Once you’ve added that, then it’s just a matter of decorating your Service like so:

    [ServiceContract(Namespace = "http://example.com/api/v1.0/")]
    [ServiceErrorBehaviour(typeof(HttpErrorHandler))]
    public class MyServiceService
    {
      // ...
    }

…and then making sure ELMAH is added as a reference, and adding it’s entries to your web.config.

Then you’ll be getting a whole stack of errors you otherwise may not have seen.

It’s also possible to log exceptions from higher up the chain (eg Databases, Files, etc) by using the line of code from Option 1.

Issues

Whilst ELMAH is great for capturing information about the request, I havn’t yet found any way to capture the original HTTP Request – this would be the ultimate goal for me.

It’s also not particularly easy to capture additional information (such as database records, or objects in cache, etc) without rolling your own copy of ELMAH.

All in all though – for a few minutes work, it’s one additional way to capture errors that your existing code may not be able to.

Yes, ELMAH even captures errors (in most situations) when your WCF services can’t start up (eg your fubar’ed some attributes).

Hope that helps.

NB: Use this code at your own risk, don’t blame me if it brings down your multi-million-dollar-per-hour application and causes you to go bankrupt.

Two methods that I keep finding myself needing are a way to Serialize and Deserialize objects in .NET 3.5.

Either for Unit Testing against a WebService of some kind, or for storing objects in memory to disk in XML for human-readable niceties.

Don’t forget to add in appropriate error handling code as needed.

With .NET 3.5 SP1, these methods will serialize (almost) any object to either XML or JSON, it was based in part off an example given in a long since forgotten forum post.

 

using System.IO;
using System.Runtime.Serialization; // System.Runtime.Serialization.dll (.NET 3.0)
using System.Runtime.Serialization.Json; // System.ServiceModel.Web.dll (.NET 3.5)
using System.Text;
namespace Serialization
{
    public static class Helpers
    {
        /// <summary>
        /// Declare the Serializer Type you want to use. 
        /// </summary>
        public enum SerializerType
        {
            Xml, // Use DataContractSerializer
            Json // Use DataContractJsonSerializer 
        }

        public static T Deserialize<T>(string SerializedString, SerializerType UseSerializer)
        {
            // Get a Stream representation of the string.
            using (Stream s = new MemoryStream(UTF8Encoding.UTF8.GetBytes(SerializedString)))
            {
                T item;
                switch (UseSerializer)
                {
                    case SerializerType.Json:
                        // Declare Serializer with the Type we're dealing with.
                        var serJson = new DataContractJsonSerializer(typeof(T));
                        // Read(Deserialize) with Serializer and cast
                        item = (T)serJson.ReadObject(s);
                        break;
                    case SerializerType.Xml:
                    default:
                        var serXml = new DataContractSerializer(typeof(T));
                        item = (T)serXml.ReadObject(s);
                        break;
                }
                return item;
            }
        }

        public static string Serialize<T>(T ObjectToSerialize, SerializerType UseSerializer)
        {
            using (MemoryStream serialiserStream = new MemoryStream())
            {
                string serialisedString = null;
                switch (UseSerializer)
                {
                    case SerializerType.Json:
                        // init the Serializer with the Type to Serialize
                        DataContractJsonSerializer serJson = new DataContractJsonSerializer(typeof(T));
                        // The serializer fills the Stream with the Object's Serialized Representation. 
                        serJson.WriteObject(serialiserStream, ObjectToSerialize);
                        break;
                    case SerializerType.Xml:
                    default:
                        DataContractSerializer serXml = new DataContractSerializer(typeof(T));
                        serXml.WriteObject(serialiserStream, ObjectToSerialize);
                        break;
                }
                // Rewind the stream to the start so we can now read it. 
                serialiserStream.Position = 0;
                using (StreamReader sr = new StreamReader(serialiserStream))
                {
                    // Use the StreamReader to get the serialized text out
                    serialisedString = sr.ReadToEnd();
                    sr.Close();
                }
                return serialisedString;
            }
        }
    }
}

Hopefully others will find this useful.

 

Updated - A little more generic now – can serialize to either Json or Xml as needed by altering the type param.

With many web 2.0 applications there’s a basic three-tier architecture..   In our case the client is a Flex 3/Caringorm application, the Services are WCF/ASP.NET Web Services, and the Database SQL 2005.

One of the typical approaches to creating Web Services for this type of system is to use a CRUD type pattern. That is: all methods are based around either Creating, Retrieving, Updating, or Deleting records.  In most usually done on a per-table basis, and means that you’re effectively making the Web Services a HTTP enabled SQL client.

For our situation, this wasn’t really appropriate for a number of reasons, including complex relationships between tables, and a need to reduce the amount of network traffic.

Another concern, although relatively minor, is to reduce the amount of work needed by the Flex team to implement the Web Services. 

Ideally, we wanted to be able to share business objects as widely as possible, to reduce the amount of rework needed by everyone involved in implementing the interfaces.

Therefore we chose to go with task, or semantic based methods, and using the objects as needed by the Flex front-end.  The work of validation, and mapping to appropriate tables would be done by the Web services.

An example of this might be that a Document had many properties, such as Media Items (pictures, video, etc), Tags, Authors, etc.  However, within the database there might be a necessity to track Document Versions, What versions are Live, the relationships between Documents, Document Versions and Media Items. 

Because the objects that I needed to send/receive didn’t match the objects that needed to be saved in the database, I needed to write a lot of “left hand/right hand code”: ServiceDocument.Property =   SQLDocument.Property.  Most of this was fairly simple code to write, but tracking the places where this takes place can be grow to become quite a challenge when the solution grows to dozens of tables.

This is an approximate list of what I need to do to add a property to one table:

  • Add the Property to the Service Types
  • Add conversion pieces to transpose the Service Type to/from the LINQ to SQL Object equivalents.
  • Add the column to the Table in the Database Model for LINQ to SQL
  • Add the column to all Stored Procedures in the Database Model which reference this, removing and re-adding them if this means new properties too.  Don’t forget to ensure the return types on the re-added Stored Procedures are set correctly.
  • Add the columns to the actual Stored Procedures, update parameters, etc
  • Add the column to the actual Table

I can only imagine the Version Control conflict chaos that would ensue if you had several people making these changes concurrently.

I highly recommend grouping changes into a per-table basis, because it can take a while to go through all the additional pieces you have referencing the LINQ to SQL and Service Type object equivilents.

Here’s two things that caused me a bit of pain when working with WCF. Hopefully these pointers should help you get back to more productive things.

No Output when returning Serialized / Serialised objects.

I had been working on adding a significant number of methods and properties to a series of classes, and when I went to test the service I got literally no output.

Debug points indicated that all properties were there, and valid – but still WCF wasn’t returning anything. There was no exceptions  being returned to the client.

The best tool for debugging these sorts of solutions is to first of all enable Tracing and MessageLogging.  This is done via the WCF Service Configuration Editor, on the Diagnostics tab. 

Once you’ve done that, and re-run the projects – you can open up Service Trace Viewer.  For me under Visual Studio 2008, this was under Microsoft Windows SDK v6.0A > Tools.

image

This tool then lets you open up the trace log generated in your solution directory, and see all the activity that’s been happening.

debugging-wcf-services

From here, it was just a matter of scrolling down to the activity entry that had the yellow hilighting (indicating a warning), selecting it – then clicking on the Errors.

For me, the first time this happened to me, it was because I had stuffed up the DataMember Name values. It has also occurred for other reasons, such as a property not being populated, when I had specified that it was both required, and also that it could not emit a default value.

Can’t get mex to work

No, this isn’t a misguided racial slur. I was having issues setting up the mexHttpBinding on an ASP.NET AJAX WCF Service.

The solutions all point towards the same thing, that you need to set up an endpoint, and set the contract to IMetaDataExchange, then set the behaviour to have <serviceMetadata />. Except that it just wouldn’t let me add that property to my endpoint behaviour, and whenever I changed it to a service behaviour it would then not allow me  to set the other properties I needed for that.

Well, perhaps I’m particularly slow – but hopefully this pointer will help someone else.

1: Create a NEW service behaviour:

<serviceBehaviors>
  <behavior name="MyServiceBehavior">
    <serviceMetadata 
      httpGetEnabled="true"/>
    <serviceDebug
     includeExceptionDetailInFaults="true"
     />
  </behavior>
</serviceBehaviors>

2: Add a new endpoint to your  existing service

<endpoint 
   address="mex" 
   binding="mexHttpBinding"
   bindingConfiguration=""
   contract="IMetadataExchange" />

3: Add the behaviorConfiguration you added in Step 1 to the Service (NOT the endpoint).

<service 
  behaviorConfiguration="MyServiceBehavior"
  name="MyProject.MyService">

I kept trying to add it to the endpoint, and failing miserably. So much time spent back-and-forth on this!

 

That’s it for this instalment of “WCF is great, but I wish the config was a bit easier to understand”. Stay tuned for more exciting episodes!

Today I spent about half an hour banging my head against this problem:
Whenever I would try and return a business object, I’d simply get no response from my WCF Service. Litterally nothing.

The problem turned out to be that I had accidentally specified the DataMember Name of a property in a sub object twice.

So, I had my broken class set up like:


[DataContract(Name = "MyClass", Namespace = "Example")]
public partial class MyClass
{
[DataMember(Name = "property1")] public int Property1 { get; set; }
[DataMember(Name = "property1")] public string Property2{ get; set; }
}

An instance of this class was used as a property in another object, which was being returned from WCF.

.NET didn’t throw any sort of error unless I tried to return just “MyClass”.

Sure, it was my fault, but if you have a complex data structure, this could get awefully difficult to find without some sort of message from WCF.

Yes, this is part of that ultra nifty WCF JSON .NET 3.5 Flex project at work. :)

(A note to readers: This is all pure geek/coder content – Please skip this if nothing in the subject line makes sense)

I started on a new project at work for a client a bit over a week ago, by virtue of the requirements, we decided to investigate the use of new version of Microsoft’s  .NET Framework, Version 3.5, for all of the server-side services.

Microsoft have been quite strongly pushing the benefits of the new features of .NET 3.5. There’s been a few key features which are particularly interesting, and if all goes according to the marketing hype, should end up saving a huge amount of time and effort, whilst ensuring that we use well known and standardised interfaces.

What features?

Windows Communications Foundation (WCF) is particularly interesting because it promises to let you (mostly) remove the whole ‘how’ and ‘where’ portion of communications between tiers, and let you focus on the ‘what’ and ‘when’.

In essence, WCF should let me state that I want to create (say) a Web Service, that accepts information in format X, and outputs responses in some other format. It doesn’t have to be a Web Service either, it could be a Peer to Peer network speaking in straight binary streams.

For this project the client-functionality is all in Flex, so we need to ensure that the Flex guys can quickly decode all the responses and turn them into Action Script objects. Through a bit of experimenting and application prior experience – Web Services speaking JSON appeared to be the easiest and most light weight method of doing this.

Language Integrated Queries (LINQ) is another particularly interesting technology, particularly because it lets me focus on what I want to do with the data I have, rather than spending time transforming it from the Database tables, rows, and procedures, into .NET objects and methods.

There are a number of implementations of LINQ, which enables you to query a variety of sources – the one that I’m most likely to use is LINQ to SQL (talking to SQL Server). Regardless of what I’m accessing however, the syntax is identical – again, removing the need to modify my code if I need to query an XML file, Oracle or MySQL Database, or even native .NET objects.

You can probably see a common theme here – WCF lets me focus on communication with the outside world without needing to write that interface or conversion functionality, and LINQ lets me access and manipulate data, without needing to write that interface either.

So, it’s all plug and play?

Well, that depends entirely on what you’re doing with your data. If you’ve got something like a CRM application where the client is responsible for managing (most of) the data, then yes it can quite possibly be almost plug and play if you’re going with a “CRUD” interface.

If your data structure is more complex, then you need to determine exactly where the split is. In this specific project, I’m presenting an abstracted view of the data that the client needs, and doing all of the business logic to manage data management in the SQL and Web Services Layer.

So far, the whole WCF and LINQ combination looks good. I’m hoping to post some more detailed posts later on.

Further Reading

I highly recommend Scott Guthrie’s LINQ to SQL series of posts. Start with Part 1: Introduction to LINQ to SQL

These resources have also been of a great help in getting my head around the whole LINQ thing: