WCF

Resolving WCF object graph cycles and CustomMessageInspector

December 16, 2010 WCF 5 comments

Today I played a little bit with WCF services. Currently in system we have extremely cumbersome and large object graphs.
Long story short we have Order data contract that always has Customer property in it. From other side Customer did not have reference to Order, so today I added property IList<Order> Orders to my customer and to test just called wcftestclient. Of course if you are not new to WCF, you know that it showed me that I probably have cyclic dependencies.

Reason is that if you have cyclic dependencies XmlSerializer anyway tries to serialize whole graph till it reaches stackoverflow.
[EDITED because of complains]  Actual error is something like “SerializationException: Customer contains cycles and cannot be serialized if reference tracking is disabled…

To avoid this problem you would need to mark you data contract with [DataContract(IsReference = true)]. So I did:

 [ServiceContract]
 public interface IDataContractCycles
 {
  [OperationContract]
  CustomerModel GetCustomer();
 }

 [DataContract(IsReference = true)]
 public class CustomerModel
 {
  [DataMember]
  public string Name { get; set; }

  [DataMember]
  public IList Orders { get; set; }
 }

 [DataContract(IsReference = true)]
 public class OrderModel
 {
  [DataMember]
  public string Name { get; set; }

  [DataMember]
  public CustomerModel Customer { get; set; }
 }

And to test I again fired up wcftestclient and it crashed!!! wtf? I had to commit some code to keep guys working so I commented Customer property of my Order. I thought that it would crash in our client the same way.

image

And now meaning of this story: TRUST NO ONE!

I cannot give up that easily, so I wrote ever simple wcf server and client, then added custom message inspector to see actual payload.

For this you would need something like below:

 class Program
 {
  static void Main(string[] args)
  {
   var client = new DataContractCyclesClient();

   client.Endpoint.Behaviors.Add(new CustomEndpointBehavior());

   client.Open();

   CustomerModel customerModel = client.GetCustomer();
  }
 }

 internal class CustomEndpointBehavior : IEndpointBehavior
 {
  public void Validate(ServiceEndpoint endpoint){}
  public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){}
  public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher){}

  public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  {
   clientRuntime.MessageInspectors.Add(new CustomMessageInspector());
  }
 }

 internal class CustomMessageInspector : IClientMessageInspector
 {
  public object BeforeSendRequest(ref Message request, IClientChannel channel)
  {
   return null;
  }

  public void AfterReceiveReply(ref Message reply, object correlationState)
  {
   reply.ToString(); // THIS IS ACTUAL PAYLOAD OF THE MESSAGE
  }
 }

I got correct object graph and payload with reference Id-s. See message below. It has Customer marked with z:Ref=”i1″ and then the same Id is used in two orders. This is cool stuff.

<s:Body u:Id=”_0″>

  <GetCustomerResponse xmlns=”http://tempuri.org/”>

    <GetCustomerResult z:Id=”i1″ xmlns:a=”http://schemas.datacontract.org/2004/07/WcfLearningCycles” xmlns:i=”http://www.w3.org/2001/XMLSchema-instance” xmlns:z=”http://schemas.microsoft.com/2003/10/Serialization/”>

      <a:Name>Andriy Buday</a:Name>

      <a:Orders>

        <a:OrderModel z:Id=”i2″>

          <a:Customer z:Ref=”i1″ />

          <a:Name>Kindle</a:Name>

        </a:OrderModel>

        <a:OrderModel z:Id=”i3″>

          <a:Customer z:Ref=”i1″ />

          <a:Name>HTC Cable</a:Name>

        </a:OrderModel>

      </a:Orders>

    </GetCustomerResult>

  </GetCustomerResponse>

</s:Body>

Liked it? Yes? No?


5 comments


Exam 73-503: TS: Windows Communication Foundation – PASSED

November 27, 2010 Certification, Success, WCF 3 comments

I recent posts I mentioned that I read training kit for ms WCF exam. Of course I did this for some reason. I had this exam scheduled for yesterday as well as presentation on WCF for Thursday, which went extremely well. All that was scheduled because I decided to throw myself out of comfort zone. I now can ensure you that this approach indeed works. So, if you want to achieve something don’t hesitate – just go ahead and put some deadlines for yourself, and make them visible to others so this will be controlling your activity.

How did I prepare?

So I’m completely sure that positive result of this exam was guaranteed by my experience working with WCF. But anyway I read training kit, which brought many interesting aspects and some kind of hints for the exam. Third learning source (after experience and training kit) was MSDN and writing simple applications by my own. I do not like to use examples from training kit, also I found few mistakes in kit. Thursday’s presentation on WCF helped me as well, I strengthen my knowledge in transactions and instancing. Just before exam I tried MeasureUp demo test and got 6 out 6 – never got this at MeasureUp for other exams.

Passing Exam

Exam has 45 questions for 120 min. And I liked answering for them, since I faced dozen of questions related to what I do in my everyday work.

I PASSED EXAM with score 918, this means that I answered correctly on 41 questions. Woo hoo!

You can see my transcript using this information:
https://mcp.microsoft.com/authenticate/validatemcp.aspx
Transcript ID: 904316
Access Code: andriybuday


3 comments


DevMeeting: WCF–Advanced-1

November 25, 2010 DevMeeting, Presentation, PublicTalks, WCF 2 comments

 

Today I performed meeting on WCF. It was continuation of this thread of meetings.

Couple of interesting facts about this presentation:

1) I started preparing at 3AM and continued doing this till actual presentation at 1 PM. (Yeah I of course responded to some of e-mails at work and did some other stuff, but anyway most time spent on preparation)

2) Also I want to my English teacher to forgive my absence on today’s English Lesson. Additional 1,5 hour really helped me. Guys, could you please ensure her that presentation cost all the money?

3) I took to much stuff to talk during 1 hour. Initially I prepared following list:

  • Basics overview
  • Sessions and Instances
  • Transactional Services
  • Concurrency
  • Security
  • Instrumentation
  • Most often troubles you might face using WCF

So I crossed some items, but it turned about that we had time only for two first items in bold.

Regardless of that many people, I’m sure, liked it very much.

4) I did a lot of coding during presentation, I hope guys liked this. Right?

5) I was forgetting about zooming and colors on projector. My bad.

6) There was not enough sit places for guys, many of them simply stand near the wall. Sorry for that. I hope managers will resolve this issue soon. He-he.

7) I kept them all interested in further presentation, since Security was not mentioned at all :-P

8) Main Links from this presentation:

9) You can go and download my presentation (I removed transactions to have something to show next time) using this link.

10) So mainly I talked on Sessions and Instances.

11) But, then I also talked on items listed below:

  • Throttling
  • Quotas
    • MaxReceivedMessageSize
    • ReaderQuotas
  • Demarcating
  • Instance Deactivation

12) Thank you!

Guys, I will appreciate your comments/suggestions/thoughts here!


2 comments


WCF: Sessions and Instances

November 25, 2010 WCF No comments

Sessions and Instances

Per Call*

On each request to service (each time we use service method) new instance of Service implementation will be generated. Often this is not suitable for us when we want some to keep track of actions (transactions) or when we access some critical resources.

image_thumb[11]

Per Session*

Is default Session mode. (BTW book on preparation to 70-503 has mistake mentioning that PerCall is default). In this case client knows that Service provides sessions. We can also highlight requirement of using sessions by marking contract with SessionMode.Required. Session is kept with identifier assigned to you proxy class, that you use at client. 

We also have possibility to share same instance of service by passing additional identifier in message header that goes from Client. For that we would need to implement IInstanceContextProvider.

image_thumb[12]

Singleton

Is more rarely used Session mode, but it might be useful when we access one super-critical resource. Plus to that that one plus in using this session mode – possibility to create instance of service even before service host has been created.

image_thumb[13]

* Pictures, but not text below, were taken from training kit book for ms exam 70-503: Link


No comments


WCF: Instrumentation: Parameter Inspector

November 22, 2010 WCF 4 comments

Let’s take a look how we use one of the instruments of the WCF, called Parameter Inspector.
Here below we see how message request goes between Client and Service.
image
Let’s now imagine that we have some kind of calculator on service side, that has method string Execute(int a, int b, string operation). Client should be very careful in passing parameters to the service, because service is developed by some other team, and after you pass incorrect parameters it fails.
It turns out that with WCF services we are not required to implement such logic before calling method. It can be applied to your request when passing to service. Either just before passing it to channel stack at client or at dispatcher after it came from network on server.
On the picture below we see more closely what is at proxy layer, and 3 points where you can inject your logic.
image So moving forward I’m going to implement Parameter Inspection for my calculator example.
Here is implementation of my calc service. Please take a look that for this naive example, I’m killing process when operation is not available. Of course in standard situation with WCF we would probably throw fault exception and catch it on client side. But for now, lets assume that there is some super logic on service and we cannot change calculator code – it stops working is we pass wrong operation string.
    public class CalculatorService : ICalculatorService
    {
        public int Execute(int a, int b, string operation)
        {
            Console.WriteLine("Received request: ({0}{2}{1}=?)", a, b, operation);

            int result = -1;
            switch (operation)
            {
                case "+":
                    result = a + b;
                    break;
                case "-":
                    result = a - b;
                    break;
                case "*":
                    result = a * b;
                    break;
                case "/":
                    result = a / b;
                    break;
                default:
                    Console.WriteLine("Our calc executed hara-kiri.");
                    Process.GetCurrentProcess().Kill();
                    break;
            }
            return result;
        }
    }
Client is the most standard, that you can imagine, it asks calculator for answer by passing parameters entered in console in while loop.
                        var res = calculatorServiceClient.Execute(a, b, op);
                        Console.WriteLine(res);
Now let see how calc crashes on ‘@’ operation:
image We want to execute parameters verification before calling method on server, and if parameters do not satisfy us, we abort calling calculator. For this I simply surround call to the service in my client in following way:
                    try
                    {
                        var res = calculatorServiceClient.Execute(a, b, op);
                        Console.WriteLine(res);
                    }
                    catch (ArgumentException exception)
                    {
                        Console.WriteLine(exception.Message);
                    }
So how do we get ArgumentException on client? We add custom behavior to the client endpoint.
            using (var calculatorServiceClient = new CalculatorServiceClient("WS2007HttpBinding_ICalculatorService"))
            {
                calculatorServiceClient.Endpoint.Behaviors.Add(new CustomEndpointBehavior());

                calculatorServiceClient.Open();
                
                // ... 
So custom behavior allows us add operation, message and parameter inspectors. In my example I will only add parameter inspector. See below:
    public class CustomEndpointBehavior : IEndpointBehavior
    {
        public void Validate(ServiceEndpoint endpoint)
        {
            return;
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            return;
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            return;
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            foreach (var clientOperation in clientRuntime.Operations)
            {
                clientOperation.ParameterInspectors.Add(new OpParameterInspector());
            }
        }
    }

    public class OpParameterInspector : IParameterInspector
    {
        public object BeforeCall(string operationName, object[] inputs)
        {
            switch (operationName)
            {
                case "Execute":
                    VerifyExecuteParams(inputs);
                    break;
            }

            return null;
        }

        private void VerifyExecuteParams(object[] inputs)
        {
            if (new string[]{"+", "-", "*", "/"}.Where(x => x == (string) inputs[2]).Count() == 0)
            {
                throw new ArgumentException("Your operation should belong to folowing list: '+', '-', '*', '/'. Please verify and try again.");
            }
        }

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            return;
        }
    }
And as result of our work we got parameters validation, not completely in client code and not on server, but somewhere in the middle (yeah, it is still client, but validation is postponed to next step in WCF pipeline – Proxy).
image
While learning WCF I wonder how many different extensions and flexibility it allows. Not sure if it all is needed, but if you have doubts if WCF can or cannot do something, be sure – it can.


4 comments


Book Review: MCTS exam 70-503 Windows Communication Foundation Training Kit

November 14, 2010 Book Reviews, Certification, WCF No comments

imageSo accordingly to my Career Plan for Software Engineer, I want to pass some Microsoft exams. Next one (see end of 2010) is 70-503 – WCF. Which I already scheduled for 26th November.
Now few words about book itself. It indeed covers all core of WCF and huge set of WCF features/usages. What I liked is explanation of various bindings/enumerations/settings because they are showed in structured order. Yeah, from some point of view it is boring to read tables describing some of the features, but now I know that I can refer to this book as to good catalog of all WCF features.
I’ve been working with WCF for about 1 year or so, but did not understand all in depth. First of all the most difficult was to keep an eye on all that complex configuration on server and client for whole bunch of our services. But now I see that if I would have read this book before I would have much better understanding of things and would be more efficient in configuring and implementing services.
I’m also planning to perform second (first here) “developer’s meeting” for my team on features of WCF. This time it should be Advanced course. It might be difficult to talk about WCF in depth, because not all guys here work with it and it might require for them to try out basics at first, but I believe in them and in my capabilities to show all ready-cooked on the plate.


No comments


Windows Communication Foundation – Getting Started – Developer’s Meeting

August 19, 2010 DevMeeting, Presentation, Success, WCF 1 comment

Hello, today I performed presentation on Windows Communication Foundation and it went extremely well. People were interested in topic and it smelled in the air.

Why am I happy with this meeting?

People were listening very-very attentively! It is the best gift to the speaker. Many thanks to today’s attendees! You made this presentation awesome!

What was the agenda?

For today I planned to have “Getting Started” session, where I decided to talk in general what is WCF and then proceed to basic concepts of it, like ABC.

In DEMO 1 (Damn it! Let’s write some code!) I created ever simplest WCF library and simple Contract that exposed todo list functionality. Then I brifly showed configuration and we started wcftestclient.

In DEMO 2 (Damn it! Let’s configure it!) I talked a lot about endpoints and how we can configure them. After I created a lot of them it was highlighted that changing the way how our service works by configuring and not changing the code is the key feature of WCF. WCF is indeed unified framework that allows us has one logic, but different exposing to the real world.

In DEMO 3 (Damn it! Let’s use & host it!) I created very simple console application that was able to send todo item to the service. It went with some exceptions thrown into console, but people liked it and besides after that I created SuperTodoServiceClient and it worked well. Also we voted were do we want to host our service for the long time. Most decided to host it under IIS. Till the actual hosting all went well, but then suddenly it didn’t work under IIS. Reason was very simple – since my machine has brand new OS, IIS was not configured properly.

What’s next?

Also I’m planning to have another meeting on the WCF. This time it will be “Advanced”. In that session I would like to show some real-world examples. Also I’m going to prepare to the 70-503 exam (on WCF), so I might get some interesting topics from the training kit to show on the meeting.

Presentation

More and more I start disliking ppt files. But anyway to have some visual appearance of presentation I created ppt file (maybe finished with it at 5:30 am so don’t kill me if it is “poor”). Btw, having ppt has some plus – I can put my blog’s logo and URL :)

View more presentations from Andriy Buday.

Guys, looking forward to hear from you! Will appreciate any of your comments.


1 comment