3

I have a requirement for a WCF service I've created to be able to go into "read only" mode. While in this state it will not service requests for calls that would make changes to the database (like creating an order) but will only service read-only requests (like authenticate user). If it receives a request that it will not service, it needs to pass back a friendly message and code (e.g. CODE: 100, DESCRIPTION: "Service is in read only mode and cannot service this request").

I have close to 100 different calls and would like to implement a solution that can be made in one place (like an IDispatchMessageInspector) but I don't see a way to provide a response to any intercepted WCF messages. I have a standard response type that I send back on ALL requests and would like to send that back in these situations as well. The type is named ServiceResponse and has a messages collection. which is a class of Codes and Descriptions.

public class ServiceResponse
{
    public List<Message> Messages {get; set;}
}

public class Message
{
    public string Code {get; set;}
    public string Description {get; set;}
}

Can someone provide me with a direction on how to do this? I have exhausted all of my searching options.

Even if there is just a way in WCF to hand create the SOAP I'm sending back, that's fine as long as I don't have to handle the read-only check / response in every single service call.

Thanks!

omatase
  • 1,551
  • 1
  • 18
  • 42
  • do all of your operations currently return a "ServiceResponse" or is adding this to your interface part of the problem? – dice Feb 24 '12 at 16:37
  • They all currently return a ServiceResponse. The reason I mention it as being a requirement is because the consumer needs to be able to expect the same type of result they already expect. – omatase Feb 24 '12 at 17:27
  • I'm doing something similar in handling requests by using Ninject and its interception plugin. Depending on the size, adding in an IOC container to your existing codebase might not be trivial, but it is an option. – Jonathan S. Feb 24 '12 at 21:14
  • Hmmm, I've been meaning to learn Ninject, but I might not have the bandwidth to do that for this small of a project. – omatase Feb 24 '12 at 22:59
  • IMO - a small project is a great place to start learning Ninject! :) – Jonathan S. Feb 24 '12 at 23:45

2 Answers2

1

I see a couple of choices. 1) add the functionality into the service implementations (100 of them), 2) find an aspect-oriented tool to intercept the service invocation at runtime and execute different code, or 3) intercept all the wcf requests using a custom HTTPHandler. In the handler you can process the request and return a response to the client. Here are some links which might help

http://blogs.msdn.com/b/wenlong/archive/2007/09/18/how-to-use-asmx-extension-to-handle-wcf-requests.aspx

HttpHandler to hook the *.svc requests

Community
  • 1
  • 1
Jennifer Zouak
  • 1,338
  • 6
  • 12
1

You could achieve this with a custom ServiceAuthorizationManager.

The idea would be

  • Add a custom attribute to each class that you want to disable when in read only mode
  • In the custom ServiceAuthorizationManager, check to see if the service is in read only mode. If it is, check for the custom attribute on the method you are trying to call. The method is indicated by the request message action header. The type of the service can be found from the OperationContext.InstanceContext (I think - I can't remember exactly what property)
  • If you find the attribute, throw a fault exception with the right error message.
Mike Goodwin
  • 8,810
  • 2
  • 35
  • 50
  • Can I use this to pass back a response object instead of throwing an exception? I would like to pass back my response object. – omatase Feb 24 '12 at 23:07