Playing with WCF and NuSOAP 0.7.2

By Jerome at January 25, 2007 10:24 Tags: , , , ,

.NET 3.0 has now been released, along with Windows Communication Foundation (WCF). I thought I could give it a shot for one of my projects at work, where I have to create an internal web service. The problem is that the client at the other end will be using NuSOAP 0.7.2 to contact this WebService, so I had to make sure it would work fine.

First observation, compared to ASP.NET generated WebService, the WCF wsdl is much more complex. Actually, it has a little bit more information such as the validation rules for a guid, but it also has its schema split up into multiple XSD files. I was a bit worried that NuSOAP wouldn't handle that well, but it does fine... I also wanted to be able to expose a signature like this :

1:     [DataContract]
2:     public class Parameter
3:     {
4:         private string _key;
5:         private object _value;
6:  
7:         [DataMember]
8:         public string Key
9:         {
10:             get { return _key; }
11:             set { _key = value; }
12:        }
13:  
14:        [DataMember]
15:        public object Value
16:        {
17:             get { return _value; }
18:             set { _value = value; }
19:        }
20:    }

You'll notice that the second property is an object, and that implies that the serializer/deserializer handles properly types defined at runtime, by using xsd:anyType in the schema.

So, after a few attempts to get working linux LiveCD distro, for which none of them had PHP compiled the correct --enable-soap flag, I decided to fall back from the native PHP SOAP extensions to the OpenSource SOAP library NuSOAP and use EasyPHP on Windows.

First, I had to change NuSOAP's response encoding to UTF-8 using soap_defencoding, which seems to be the default for WCF, then I had to figure out how to pass an arry of structures to call my method.

So, for the following signature :

    void MyMethod(string a, string b, Parameter[] parameters)

The caller's php parameter structure should be :

$params = array(
'a' => $a,
'b' => $b,
'parameters' => array(
'Parameter' => array(
array('Key' => 'abc', 'Value' => 10),
array('Key' => 'def', 'Value' => 42)
)
),
); 

Notice that you have to place a "Parameter" element inside the "parameters" parameter.

Then, to call the method, use the following line :

    $client->call("MyMethod", array($params));

by encapsulating the parameter array once again. This makes a lot of levels to call one little function... I prefer the .NET way of doing thing :)

An other problem came up right at this point : The array, although the information being in the soap body, was not filled on the .NET side. After comparing with a .NET to WCF call, I figured that there was a missing namespace. This is what is generated by default with the code I've presented above using NuSOAP :

<parameters>
<Parameter>
<Key>abc</Key>
<Value>10</Value>
</Parameter>
<Parameter>
<Key>def</Key>
<Value>42</Value>
</Parameter>
</parameters>

And this is what .NET is generating :

<parameters>
<Parameter xmlns="http://schemas.datacontract.org/2004/07/MyService">
<Key>abc</Key>
<Value>10</Value>
</Parameter>
<Parameter xmlns="http://schemas.datacontract.org/2004/07/MyService">
<Key>def</Key>
<Value>42</Value>
</Parameter>
</parameters>

For some reason, the WCF basicHttp binding point is generating two different namespaces for the service contract and for the data contract. To fix this, you just have to specify explicitly a namespace for each ServiceContract and DataContract attribute of your service :

    [DataContract("http://mywebservice.example.com")]

The other problem was about using an unspecified data type as a member of a structure, a System.Object in my case. Well, it turns out that NuSOAP does not support it, as it does not include the data type of the serialized element, so the WCF deserializer cannot interpret it. I changed the data type back to string, unfortunately losing the type information. I can get it from somewhere else but still, this can lead to serialization problems related to culture (comma being a dot and the opposite depending on systems, for instance).

Anyway, there are a few things to remember to get things to work fine with NuSOAP :

  • Change the encoding to UTF-8 or whatever encoding you choose to use,
  • Don't forget to specify the name of the type of an element in an array in PHP, 
  • Do not expose unspecified parameters or attributes,
  • Explicitly specify the namespace of each DataContract and ServiceContact attribute of your service.

It's been a while since I've written a line of PHP code, and I didn't miss it at all. I'm going back to WCF now :)

Some news

By Jerome at January 24, 2007 16:29 Tags:

Here it is ! I've promised for too long now that I'd be adding a blog to this web site, and here it is ! I had some time last weekend, and I decided to update the site to add it.

It's pretty simple stuff in ASP.NET 2.0 and SQL Server 2005, but it allows posts to have comments, to be grouped and shown in the rss by groups. Nothing new, really.

The point on creating this blog here is to be able to write in english and not bother french readers (my native language) on community blogs. Plus, I'll try to add some more frequent updates on Bluetooth Remote Control for which, wandering around the web, I've found some users having trouble with it that I did not know about.

I've also been busy lately getting on to certifications such as MCTS (via the MCSD Upgrade part 1), and MCT. Upgrade part 2 is coming soon too...

Anyway, if you want to get in touch with me directly and publicly, feel free to do so here.

ODP.NET 10.2.0.2.20 Connection Pool Race Condition

By Jerome at December 22, 2006 12:56 Tags: ,

Aaah, les joies d'Oracle. Ma base de données préférée... accompagnée de son cortège de bugs...

Bon, j'arrête là le sarcasme, mais j'ai du mal :)

Dans le cadre d'un projet sur lequel je travaille, je suis tombé sur un bug très, très gênant : Le provider ODP.NET d'oracle peut se connecter à un schéma sur lequel il n'est pas censé se connecter...

Je m'explique : dans le même AppDomain d'un même process, je crée dans des Threads différentes deux OracleConnection avec deux chaines de connexion différentes. Jusque là , rien d'anormal. Le problème est que de temps à autres, l'une de deux connexion va utiliser la chaine de l'autre thread !

Après avoir vérifé rapidement le contenu de l'objet OracleConnection, il se trouve qu'une variable nommée "m_InternalConStr" contient parfois une chaine qui ne correspond par du tout à celle qui a été passée en paramètre dans le constructeur... C'est très génant, car si l'on se connecte à une base alors que l'on pense se connecter à une autre, ... je vous laisse immaginer les dégats si on fait des updates.

Donc après de nombreuses tentatives, je suis arrivé à la conclusion qu'il faut synchroniser tous les appels à OracleConnection du constructeur jusqu'à Open avec un Mutex, et cela sur l'AppDomain courant. Vous imaginez aisément le goulot d'étranglement. J'aurais tout aussi bien pu désactiver le Connection Pool, mais la aussi, coté performance cela devient gênant.

Bien entendu, ce genre de problème apparait plus souvent sur une machine Multi Processeur. (En production dans mon cas, ca fait toujours plaisir...)

Je n'arrive pas à reproduire la Race Condition de manière systématique, mais je met avec ce post un exemple de code qui teste tout ca. Généralement, l'erreur apparait au bout de quelques essais. Pour tester si le ConnectionPool est consistant, j'effectue quelques lignes de Reflection pour aller chercher des variables interne... pas très propre, mais c'est suffisement déterministe.

Si quelqu'un se sent suffisement motivé pour tester... :)

IIS, HTTP 401.3 and ASP.NET directories ACLs

By Jerome at September 01, 2006 22:09 Tags: , ,

A few days ago, on a newly installed web server with all the appropriate security patches applied, I kept having the same error on every ASP.NET 1.1 application I was running :

HTTP Error 401.3 - Unauthorized: Access is denied due to an ACL set on the requested resource.

At first, the reflex is to check all the permissions of the mapped physical directory, that they match the Application Pool identity, the guest identity (IUSR_Machine on my server) and for some configurations, the impersonated identity any ASP.NET configuration. Even with all these checks, any ASP.NET application was returning the same 401.3 error for anonymous users...

Well, it turns out that the ACL of the %SystemRoot%\Microsoft.NET\Framework\v1.1.4322 is important too... I don't know how the ACL got changed in the first place, and I don't know either how I came to check on these ACL, but that can waste a lot of time...

Bluetooth Remote Control 0.5.0-Beta5

By Jerome at July 26, 2006 00:22 Tags:

Here is a new version of Bluetooth Remote Control for Windows Mobile, with some improvements :

  • Automatic installation of the CAB file,
  • The correction of some stability issues on SPV E200,
  • The ability to view slide notes in PowerPoint on the PPC/SmartPhone.

The version 0.5.0-Beta5 is available here :

http://jaylee.org/remotecontrol

C# 3.0, a sneak peek

By Jerome at July 22, 2006 10:22 Tags: ,

If you've used both DataSet and DataTable, you must have seen the DataTable.Select method. This is an interesting method that allows to select rows using a set of criterias, like IS NULL and comparison operators referencing columns of the current table, as well as columns from other tables using relations. The problem with method is that is returns a DataRow[], on which you cannot perform an other select.

The solution is actually quite simple : Just copy the rows you'll answer me. Yes, but you can't just reference rows in two DataTable instances, so you also have to perform a deep copy of the rows. So, with a little digging in the DataTable methods, here is what you get :

public static DataTable Select(DataTable table, string filter, string sort)
{
   DataRow[] rows = table.Select(filter, sort);
   DataTable outputTable = table.Clone();

   outputTable.BeginLoadData();

   foreach(DataRow row in rows)
      outputTable.LoadDataRow(row.ItemArray, true);

   outputTable.EndLoadData();
   return outputTable;
}

Clone is used to copy the table schema only, BeginLoadData/EndLoadData to disable any event processing during the load operation, and LoadDataRow to effectively load each row. This seems to be a fairly fast way to copy a table's data.

Now, I wondered how they would do this in C# 3.0, since there is a lot of data manipulation with the new LINQ syntax. This version is quite interesting because instead of evolving the runtime, they chose to upgrade only the language by adding features that generate a lot of code under the hood. That was the case in C# 2.0 with iterators and anonymous methods. C# 1.0 also had this with foreach, using or lock for instance.

In the particular case of Linq, C# 3.0 generates a method invocation list  of a LINQ query, producing standard C# 3.0 code with the help of lambda expressions. For example, these two lines are equivalent :

   var query = from a in test where a > 2 select a;
   var query2 = Sequence.Where(test, a => a > 2);

This ties a little more the compiler to the system asssemblies, but this does not matter anymore.

By the way, you can apply queries to standard arrays and join them :

static void Main(string[] args)
{
   var names = new[] {
      new { Id=0, name="test" },
      new { Id=1, name="test1" },
      new { Id=2, name="test2" },
      new { Id=4, name="test2" },
   };

   var addresses = new[] {
      new { Id=0, address="address" },
      new { Id=1, address="address1" },
      new { Id=2, address="address2" },
      new { Id=3, address="address2" },
   };

   var query = from name in names
      join address in addresses on name.Id equals address.Id
      orderby name.name
      select new {name = name.name, address = address.address};

   foreach(var value in query)
      Console.WriteLine(value);
}

I've joined the two arrays using the Id field, and creating a new type that extracts both name and address. I really like inline querying because you can query anything that implements IEnumerable.

I'm also wondering how it'll fit into eSQL (Entity SQL)...

But back to the original subject of this post. They had to do some kind of a DataTable copy in the C# 3.0 helper library, which uses extension methods :

   DataTableExtensions.ToDataTable<T>(IEnumerable<T>)

And with some further digging, I found that the LoadDataRow method for copying data is the fastest way to go.

I also found out using the great reflector that there is an Expression compiler in System.Expressions.Expression<T>. Maybe they finally did expose an expression parser that we can use... I'll try this one too !

BTRemote Control and Windows XP 64 Bits

By Jerome at May 26, 2006 23:21 Tags:

Quite a few people have now been using the latest beta for a while, and I get most of the time feature requests, sometimes non critical bugs like the Remote Client not connecting if the host PC is not discoverable, and not so often blocking bugs.

The one Krijn Wijnands (thanks !) has uncovered might involve Windows XP 64 Bits. The remote client does not connect to the server, and he's using an hardware configuration that's proved to work fine.

I do not own a 64 bits machine and if any of readers of this blog or user of this utility uses Windows XP 64 bits, please leave me a message. I'll be glad to hear from you.

The client version of this software do log much out of the debug build for now, but I'll add some more for extensive diagnostics.

From a pure developer point of view, .NET 2.0 64 Bits should not change a thing, but I suspect a P/Invoke issue that I've not covered. That should give me a reason to upgrade my server to 64 Bits ;) For the sake of the testing, of course.

For the next release, I'll be adding generic support for applications, configurable using a static xml file (there's no point on modifying this at runtime)

If you have some other wishes that come to mind, feel free to speak !

Precision Timer in .NET 2.0

By Jerome at November 18, 2005 16:25 Tags: ,

If you've been using the .NET Framework since the beginning, you must have had to do some early code profiling, or framerate computation for realtime graphics.

The first idea that pops up to acheive this is to use the DateTime.Now property and do some subtraction of two instances. This is not a good idea since the resolution of this timer is around 10ms or so, which is clearly not enough (and your framerate counter may not go higher than 100 FPS or worse may not work at all).

If you've been in the business for long enough, and been doing some plain old "native" code in, say, C++ on Win32, you should probably used the couple QueryPerformanceFrequency/QueryPerformanceCounter to get the job done. And the same goes for .NET 1.0/1.1. Well, I don't know for you, but each time I have a project that reaches a certain critical size, I always need to use this kind of timer and I end up by writing the P/Invoke wrapper to reach these two methods.

Good news is, .NET 2.0 already has this class integrated in the form of System.Diagnostics.Stopwatch, so you don't have to write it from scratch again and again because you can't find on the net the right "free" class that does enough for you.

The BCL team has added some other nice utility classes like this one, and this saves quite some time.

Reflective Visitor using C#

By Jerome at April 04, 2005 11:35 Tags: ,

There is a well known design pattern in the Object Oriented world: The Visitor pattern.

This pattern, among other things, allows to extend an object without actually modifying it. It is fairly easy to implement in any good OO language such as C++, Java or C#.

However, there is a problem with the implementation of this pattern, or rather an implementation limitation. It requires the base interface or abstract class for all visitors to define at most one method for each type that may visit it. This is not a problem by itself, but it requires to modify the visitor base each time you add a new type. The best way to do this would be to call the appropriate method based on the caller type.

.NET provides that kind of behavior through reflection, as it is possible to find a method based on its parameters at runtime.

I decided to try this out with the C# 2.0 and its generics :)

Here what I came up with :

 

public interface IOperand
{
 
IOperand Accept(Visitor visitor, IOperand
right);
}

public class Operand< T> : IOperand
{
  private
T _value;

  public
Operand(T value)
 
{
   
_value = value;
 
}
  public IOperand Accept(Visitor v, IOperand
right)
 
{
    return v.Visit(this
, right);
  }
  public T Value
  {
    get { return
_value; }
 
}
  public override string ToString()
  {
    return string.Format("{0} ({1})", _value, GetType());
  }
}

This is the definition of an operand, which is used in a abstract machine to perform operations on abstract types. This class is generic, I did not want to implement all the possible types.

Then here is the visitor :

 

public class Visitor
{
 
public virtual IOperand Visit(IOperand left, IOperand right)
 
{
   
MethodInfo info = GetType().GetMethod("Visit", new Type[] { left.GetType(), right.GetType() });
   
   
if (info != null && info.DeclaringType != typeof(Visitor))
     
return info.Invoke(this, new object[] { left, right }) as IOperand;

    
Console.WriteLine("Operation not supported");
   
return null;
  
}
}

This method search in the current type all methods named "Visit" that take the actual type of the parameters left and right and tries to match a method with it. Also, to avoid looping through the same method we're in since it's matching everything, there is a test for the type declaring the method.

Now the AdditionVisitor :

 

public class AdditionVisitor : Visitor
{
  public IOperand Visit(Operand<int> value, Operand<int> right)
  {
    return new Operand<int>(value.Value + right.Value);
  }
  public IOperand Visit(Operand<int> value, Operand<short> right)
  {
    return new Operand<int>(value.Value + right.Value);
  }
  public IOperand Visit(Operand<double> value, Operand<int> right)
  {
    return new Operand<double>(value.Value + right.Value);
  }
}

Which defines a bunch of visitable methods used to add different operations on IOperand-like types.

And finally to use it :

 

class Program
{
  static void Main(string[] args)
  {
    Operand<int> a = new Operand<int>(21);
    Operand<short> b = new Operand<short>(21);
    Console.WriteLine(Add(a, b));
  }

 
static IOperand Add(IOperand a, IOperand b)
 
{
   
AdditionVisitor addVisitor = new AdditionVisitor();
   
return a.Accept(addVisitor, b);
 
}
}

Using this Reflective Visitor, modifying the base visitor class is not needed anymore, which limits the modifications to one class only. Of course, there's room for optimization, for instance by avoiding the method lookup using the System.Reflection namespace, but you get the picture.

Some asked me what could be done in .NET that could not be done in C++, this is an example of it :)

C# 2.0, Closures and Anonymous Delegates

By Jerome at April 04, 2005 11:33 Tags: ,

I was looking around the web about new features in C# 2.0, and I came across this article about the support for closures in C# 2.0. The article explains that the support for closures in C# 2.0 takes the form of anonymous delegates.

There are some examples of closures like this one :

public List<Employee> Managers(List<Employee> emps)
{
  return emps.FindAll(
    delegate(Employee e)
    {
      return e.IsManager;
    }
  );
}

Which is interesting, but less than this one :

public List<Employee> HighPaid(List<Employee> emps)
{
  int threshold = 150
;
  return emps.FindAll(
    delegate(Employee
e)
    {
      return
e.Salary > threshold;
    }
 
);
}

The interesting part here is that the delegate is actually allowed to use a variable that is local to the method where it is defined. You might wonder how this is implemented by the C# compiler.
It may become even less obvious with this example :

public Predicate<Employee> PaidMore(int amount)
{
  return delegate(Employee e)
  {
    return e.Salary > amount;
  };
}

Ok, where does the compiler stores the value of "amount" since the delegate method is only returned to be executed later... ?

In fact, the compiler only generates a "DisplayClass" that containts amount as a field initialized when the anonymous delegate is created, and the implementation of the delegate itself.

Easy.

About me

My name is Jerome Laban, I am a Software Architect, C# MVP and .NET enthustiast from Montréal, QC. You will find my blog on this site, where I'm adding my thoughts on current events, or the things I'm working on, such as the Remote Control for Windows Phone.