LA.NET [EN]

WCFArchive

Apr 09

As I’ve said before, I’ve started porting an existing project to .NET 4.0. I’ve tried using the new features .NET 4.0 introduces (ex.: code contracts). One of the objectives I had was replacing the traditional WCF service calls with RIA services. Until now, I’ve watched a couple of presentations (for instance, Nikhil’s presentation on MIX 2010) and it really seemed great.

I must say that I was a little suspicious about it because all the presentations I had seen used EF (and if you know me, you know that I’m still not ready to say goodbye to NHibernate and I do really believe in hiding/abstracting my backend behind an OO domain model). Anyway, I’ve decided to go ahead and tried to reuse my domain model in a RIA Service after reading about presentation models in the RIA Services documentation. What a bad mistake…It did cost me a day and a hald…Unfortunately, RIA Service don’t really integrate well with “real world” objects. For instance, take a look at my DTO (which I was trying to expose to the SL client):

[Serializable]
[DataContract(Namespace = "http://sra.pt/Entidades")]
public class OcorrenciasPaginadas {
    [Key]//don’t like this, but can live with it
    [DataMember()]
    public Int32 TotalElementos { get; set; }

    [DataMember()]
    public IEnumerable<ResumoOcorrencia> Ocorrencias { 
get; set; } }

As you can see, I had to add annotate  the TotalElementos with the KeyAttribute (even though TotalElementos is not an ID; anyway, it seems like objects must always be annotated with a key). The worst of all is that the client proxy that is automatically generated in the client side doesn’t include the Ocorrencias property. After talking with Fredrik, he mentioned the IncludeAttribute. So,I’ve started by adding it. Unfortunately,it started complaining that the IncludeAttribute can only be used in association with the AssociationAttribute.

After reading the docs, it was really obvious that RIA Services considers each entity as a lightweight wrapper around a row of a table (that’s the only justification I can think of for making me add an Id property to ResumoOcorrencia that “points back” to the “main” OcorrenciasPaginadas object). In other words, RIA Services does some really cool things, but it’s just not for me because I’m not exposing my backend tables directly to my clients (I’m sorry, but I have a domain model which is responsible for everything and my clients only consume DTOs – which in most situations are really different from the tables that the domain uses to persist data).

I really expected much more from MS, especially because they’ve been presenting RIA Services as something which  can be used with any backend you have (if you don’t believe me, just watch any RIA Services presentation. I bet the guy that is presenting will always say something like “I’m using EF because this is quicker than building my own domain; don’t worry to much with this because you can expose any backend/model you’ve got with this wonderful technology”; this is not true, though I can confirm that if you’re using EF, then RIA Services do really rule).

Bottom line: goodbye RIA Services; Hello again “plain WCF”!

Apr 07

Protected: The OnDeserializingAttribute – part II

Posted in C#, Design by Contract, WCF       Comments Off on Protected: The OnDeserializingAttribute – part II

This content is password protected. To view it please enter your password below:

Apr 06

The OnDeserializingAttribute

Posted in WCF       Comments Off on The OnDeserializingAttribute

Since I’m porting an existing project to .NET 4.0, I’ve thought about using code contracts in order to improve my code base (and yes, I can say that after some initial frustrations, code contracts is my pal now :),,). And yes, it did improve…but since I’m using runtime exceptions, that also meant that I started getting unexpected runtime exceptions.

One of my DTOs had an invariant which specified that a specific object can never be null. To ensure that, I’ve introduced my own default constructor which was responsible for initializing that field into a valid (default) value. And everything run fine until I tried to recover an instance of that object through a WCF service. It was only then that I’ve recalled about an old problem that had bit me in the past: the constructor of a type isn’t called during deserialization!

Fortunately, there’s a solution for this problem: the OnDeserializingAttribute. That means that I’ll have to refactor the initialization code into a helper method so that it gets called during “normal” instantiation and during deserialization. A little more work, but at least I can still keep my invariants valid. Hurray!

Now, if I could only get NHibernate to play nicely with .NET HashSet

Mar 12

Getting exception error message in Silverlight

Posted in Silverlight, WCF       Comments Off on Getting exception error message in Silverlight

One of the things I needed to do in a recent project is get the error message returned from a WCF service in a Silverlight user control. The MSDN docs have a nice article which explains the changes you need to perform in order to get the server generated exception in your SL app (basically, you need to change the status code from 500 to 200 so that SL can access the body of the returned message).

It won’t be long until you notice that there’s a bug in WCF and that you need to use the full assembly name (yes, the one which takes type, assembly, version, etc, etc) so that WCF is able to get the custom behavior extension element you’ve written. What I did find out (the hard way – ie, after several lost minutes trying to check the name of the service) is that it won’t work if you’re using a strongly typed or versioned assembly.

There’s an entry in connect which says that this will be fixed in .NET 4.0, but this is not really good enough if you’re still in .NET 3.5 land…

Dec 02

While I was reading the Essential Windows Communication Foundation book (from Addision Wesley), I found the following code (on a transaction required for a WCF service context):

[OperationBehavior(TransactionScopeRequired = true,
   TransactionAutoComplete = true)]
public void Transfer( String from, String to, double amount){
  try {
    Withdraw(from, amount);
    Deposit( to, amount);
  }
  catch(Exception ex){
    throw ex;
  }
}

Lets not even talk about why using the Exception type in a try/catch is bad (though I accept its usage in a book, but only after seeing a justification of why you should not use it in production code)…instead, lets concentrate on what is happening inside the catch block…see anything wrong there? I hope so! You should never re-throw an exception like that. In my opinion, you’ve got 2 options here:

1. You’re “important” in the stack chain and then you’ll want to wrap that exception with your own specific  exception type (for isntance, NHibernate does something like this and wraps ADO.NET exceptions with its own exception type). Here’s what I mean:

catch(Exception ex ) { //btw, don’t catch the Exception type
  //do something here…probably log it
   throw new MyException(ex);
}

2. You’re not significant,so you can just rethrow that exception after logging:

catch(Exception ex ) { //btw,don’t catch the Exception type
  //do something here…probably log it
   throw; //see? no ex here!
}

Ok, so why is this important? Because when you re-throw the exception by using technique shown in point 2, you will be preserving the stack trace. When you do it like in the original code, the stack trace that the client will see ends up in your catch block. Probably not what you’ll want in most scenarios!

Do notice that technique 1 will also preserve the stack chain since you’re passing the exception as the inner exception of the new exception you’re throwing. Both of these options are really better than the one shown on the initial code.

I’m only writing this here because I was under the impression that this info should be well know by now, but it seems like I’m wrong…Do keep in mind that it’s not my intent to trash on this book (I’m still on page 211, but I’m liking it so far), but I was a little but surprised by seeing this code there (as always, I’ll put a review after ending it).

May 12

You can get them from here (VS) and here (.NET). I”m reading what”s new on Brad Abrams post and I”m really digging the new features:,,) For instance, having the format option working with JS code is simply cool! Another cool thing: the ScriptManager is able to combine scripts so there”s really no need for using the ToolkitScriptManager for that:)

Btw, i”m still going through the complete list but it really looks like we”re gonna gave lots of new stuff 🙂

Mar 25

On a different set of machines…I”m stumped. I mean, I though I”d nailed it with the proxy problem, but unfortunately there are still some machines where the 1st call is really really slow and removing the proxy isn”t helping. I”ve even profiled the code but  I still can”t see where the problem lies. I”ve written a post on the WCF forum, but there are still no clues on how to solve this. Anyone wants to give it a try?

Mar 14

Protected: WCF client calls slow

Posted in WCF       Comments Off on Protected: WCF client calls slow

This content is password protected. To view it please enter your password below:

Mar 10

In these last days I”ve been really busy finishing an application which consists of a Windows Forms app that gets its data from serveral WCF services (which, btw, use basic HTTP binding + SSL). Now, most of the services work really smoothly, but…there are 2 which are really making me go crazy: they are SLOW when run in Windows XP Pro machines! Now, I”m talking about really simple services which should really execute under 300 ms!

As you might expect, the first thing I did was use fiddler to see what was going on. According to it, the request was taking 15 seconds, which seemed to confirm my initial impression that there was something wrong with the service. The next logical step was enabling tracing on the WCF service. I couldn”t really believe in what my eyes were seeing: instead of seeing several seconds on processing time, the traced shown <300 ms. Could it be something wrong with IIS (which, btw, is IIS 6 on  Windows 2003 Server machine)? To answer this,I enabled IIS logging. Guess what: IIS logging confirms the WCF tracing entries: requests were served in <300 ms!

Maybe there something wrong with the network? Pinging revealed nothing wrong…So I went ahead and installed netmon on my machine. After filtering the traffic,I was able to see that request/response from client to server were consistent with the logging info I was getting from WCF and IIS. So, I”ve just went ahead and tried using ngen with my client windows forms app. It didn”t made any difference though…it was time to try one more thing: logging on the client side.

The SvcTraceViewer tool has a really great feature: you can open several trace files at the same time. When I did this, I got the following results (just copy/paste it here: on each line you”ll see a description, the number of traces, the start and end time of the action):

 

000000000000 8 13s 9:21:20 9:21:34
Construct ChannelFactory. Contract type: ”SRA.Mercados.Servicos.IServicoUtilizador”. 4 328ms 9:21:20 9:21:21
Open ChannelFactory. Contract type: ”SRA.Mercados.Servicos.IServicoUtilizador”. 4 31ms 9:21:21 9:21:21
Process action ”http://sra.pt/Mercados/IServicoUtilizador/ObtemUtilizador”. 24 14s 9:21:21 9:21:35
Receive bytes on connection ”http://bksrv.sranet.local:8080/ServicosMercados/UtilizadorImpl.svc”. 17 437ms 9:21:34 9:21:35
Close ChannelFactory. Contract type: ”SRA.Mercados.Servicos.IServicoUtilizador”. 4 0ms 9:21:34 9:21:34

Construct ServiceHost ”SRA.Mercados.ServicosImpl.ServicoUtilizador”. 10 109ms 9:21:34 9:21:35
Open ServiceHost ”SRA.Mercados.ServicosImpl.ServicoUtilizador”. 64 93ms 9:21:35 9:21:35

Listen at ”http://bksrv.sranet.local:8080/ServicosMercados/UtilizadorImpl.svc”. 6 62ms 9:21:35 9:21:35
Listen at ”https://bksrv.sranet.local/ServicosMercados/UtilizadorImpl.svc/mex”. 4 15ms 9:21:35 9:21:35
Processing message 1. 5 15ms 9:21:35 9:21:35
Execute ”SRA.Mercados.Servicos.IServicoUtilizador.ObtemUtilizador”. 4 265ms 9:21:35 9:21:35

The bold lines are where the problems are happening. Now, I really don”t understand why it takes 13 seconds for the process action on the client to hit the server (notice that server will only start its processing at 9:21:34 and that the client opens the channel at 9:21:21!). Now, I”m not really an expert on WCF, but it does seem like there”s something wrong going on here. What”s bothering me is that I don”t know what it is 🙂

It was getting late, so I only had time for testing one more thing: using perfmon and see if I can get any info from it. I”ve only tried seeing one thing: the % of JIT time spent on a process. Guess what: the counter goes through the roof when I call a method of one of those services that take a long time! I”m still trying to understand what”s going on with those XP machines (specially because on my Windows 2008 server everything is working out smoothly), but it seems like there”s something that is making the Jitter do a lot of work when one of those methods gets called. I”m not sure on what it is since, as I”ve said, it”s really a simple method and I”ve already run ngen on my code.

If anyone has any idea on what”s going on here please do share it with me! I”m running out of them and I still don”t understand what”s going on…thanks.

Jan 16

The latest release of .NET has added several interesting new things. One of those is support for Syndication. The System.ServiceModel.Web assembly has several classes that you can use to expose an ATOM or RSS feed. There”s already a cool article on how to achieve this  which has been published on MSDN, so I”m not going to bother you with the details (you can check the code online, but don”t download it because it”s not updated; instead, browse the online version). The only thing I”d like to add to what is presented on the article is how to make Firefox interpret the RSS generated as RSS (instead of interpreting it like XML).

The problem with FF is that it will only consider the XML to be RSS feed if it has all the mandatory elements. If you”re like me, you”re probably going to go through all the public properties of the SyndicationFeed object and you”ll set those that make sense. Unfortunately, there really isn”t any called link (though there”s a Links collection property) so I didn”t set up that element from my code (and <link> is one of the mandatory channel elements! – ok, my fault. Should have read the specs to see which items were mandatory…).  And that”s why  I lost almost one hour trying to understand why FF wasn”t applying its default XSLT stylesheet to my RSS content. I could see the XML, but then I got that awful message that said that there wasn”t any stylesheet file applied to my XML document. In fact, it looks like I wasn”t the only one that forgot to define the RSS link element: if you try to run the code presented on the sample, you”ll see something like this:

Untitled

The only thing you need to fix the code is to add a link element to the feed, which can be done with code that looks like this:

feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri(“put a valid URI here”)));

where feed is a reference to a SyndicationFeed object.

Now, if I only could make it add global namespaces,then I”d really be a happy man! (ok,You can add namespaces to the <channel> element, but what I want is to add those declarations on the top <rss> element)

Jun 12

Yesterday I talked about calling a traditional ASMX web service from your Silverlight app. Today, I”ll be talking about WCF services. As I”ve said yesterday, in the current release, you only have tool support for getting a proxy to an ASMX web service (well, at least I”ve tried getting a web reference to a WCF service and it simply didn”t work – maybe i”m doing something wrong). However, nothing prevents you from creating your own proxy to make the call to  a WCF service.

Since the alpha version only understands JSON when it calls ASMX services, I”m also assuming that is the only way you have to get info from a WCF service. That being the case, you must start by configuring your service to use JSON as its message enconding format.

After doing that, it”s only a matter of  creating a new proxy class. Let me illustrate this with a quick example. Lets start by creating the dummy service:

[ServiceContract]
public interface ITest
{
    [OperationContract]
    S DoWork();
}

public class Test : ITest
{
    public S DoWork()
    {
        S a = new S();
        a.Address = “Funchal”;
        a.Name = “Luis”;
        return a;
    }
}

Don”t forget to add the svc file :,,) (not shown here because there really isn”t much to show, right). As you can see, this is really a stupid service which returns an object that only has two properties. Here”s the S class (just for the sake of completeness):

[DataContract]
public class S
{
    [DataMember(Name=”Name”)]
    private string name = “Luis”;
    [DataMember(Name=”Address”)]
    private string address= “Funchal”;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public string Address
    {
        get { return address; }
        set { address = value; }
    }
}

Now, the fun begins 🙂 You must start by definig the S class in your silverlight project. You can do this in several ways:

  • you can add an existing cs file and then choose the link option (instead of clickin in the add button);
  • you might have built a dll with the previous type and then add it as reference to the service and silverlight projects;
  • there”s always the old copy/paste approach 🙂

After doing that, you need to build a new type (the proxy) which you”ll be using to communicate with the service. You must really build a new class because all the cool methods of the the SoapHttpClientProtocol class that you need to make the service calls are protected (the truth is that nothing prevents you from using the BrowserHttpWebRequest class and then using the JavaScriptSerializer to serialize/deserialize the values. If you find this funny, then by all means, go ahead and do it; i prefer to build the class in 30 seconds and then hit the coach to watch tv :))  . Here”s a simple proxy that lets you invoke the DoWork method in a sync fashion:

public class MyProxy:SoapHttpClientProtocol
{
            public S DoWork()
            {
                object[] obj = this.Invoke(“DoWork”, new ServiceParameter[0], typeof(S));
                return (S)obj[0];
            }
}

Do notice the new ServiceParameter[0] value passed as the 2nd parameter of the Invoke method (needed because the method doesn”t receive any parameters; if it expected parameters, you just need to pack them in an array and pass them to the Invoke method)…Getting the async methods is as easy as adding 2 methods which call the BeginInvoke/EndInvoke methods inherited from the base class. Using the proxy is really simple, as you  can see from the following code:

MyProxy proxy = new MyProxy();
proxy.Url = “url to the service”;
S aux = proxy.DoWork();
Debug.WriteLine(aux.Name +”-“+ aux.Address);

And that”s all for today.

May 22

The 3.5 beta version of the .NET platform lets us use JSON as the serialization format used by a web service call. The best of all is that this means that we can now call a web service from an ASP.NET AJAX page.

To do this, you need to add some entries to your configuration file (on the server side). Getting a proxy on the client side is a simple as adding a service reference through the ScriptManager control. Lets start by seeing the service code (which was generated by adding a new WCF service to an AJAX futures enabled web site):

[ServiceContract()]
public interface ITest
{
    [OperationContract]
    string MyOperation1(string myValue);
}

public class Test : ITest
{
    public string MyOperation1(string myValue)
    {
       return “Hello: ” + myValue;
     }
}

The svc file looks like this:

<%@ ServiceHost Language=”C#” Debug=”true” Service=”Test”
              CodeBehind=”~/App_Code/Test.cs” %>

Now you need to add an endpoint that is able to understand JSON. In my case, I wanted to expose a mex endpoint too, so I ended up with the following definitions for my web service:

<services>
  <service name=”Test” behaviorConfiguration=”metadataSupport”>
         <endpoint binding=”webHttpBinding”
                    behaviorConfiguration=”jsonBehavior”
                    contract=”ITest”
                    bindingConfiguration=”jsonBinding”/>
          <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange”/>
   </service>
</services>

As you can see, i”m using  a WebHttpBinding and I”m saying that there”s a new jsonBinding element which configures the traditional webHttpBinding that is introduced by default by the WCF framework. In this case, we”re just setting the message encoding to JSON:

<bindings>
  <webHttpBinding>
        <binding name=”jsonBinding” messageEncoding=”Json”/>
  </webHttpBinding>
</bindings>

We also need to add a new behavior that looks like this:

<behaviors>
  <serviceBehaviors>
     <behavior name=”metadataSupport”>
         <serviceMetadata httpGetEnabled=”true” httpGetUrl=””/>
     </behavior>
   </serviceBehaviors>
   <endpointBehaviors>
        <behavior name=”jsonBehavior”>
           <enableWebScript />
        </behavior>
   </endpointBehaviors>
</behaviors>

And that”s it! the only thing you need to do to call this WCF service from your AJAX ASP.NET page is add a reference to the web service:

<asp:ScriptManager ID=”ScriptManager1″ runat=”server”>
  <Services>
     <asp:ServiceReference Path=”Test.svc” />
  </Services>
</asp:ScriptManager>

Doing this ends up inserting the following js code in your page:

Type.registerNamespace(”tempuri.org”);
ITest=function() {
ITest.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
ITest.prototype={
MyOperation1:function(myValue,succeededCallback, failedCallback, userContext) {
return this._invoke(ITest.get_path(), ”MyOperation1”,false,{myValue:myValue},succeededCallback,failedCallback,userContext); }}
ITest.registerClass(”ITest”,Sys.Net.WebServiceProxy);
ITest._staticInstance = new ITest();
ITest.set_path = function(value) { ITest._staticInstance._path = value; }
ITest.get_path = function() { return ITest._staticInstance._path; }
ITest.set_timeout = function(value) { ITest._staticInstance._timeout = value; }
ITest.get_timeout = function() { return ITest._staticInstance._timeout; }
ITest.set_defaultUserContext = function(value) { ITest._staticInstance._userContext = value; }
ITest.get_defaultUserContext = function() { return ITest._staticInstance._userContext; }
ITest.set_defaultSucceededCallback = function(value) { ITest._staticInstance._succeeded = value; }
ITest.get_defaultSucceededCallback = function() { return ITest._staticInstance._succeeded; }
ITest.set_defaultFailedCallback = function(value) { ITest._staticInstance._failed = value; }
ITest.get_defaultFailedCallback = function() { return ITest._staticInstance._failed; }
ITest.set_path(“/AJAXFuturesEnabledWebSite2/Test.svc”);
ITest.MyOperation1= function(myValue,onSuccess,onFailed,userContext) {ITest._staticInstance.MyOperation1(myValue,onSuccess,onFailed,userContext); }

which really looks similar to waht you get when you add JSON support to an ASMX web service.

Jan 19

Since I”ve just lost a couple of hours trying to configure my WCF service to use SSL, I”ve though I”d put the steps here for self-reference.

The first thing you need to do is to create a test certificate. Since I”m running Vista+IIS 7 (workstation), I”ve used makecert with something like this:

makecert -sr LocalMachine -ss My -a sha1 -n “CN=url-you”re-using” -sky exchange -pe

Basically, the previous command creates a new certificate and puts it in the Personal folder of the local machine store. It also configures the private key so that it needs to be exported.

After doing this, it will be necessary to export the certificate and all the certificates in the certification path – normally, one: Root Agency. Then you”ll have to install them in the clients that want to use the client (normally, the root agency certificate will be installed in the trusted publishers and the test certificate should be put in the trusted people store of the local machine).

After performing these steps, you might still need to give access permissions to the private key  to the service running the process that hosts the WCF service (WCF sampls have a tool called FindPrivateKey that helps you in finding the file that has the private key of the service).