The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

Archive for the 'WCF' Category

Hey Microsoft, Our Databases Aren’t Services!

Posted by Davy Brion on 17th January 2010

Something that frequently bothers me is when people/companies create services that are basically thin layers on top of their database.  The service contracts expose the typical CRUD operations for each table, and add some additional methods for specific queries etc.  These kind of services will sometimes pretend to contain a bit of ‘business logic’ but they are essentially just a remote interface into your database with maybe a bit of extra security on top of it.  They effectively turn your database into a remote service.  Now if you’re anything like me, you’re probably thinking “why on earth would people do that?”

There are probably a few answers to that question, but one reason that can’t really be disputed is that a lot of the tooling that Microsoft offers to developers simply encourage this kind of stuff.  Let’s go over a little example.

I wanted to see what some of Microsoft’s recommended tools would create for me if i wanted to create a Silverlight application which uses a database.  Obviously, a Silverlight application can’t use a database directly so the application will need to communicate with a service.  The service obviously does have access to the database.  RIA Services is a solution that Microsoft seems to be pushing a lot for this specific scenario so i figured i’d give this a shot.

I created a RIA Services Class Library project in my solution and tried to add a ‘Domain Service Class’ (as the RIA Services templates call it) to the project.  If you already have a DataContext or an ObjectContext defined within the same assembly, you can immediately select the database tables that you want to expose.   So i canceled the dialog and quickly added an ADO.NET Entity Data Model to the solution for which i selected my Chinook database.  I tried to create a ‘Domain Service Class’ again and got the following window:

create_service

Well, now that sure is easy isn’t it? I can immediately select all my ‘Entities’ and i can even check whether i want to be able to edit them through the service, and apparently i can also generate associated classes for metadata (which would be useful for validation according to the tooltip).  I checked the Album table, and left the ‘Enable editing’ option unchecked.  This created a service with the following code:

    // Implements application logic using the ChinookEntities context.

    // TODO: Add your application logic to these methods or in additional methods.

    // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access

    // Also consider adding roles to restrict access as appropriate.

    // [RequiresAuthentication]

    [EnableClientAccess()]

    public class AlbumService : LinqToEntitiesDomainService<ChinookEntities>

    {

 

        // TODO: Consider

        // 1. Adding parameters to this method and constraining returned results, and/or

        // 2. Adding query methods taking different parameters.

        public IQueryable<Album> GetAlbum()

        {

            return this.ObjectContext.Album;

        }

    }

 

I don’t know about you, but i love those TODO statements.  After all, you really do might want to consider constraining the resultset that could be returned by the GetAlbum method.   Who knows, perhaps you have certain use cases where you don’t want all of the ‘entities’ in the Album table to be returned by your ‘domain service’.  Hopefully, this service will be used by developers who are smart enough to realize that they should modify this method, instead of using client-side LINQ statements to filter the returned Album ‘entities’ as i’m sure we’ve all seen in too many Microsoft demo’s already.

It gets better if you recreate the service and check the ‘Enable editing’ option.  Now you’re ‘domain service’ will also contain the following methods:

        public void InsertAlbum(Album album)

        {

            this.ObjectContext.AddToAlbum(album);

        }

 

        public void UpdateAlbum(Album currentAlbum)

        {

            if ((currentAlbum.EntityState == EntityState.Detached))

            {

                this.ObjectContext.AttachAsModified(currentAlbum, this.ChangeSet.GetOriginal(currentAlbum));

            }

        }

 

        public void DeleteAlbum(Album album)

        {

            if ((album.EntityState == EntityState.Detached))

            {

                this.ObjectContext.Attach(album);

            }

            this.ObjectContext.DeleteObject(album);

        }

 

Man, this sure is easy, isn’t it? I now have a service that offers me full CRUD access to the Album table in my database.  If i wanted to, i could now start implementing a screen in my Silverlight application which allows my users to list the albums, edit them, delete them, create new ones, etc… and i wouldn’t even have to change anything in my ‘service layer’.   The problem is that too many developers actually will do exactly that.   After all, why should they doubt any code that was generated by a tool which comes from Microsoft?  If the tool can generate this, then certainly some people actually want you to use it like this, no?  If not, why would it even generate code like this?

I’m sure this kind of stuff gets a lot of ooh’s and aah’s during the product demo’s at Microsoft events, but other than that, what good does this really bring?  Is this really the way you want people to develop their services?  Do you really want developers to pretty much expose the database as-is to remote clients?  And those TODO statements simply won’t cut it, you know that all too well.  I simply don’t think there’s any good reason to generate code like this because a lot of people will simply take it as is and use it like that directly from their client code.  Oh sure, most of them will hook up the authentication but i’m willing to bet that very few people will actually put real business logic in there.  Why would they?  The message that a lot of people will get from the resulting code is that a service is merely a way to provide CRUD for your database tables.  What’s business logic to these people?  Right, the stuff they’ll implement in their presentation layer because this service doesn’t really encourage people to consider implementing it there.

The only benefit that i can see from using RIA services is that you don’t really have to deal with your service contracts, and your operation contracts or any of that stuff.   No, we won’t be doing any of that.  We simply use a [EnableClientAccess] attribute and we’re done!  I don’t really consider that a benefit, though i can certainly understand why people would not want to deal with the pain of classic WCF services.  RIA Services is simply a solution to the wrong problem.

I haven’t looked at ADO.NET Data Services (which will be renamed to WCF Data Services in .NET 4.0) yet, but i suppose it’ll be more of the same: something that makes it incredibly easy to create services directly on top of your database data.

Seriously though: who on earth actually wants that?

I have no doubt that there are some people out there that are using RIA Services in a responsible manner and are sticking by responsible architectural guidelines.  I also have no doubt that those people are ignoring most of the tooling that is offered by Microsoft around it.  So really, why not get rid of this kind of tooling, and spend the effort that normally goes into those tools (or anything else which encourages bad practices for that matter) on providing actual guidance to the developers of your platform?  The last thing we need are more developers who think that this is ‘ok’, or projects that have been delivered based on this kind of ‘architecture’, or customers that are turned off by .NET projects because “they all have maintenance problems”. 

Posted in Architecture, Opinions, WCF | 25 Comments »

Integrated Security With Silverlight And WCF

Posted by Davy Brion on 3rd November 2009

I lost some time yesterday trying to get a Silverlight client to use Integrated Security with a WCF service so i figured i’d post the steps necessary to make it work here.

First of all, you need to make sure that your IIS installation has support for Windows Authentication. Go to Add/Remove Programs (appwiz.cpl), click on Turn Windows Features on or off, select Internet Information Services – World Wide Web Services – Security and make sure that Windows Authentication is checked.

Next, you need to make sure that the virtual directory where you’re hosting the WCF service has Windows Authentication enabled. Open Internet Information Services Manager (inetmgr), select the virtual directory where the WCF service is hosted, click on the Authentication icon and enable Windows Authentication.

After that, you need to add the following to the binding configuration of the service endpoint (in the host, obviously):

          <security mode="TransportCredentialOnly">

            <transport clientCredentialType="Windows" />

          </security>

I only got it working with basicHttpBinding, so unfortunately i can no longer use the customBinding to use binary XML…

In your Silverlight project, open the ServiceReferences.ClientConfig file and add the following to the binding configuration:

          <security mode="TransportCredentialOnly" />

After that, you should be able to do this in your WCF service:

            WindowsIdentity myuser = ServiceSecurityContext.Current.WindowsIdentity;

And that should return the Windows user of the user running the Silverlight client.

For the record: this is with Silverlight 3… i have no idea if it’ll work with Silverlight 2

Posted in Silverlight, WCF | 1 Comment »

Why I Dislike Classic Or Typical WCF Usage

Posted by Davy Brion on 21st July 2009

If you’ve ever used or read about WCF, you’ve most likely seen classic or typical WCF usage. With that i mean service contracts with various operations on them, service implementations that either contain logic or always delegate to other classes, generated client proxies that need to be kept in synch every time you add an operation to a service and a lot of repetitive XML in your configuration files. In some cases (usually for very specific services with limited functionality) there is nothing wrong with that. But for a service layer that sits on top of your business layer so it can be used by the front end of your application (be it ASP.NET, Silverlight, a WPF client or whatever) i find typical WCF usage to be far from ideal.

My biggest issue with typical WCF usage is that of service contract design. It’s very hard to get this ‘right’ and most people simply don’t. First of all, you need to decide between fine-grained and coarse-grained operations. Fine-grained operations typically lead to chatty communication between the client and the service, which could seriously impact performance and scalability. Then again, fine-grained operations do offer a lot of flexibility when it comes to reusing functionality in various parts in the client. Coarse-grained operations typically don’t have the same negative effect on performance, but they can easily introduce implicit coupling between your service and the client which can get pretty annoying when you need to deal with a new kind of client, like a Silverlight application for instance (which tends to have different service usage patterns than typical ASP.NET applications). It can also lead to duplication when parts of functionality offered by a coarse-grained operation are needed somewhere else.

Even if you do get the granularity of your operations right, you have to figure out where to put them. Are you going to create a service for each kind of functional subdomain (billing, invoicing, registrations, etc…), for each entity that is ‘known’ to the client (there are many people who do this, unfortunately) or on a per-feature basis (story or use case driven)? Every possible variation you can think of is already being used today, and they almost always come with a lot of disadvantages. Get this part wrong and you can end up with clients that might need 2 or more service proxies just to show some related data on a screen (or worse, to complete a business transaction). Whether you get it right or wrong, odds are high that you’ll have spent quite a bit of time defining your service contracts. Time that might have been better off being spent on other parts.

The second thing that bothers me a lot about typical WCF usage is the quality of the code in service implementations. In the worst cases, these classes actually contain true business logic to implement the service operations. That’s not just breaking the Single Responsibility Principle, it’s more like assaulting it. Whether they contain actual business logic or merely delegate to other classes, these service implementations will need to talk to instances of classes or components that they depend on sooner or later. My question is, where do these instances come from? Do you manually resolve them through your IOC container? Do you have them injected in your service instance (if creation of the service instance is controlled by an IOC container, that is)? What if the granularity of the service contract forces the service implementation to depend on components that might not be used together in all operations?

And then there’s the thorny issue of cross cutting concerns within service implementations. How many times have you seen the same old tired logging and exception handling code repeated in every service operation? How about transaction handling, auditing, authorization or resource management? True, you can plug into WCF’s extensibility model (if you’re willing to look for it…) or use AOP tricks to minimize that kind of code duplication but that in turn limits your possibilities when you want to add just a little bit of custom code to some of the cross cutting concern’s logic when needed. In most cases, service implementations simply contain a lot of smelly code, the large majority of which is essentially a form of waste.

That’s already an important list of problems when designing and implementing typical WCF services. But what about using typical WCF services? This is somewhat problematic as well, IMHO. First of all, you’ll need a proxy to access the service. You can either develop these proxies yourself, or you can generate them through visual studio, svcutil, or custom tools that you (or others) developed. Whatever way you choose to use, you can’t escape the fact that you constantly have to keep those proxy implementations in synch with their respective service contract. Every single time one of the developers adds an operation to a service (which is pretty often once there are a few people working on a large project), you’re going to have to do something to make sure you can access that operation through your proxy. It’s usually not a lot of work, but it does kinda disrupt your coding flow. Over and over again. It can also be a pain in the ass when it comes to source control conflicts.

Then there’s the actual matter of using the proxy instances. Can you implement your story or use case with just one client proxy type? Great! Do you reuse the channel when making multiple service calls? You do? Great! Do you make sure you handle faulted channels properly? And if you need multiple client proxy types (depending on your service contract granularity), are you aware of the fact that you are using multiple WCF channels (and yes, they are expensive) which are often kept open longer than they should be if you’re not careful? Are you generally careful about chatty communication? Obviously, that last one depends on the contract of the service and not really the implementation of the client proxy. There are quite a lot of things you need to keep in mind when using these proxies.

My final thing on the list of ‘dislikes’ is the configuration that is required to use these services. For every service you expose you’ll need to add some XML to your configuration file. Twice even (server _and_ client)! Most of this XML configuration is extremely tedious and very repetitive which just invites minor mistakes to be made. Those minor mistakes could lead to a lot of debugging/problem solving time though.

I’ve been subjected to each and every one of the issues i’ve mentioned in projects that made typical use of WCF (or classic ASP.NET Web Services for that matter). This type of service layer implementation is, IMHO, hurtful for productivity, detrimental to code quality and i don’t really like the implicit trade-off between reusability and performance/scalability (depending on the granularity of your operations).

About a year ago, i really wanted to figure out a way to implement services which would enable me to keep fine-grained operations on my service layer without having to pay the performance/scalability penalty for that. As some of you already know, that led to the whole WCF call batching thing (more info here and here) which i later on called the Request/Response Service Layer. Some people liked the approach, but i don’t think anyone else actually uses it. At least, i’ve never heard of anyone using it in a real project.

Well obviously, we’ve been using this at work for about a year now and while i won’t claim that it’s perfect (hint: nothing is), it has worked very well for us in several projects. More specifically, this approach has offered us the following benefits, which heavily contrast all of the downsides of typical WCF usage that i listed above:

  • Since we only have one service contract with one service operation, we don’t need to spend time thinking about how to design and implement our service contracts and our operations. After all, every operation that the service layer must support is a specific request type that can be added, together with its requesthandler.
  • We can keep our operations as fine-grained as we want (which increases reusability and overall flexibility), without having to pay the cost for chatty network communication by batching multiple requests per roundtrip as much as possible in a transparent manner.
  • The actual implementation of our service is very minimal. It’s just a small class which resolves the appropriate requesthandler through the IOC container, based on the type of the incoming request. It then delegates to the requesthandler by passing the request to it, and it returns the response to the client. We can simply add ‘operations’ by adding request types and requesthandlers to our assemblies… everything gets registered automatically when the application starts up
  • We avoid repetitive code for cross cutting concerns by putting it in a base requesthandler class that the other ones inherit from. That kind of code now only occurs once, and we can plug in custom code at any point of the execution by simply using the Template Method pattern.
  • The implementation of our requesthandlers doesn’t contain any code that doesn’t have to be there. Each requesthandler simply implements the Handle method to handle the incoming request, and can do as it pleases to fulfill the request. All dependencies are injected automatically by the IOC container. It’s usually nothing more than using the dependencies to execute the necessary business logic and then returning a response-derived object.
  • Since we only have one service, we only need one client proxy which never needs to be updated (technically, we have 2: one which is entirely asynch and mostly used in Silverlight clients, and one which is strictly synchronous and is mostly used by ASP.NET applications and Windows Services or command line tools.
  • This single client proxy implementation can make sure that underlying WCF resources are utilized as efficiently as possible and cleaned up properly throughout the client application(s).
  • The client proxy is easy to stub during unit tests which increases the testability of our client side code.
  • Very little configuration. We only have to configure one client-side endpoint, and one server-side endpoint. That’s it.
  • All of this is very easy to put in some kind of reusable library. Our applications simply reference the library, inherit from the base requesthandler types, make sure everything is registered properly upon application startup, add a couple of lines of XML and we can start the development of our service layer without any friction.

The only downside to this approach that i can think of after using it for a year, is interoperability with other platforms. I haven’t used it in that situation yet, and while i do think it can be made to work i don’t think it’ll be easy nor pretty.

Now, just to be clear: this entire post was not a rant against WCF. I actually do like WCF as a technology, it’s just the typical usage patterns of WCF that i really dislike. I love the fact that WCF is very extensible, configurable and flexible, but i merely consider it as a communication technology. Nothing more, nothing less.

Posted in Opinions, WCF | 19 Comments »

Calculating The Size Of SOAP Messages

Posted by Davy Brion on 11th March 2009

I recently needed something to log the size of incoming and outgoing SOAP messages, and my first implementation of calculating the size looked like this:

        private static double GetMessageLengthInKB(Message message)

        {

            return Math.Round(Encoding.UTF8.GetBytes(message.ToString()).Length / 1024d, 2);

        }

There is a big problem with this. Well, at least one that i know of, possibly more. The ToString() method on the Message class returns the nicely formatted content of the message. Including all whitespace. This obviously increases the reported size of the SOAP message by a significant number, even though it’s not sent over the wire with all that whitespace. A better way to calculate the size is like this:

        private static double GetMessageLengthInKB(Message message)

        {

            var writerSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = false };

 

            using (var memoryStream = new MemoryStream())

            using (var writer = XmlDictionaryWriter.Create(memoryStream, writerSettings))

            {

                message.WriteMessage(writer);

                writer.Flush();

                return Math.Round(memoryStream.Position / 1024d, 2);

            }

        }

One thing to keep in mind is that you need to be careful with writing the contents of a SOAP message. If you write the content of a SOAP message without copying it first, you’ll run into other problems further along the WCF pipeline. So the MessageInspector now looks like this:

    public class MessageInspector : IDispatchMessageInspector

    {

        private readonly ILog logger = LogManager.GetLogger(typeof(MessageInspector));

 

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)

        {

            if (logger.IsInfoEnabled)

            {

                var bufferedCopy = request.CreateBufferedCopy(int.MaxValue);

 

                var sizeLog = string.Format("request message size: ~{0} KB", GetMessageLengthInKB(bufferedCopy.CreateMessage()));

                logger.Info(sizeLog);

 

                request = bufferedCopy.CreateMessage();

            }

 

            return null;

        }

 

        public void BeforeSendReply(ref Message reply, object correlationState)

        {

            if (logger.IsInfoEnabled)

            {

                var bufferedCopy = reply.CreateBufferedCopy(int.MaxValue);

 

                var sizeLog = string.Format("response message size: ~{0} KB", GetMessageLengthInKB(bufferedCopy.CreateMessage()));

                logger.Info(sizeLog);

 

                reply = bufferedCopy.CreateMessage();

            }

        }

 

        private static double GetMessageLengthInKB(Message message)

        {

            var writerSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = false };

 

            using (var memoryStream = new MemoryStream())

            using (var writer = XmlDictionaryWriter.Create(memoryStream, writerSettings))

            {

                message.WriteMessage(writer);

                writer.Flush();

                return Math.Round(memoryStream.Position / 1024d, 2);

            }

        }

    }

As you can see, you’re better off creating a buffered copy of a message, and then creating a new message out of that copy before doing anything with it.

Posted in WCF | 1 Comment »

I Love Easy Extensibility

Posted by Davy Brion on 10th March 2009

Welcome to episode 245 in my Love/Hate relationship with WCF. Today i had to add some technical logging to some infrastructure code. More specifically, we wanted to log the size of incoming and outgoing SOAP messages. If you’re using something like the Request/Response service layer you do want to keep an eye on the size of those SOAP messages to make sure nobody is going overboard with the WCF batching.

I obviously already had my service, so i just needed something that i could plug in at the appropriate moment to record the size of incoming and outgoing SOAP messages. Turns out this was extremely easy to do. First, you need to write an inspector for the messages (which has to implement WCF’s IDispatchMessageInspector interface):

    public class MessageInspector : IDispatchMessageInspector

    {

        private readonly ILog logger = LogManager.GetLogger(typeof(MessageInspector));

 

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)

        {

            if (logger.IsInfoEnabled)

            {

                logger.Info(string.Format("request message size: ~{0} KB", GetMessageLengthInKB(request)));

            }

 

            return null;

        }

 

        public void BeforeSendReply(ref Message reply, object correlationState)

        {

            if (logger.IsInfoEnabled)

            {

                logger.Info(string.Format("response message size: ~{0} KB", GetMessageLengthInKB(reply)));

            }

        }

 

        private static double GetMessageLengthInKB(Message message)

        {

            return Math.Round(Encoding.UTF8.GetBytes(message.ToString()).Length / 1024d, 2);

        }

    }

After that, you need a way to inject the MessageInspector into the behavior of your service. So you need to define your own behavior first:

    public class AddMessageInspectorBehaviorAttribute : Attribute, IServiceBehavior

    {

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

 

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,

            Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {}

 

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

        {

            foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)

            {

                foreach (var endpoint in dispatcher.Endpoints)

                {

                    endpoint.DispatchRuntime.MessageInspectors.Add(new MessageInspector());

                }

            }

        }

    }

And then you apply that to your service:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

    [AddMessageInspectorBehavior]

    public class WcfRequestProcessor : IRequestProcessor

    {

        // the service stuff...

    }

And that was it! I was afraid i was going to have to figure out which one of WCF’s 12.4 billion configuration options would make this possible but this actually didn’t require any configuration at all. Which is very nice, IMO.

On a side note, if anyone knows of a better way to calculate the real size of a SOAP message, please let me know :)

Posted in WCF | 2 Comments »

Abstracting Request State

Posted by Davy Brion on 17th January 2009

Sometimes it’s useful to be able to store an object somewhere so you can easily access it for the duration of the current request, instead of having to pass it around with every method call that you make. That request could be an ASP.NET request, or a request in your WCF service layer. I used to resort to storing these objects in ThreadStatic fields (which is basically a static reference for each thread), thinking that it would be safe because only one thread handles a complete request. Last week i read that some requests can be paused and resumed by another thread. If you’re using ThreadStatic fields, this could lead so major issues which would be a royal pain in the ass to debug. In order to prevent this possible problem, i wanted to have a safe way to keep state that should be available for the duration of a single request.

If your code executes in an ASP.NET environment, you can safely use the HttpContext.Current.Items dictionary for this. If your code executes in a WCF environment, you can store these things in the OperationContext. I don’t want my code to be tightly coupled to either ASP.NET or WCF, so i wanted some kind of abstraction. This is the approach that i came up with.

First, we have the IRequestState interface:

    public interface IRequestState

    {

        T Get<T>(string key);

        void Store(string key, object something);

    }

This just offers a way to store objects and retrieve them. That’s pretty much al we need, right?

Then we have the ASP.NET implementation:

    public class AspNetRequestState : IRequestState

    {

        public T Get<T>(string key)

        {

            return (T)HttpContext.Current.Items[key];

        }

 

        public void Store(string key, object something)

        {

            HttpContext.Current.Items[key] = something;

        }

    }

Very simple stuff… the AspNetRequestState implementation simply uses the HttpContext.Current.Items dictionary underneith to store and retrieve the objects.

For WCF, it is slightly more complicated. Every WCF call is an operation and it has a context as well, which is provided through the OperationContext class. The OperationContext class doesn’t have an Items dictionary like HttpContext does, but it does have a way to add extensions to the context. We can use this extensions mechanism to store state which should be kept around for the duration of the current WCF operation. First, we need to define our Extension:

    public class MyExtension : IExtension<OperationContext>

    {

        public MyExtension()

        {

            State = new Dictionary<string, object>();

        }

 

        public IDictionary<string, object> State { get; private set; }

 

        // we don't really need implementations for these methods in this case

        public void Attach(OperationContext owner) { }

        public void Detach(OperationContext owner) { }

    }

The IExtension interface that we must implement defines the Attach and Detach methods but we don’t really need them for what we’re trying to do. This extension simply initializes a Dictionary instance and exposes it with a public getter. Now we can easily create our WcfRequestState implementation:

    public class WcfRequestState : IRequestState

    {

        private static IDictionary<string, object> State

        {

            get

            {

                var extension = OperationContext.Current.Extensions.Find<StateExtension>();

 

                if (extension == null)

                {

                    extension = new StateExtension();

                    OperationContext.Current.Extensions.Add(extension);

                }

 

                return extension.State;

            }

        }

 

        public T Get<T>(string key)

        {

            if (State.ContainsKey(key))

            {

                return (T)State[key];

            }

 

            return default(T);

        }

 

        public void Store(string key, object something)

        {

            State[key] = something;

        }

    }

Pretty simple as well, and pretty similar to the AspNetRequestState implementation. The AspNetRequestState implementation is able to simply use the HttpContext.Current.Items dictionary, which we can’t use here. So when we want to access the ‘State’ dictionary in this implementation, we look it up in the current OperationContext’s Extensions collection. If it’s not there yet, we add a new instance of our MyExtension class to the OperationContext’s Extensions collection.

Now we can use this wherever we need to store something for the duration of the current request, regardless of whether we’re executing in an ASP.NET or WCF context. Just configure your IoC container to create instances of AspNetRequestState whenever an IRequestState instance is needed in your WebApplication, or configure it to return WcfRequestState instances in your WCF service. The code that needs to store some request state will no longer have to resort to using ThreadStatic fields, and it doesn’t need to know about it’s runtime environment either. It merely needs an instance of IRequestState.

Posted in ASP.NET, WCF | 13 Comments »

Do Not .Dispose In The PreRender Event

Posted by Davy Brion on 1st October 2008

We had this weird issue with a project at work… sometimes, the web application would just completely hang for a couple of minutes. A coworker started looking at the problem, and he quickly found out that in some cases, calls to the WCF service would just completely block. Even when debugging the web application and the WCF service on our development machines, so it wasn’t an issue of throughput or concurrency or anything like that on the server.

We were clueless as to why the calls were actually blocking. We had a few scenarios that would usually (but not always) trigger the bug, but it also occurred in other situations, seemingly at random. So my coworker spent many hours trying to find out why it was happening. After a lot of debugging on his part, he found out that sometimes our WCF proxies weren’t being disposed, which left Channels to the service open which caused new proxies to block whenever the number of allowed concurrent channels was reached. My first reaction was “huh, how could that be? i’m disposing of them in the page’s PreRender event…”.

First of all, i’m far from an ASP.NET guru, so those of you who do know a lot about it probably already understand the problem. I figured that the PreRender event would always occur, and that it would be the best place to dispose the WCF proxy. That turned out to be a two-for-one brain fart on my part. First of all, the PreRender event is obviously not fired when you do a Server.Redirect or Server.Transfer, so whenever we navigated to another page, we did not dispose our WCF proxy. Secondly, Page inherits IDisposable, which i completely missed apparently. So, had i simply overridden the Dispose method and dispose the proxy in there before calling base.Dispose() and then we would’ve never had this problem to begin with.

Lesson of the day: no matter how careful you try to be, you can still fuck up pretty bad sometimes :)

Update: i actually used the PreRenderComplete event instead of the PreRender event… still, a bad place to dispose of disposable objects ;)

Posted in ASP.NET, Memory Management, WCF | 1 Comment »

WCF And Large Amounts Of Data

Posted by Davy Brion on 14th September 2008

If you’re using my Request/Response service layer, or any other WCF service that might require sending large amounts of data over the wire, you quickly bump into some limits that WCF enforces by default. Among the billions of configuration options for WCF, there are luckily some options that allow you to easily send large amounts of data from a service to a client.

I typically use the following options:

For my binding configuration i usually set the maxReceivedMessageSize, maxStringContentLength and the maxArrayLength properties to their maximum values:

    <bindings>

      <netTcpBinding>

        <binding name="MyTcpBinding" maxReceivedMessageSize="2147483647" receiveTimeout="00:30" sendTimeout="00:30">

          <readerQuotas maxStringContentLength="8192" maxArrayLength="20971520" />

        </binding>

      </netTcpBinding>

    </bindings>

This example shows these settings for the netTcpBinding… i’ve also used them with the wsHttpBinding. Not sure how well it works with other bindings though.

I also set the maxItemsInObjectGraph setting of the DataContractSerializer to make sure i don’t hit the default limit if i have to send a large object graph over the wire:

    <behaviors>

      <serviceBehaviors>

        <behavior name="MyBehavior">

          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>

          <serviceMetadata />

        </behavior>

      </serviceBehaviors>

    </behaviors>

You have to apply these settings both server and client side to get it working properly and you need to refer to these settings in your service and endpoint settings:

      <service name="Brion.Library.ServerSide.WCF.WcfRequestProcessor" behaviorConfiguration="MyBehavior">

        <host>

          <baseAddresses>

            <add baseAddress="net.tcp://localhost/RequestProcessor"/>

          </baseAddresses>

        </host>

 

        <endpoint contract="Brion.Library.Common.WCF.IWcfRequestProcessor" binding="netTcpBinding"

              bindingConfiguration="MyTcpBinding" />

 

      </service>

    <client>

      <endpoint address="net.tcp://localhost/RequestProcessor" binding="netTcpBinding"

            name="IRequestProcessor" bindingConfiguration="MyTcpBinding" behaviorConfiguration="MyBehavior"

            contract="Brion.Library.Common.WCF.IWcfRequestProcessor" />

    </client>

Now, i don’t recommend sending such large amounts of data through WCF services… but in the case of using my Request/Response service layer, the amount of data you’re sending over the wire pretty much depends on which kind of requests (and how many of them) you’re batching so i think it’s better to make sure that at least the configuration allows for it. So obviously, it’s best to keep an eye on the size of your messages to make sure you’re not doing anything crazy. Being able to send your entire database over the wire doesn’t mean it’s a good idea to actually do so ;)

Posted in WCF | 1 Comment »

Easing The Pain Of WCF Debugging

Posted by Davy Brion on 20th August 2008

WCF is pretty cool, i guess. It’s quite powerful, and it’s so configurable it even has options to control the speed of the CPU fans of the users of your service. Ok, maybe you can’t really configure that, but with approximately 12.4 billion WCF configuration settings available to you, who knows? But the biggest problem i have with WCF is the painful debugging experience when something goes wrong.

Ever got a client-side exception that looked like this?

[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +73
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +110

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +183
System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +54
System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +32
System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count, TimeSpan timeout) +32
System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count) +53
System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) +37
System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +131
System.Net.Security.NegotiateStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +28
System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +223

[IOException: The read operation failed, see inner exception.]
System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +333
System.Net.Security.NegotiateStream.Read(Byte[] buffer, Int32 offset, Int32 count) +79
System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +72

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +7594687
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +275

Rather messy, no? Does it give you any clue as to what could possibly be wrong? Nope. This particular client-side exception occurs when something goes wrong server-side, at some point after you’ve already returned your return value in your service implementation. Of course, you don’t actually see it happening server-side. So i tried setting IncludeExceptionDetailInFaults to true on the service implementation… didn’t make a difference. I set IncludeExceptionDetailInFaults to true on the service host but that didn’t work either. Sigh.

After some Live Searching (i was actually googling, but let’s make Microsoft think at least someone outside of Redmond uses Live Search) i discovered that you can enable WCF tracing. Bingo! Why didn’t Juval Lowy’s book mention this? It’s supposed to be the WCF Bible…. Oh well, thanks to Google, i mean Live Search, we now know how to enable WCF’s tracing:

  <system.diagnostics>

    <trace autoflush="true" />

    <sources>

      <source name="System.ServiceModel"

              switchValue="Information, ActivityTracing"

              propagateActivity="true">

        <listeners>

          <add name="wcfTraceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="WcfTrace.svclog" />

        </listeners>

      </source>

    </sources>

  </system.diagnostics>

You can also use the Service Configuration Editor tool which is available in the Windows SDK, but spare yourself the pain of that tool and just copy/paste this xml in your config file.

Now run the service again, and do whatever it was that triggered the weird client-side exception. After the exception occurred, open the WcfTrace.svclog file with either an editor (it’s not very readable though) or with the Microsoft Service Trace Viewer tool (which is not too bad actually).

When i opened my trace output, i immediately saw a red item in the Activity list… so i clicked on it, and i finally saw the problem:

There was an error while trying to serialize parameter http://tempuri.org/:ProcessReadOnlyRequestsResult. The InnerException message was ‘Maximum number of items that can be serialized or deserialized in an object graph is ‘65536′. Change the object graph or increase the MaxItemsInObjectGraph quota. ‘. Please see InnerException for more details.

There we go… the client-side exception was terribly useless, but this is the best kind of exception: not only is it clear about what’s wrong, it even gives you the solution to the problem. Btw, if you get that client-side exception, it doesn’t mean that your problem will be the same as the one listed here. It could literally be anything if it doesn’t happen inside of your service implementation. I’ve seen the same client-side exception when one type somewhere in the object graph didn’t have a DataContract attribute, for instance.

So anyways, do yourself a favor and enable WCF tracing while you’re still in development… it could save you a lot of time.

Oh and bonus points go to whoever points out which of WCF’s many configuration settings actually make the real exception appear in the client-side stacktrace :)

Posted in WCF | 10 Comments »

Batching++

Posted by Davy Brion on 30th July 2008

The usual example:

                dispatcher.Add(new GetProductCategoriesRequest(), new GetSuppliersRequest());

                View.ProductCategories = dispatcher.Get<GetProductCategoriesResponse>().ProductCategories;

                View.Suppliers = dispatcher.Get<GetSuppliersResponse>().Suppliers;

                View.DataBind();

Thanks to my request/response service layer, those are two service requests that will be performed in one service call. On the server side, these two requests are dealt with separately. But they merely retrieve data from the database. Wouldn’t it be cool if those 2 queries were performed in one database roundtrip instead of two? Wouldn’t it be cool if we could batch the queries that will be performed by read-only service requests into a single database roundtrip? It sure as hell would be. Implementing this was one of those irresistible challenges you just can’t say no to, so from now on we can actually do this. I’m not gonna get into the actual implementation of how I got it working (check the code in the library for that if you’re interested), but i will show you how you can do this in your application.

First of all, if you have requests that merely return data, inherit from ReadOnlyRequest instead of the usual Request type:

    [Serializable]

    public class GetProductCategoriesRequest : ReadOnlyRequest {}

 

    [Serializable]

    public class GetSuppliersRequest : ReadOnlyRequest {}

The handlers for these requests should inherit from the ReadOnlyRequestHandler base class instead of the usual RequestHandler class. Btw, my ReadOnlyRequestHandler class inherits from my UoWRequestHandler class, which requires a IUnitOfWork instance to be passed to the constructor. So we need to put an IUnitOfWork parameter into the constructor along with our other dependencies if we want the IOC container (or the request processor) to pass us a valid IUnitOfWork instance.

    public class GetProductCategoriesHandler : ReadOnlyRequestHandler<GetProductCategoriesRequest>

    {

        private readonly IRepository<ProductCategory> repository;

 

        public GetProductCategoriesHandler(IUnitOfWork unitOfWork, IRepository<ProductCategory> repository)

            : base(unitOfWork)

        {

            this.repository = repository;

        }

 

        public override void AddQueries(IQueryBatcher queryBatcher, GetProductCategoriesRequest request)

        {

            queryBatcher.AddCriteria("categories", repository.CriteriaForAll());

        }

 

        public override Response GetResults(IQueryBatcher queryBatcher, GetProductCategoriesRequest request)

        {

            var categories = queryBatcher.GetEnumerableResult<ProductCategory>("categories");

 

            return new GetProductCategoriesResponse { ProductCategories = categories.ToDTOs() };

        }

    }

The ReadOnlyRequestHandler class defines two abstract methods: the AddQueries and GetResults method. Both are passed an instance of IQueryBatcher and the actual request object so you can use the request parameters if there are any.

In the AddQueries method, you simply add the queries this request needs to perform to the batcher (with a string key value of course for later retrieval), and in the GetResults method you can get the results (with the key values used in AddQueries) back from the batcher and you can construct your Response object. The GetResults method will be called after each ReadOnlyRequestHandler for the current request batch has added the queries to be performed to the batcher. The queries are then all executed, and each ReadOnlyRequestHandler will have its GetResults method called so each handler can construct the proper response.

And that’s it basically… The calling code doesn’t even change.

Now there are obviously some limitations. If you mix ReadOnlyRequests with other Requests, then each ReadOnlyRequest will be handled as if it were a regular Request and they will each get their very own IQueryBatcher instance. I don’t think there’s any strategy to automagically determine which ReadOnlyRequests can be batched together while still correctly executing the other Requests since those requests might influence the results of ReadOnlyRequests that are present further in the batch.

Anyways, you can find an updated version of the library here. Check it out, it’s some pretty slick shit, if i do say so myself ;)

Note: i only added this stuff today, so the previous build (080729) doesn’t have this yet, in case you only downloaded that today, and the stats show that some of you actually did download it ;)

Posted in NHibernate, Performance, Software Development, WCF | 2 Comments »