WCF – Generic List is converted to Array

As I discussed in my previous blogs I am developing a small tool for transferring files between computers in LAN. I decided to use WCF as my main technology in this application. During my developing I discovered that a data member whose type is a generic list, was changed when WCF service is exposed to client. The type was changed from a list to an array.

We pay attention to the data member “Files” whose type is a List of FileObject

    [DataContract]
    public class TransferObject
    {
        [DataMember]
        public QueryTypes QueryType { get; set; } // The action of the packet
        [DataMember]
        public string Name { get; set; } //Client name
        [DataMember]
        public string Id { get; set; } //Identification
        [DataMember]
        public List<FileObject> Files { get; set; } //the list of the file

        public TransferObject()
        {
            Files = new List<FileObject>();
        }

        public TransferObject(QueryTypes qtType) : this()
        {
            QueryType = qtType;
        }
    }

And this is the generated client code. We can recognize immediately that the type was changed to an array of FileObject.

 [System.Runtime.Serialization.DataMemberAttribute()]
        public Files_Over_LAN.FileServiceReference.FileObject[] Files {
            get {
                return this.FilesField;
            }
            set {
                if ((object.ReferenceEquals(this.FilesField, value) != true)) {
                    this.FilesField = value;
                    this.RaisePropertyChanged("Files");
                }
            }
        }

The reason for this converting is that “WCF Service are platform-agnostic, they need to use the most primitive data types“. Please consider two scenario below:
Scenario 1 :
What would happen if your web service would be consumed by a .NET 1.x application, where no generics are available?
Scenario 2 :
How would non .Net applications (J2ee or PHP) will consume the service, which doenst have the knowledge of .Net Generics?
The convertion happens because array is the lowest common denominator.

And what we should do if we still want to use generic list. It’s pretty simple. Right click on your service reference, choose “Configure Service Reference”.

At the combo box of collection type, we choose Generic List instead of Array

Now the client code will be exposed correctly as we expect.

C# – Enumerate all online computers on LAN

I am writing a small tool to send file over local area network. Sometimes I would like to exchange some files between computers. You may be ask me why I do not setup any home network and simply share file between computers. The reason is I am lazy. You must tell me that I am crazy. I know. I am lazy to set up network but spend time to write a tool which may be useless for others. I can not understand myself why I do that. Ok it time to end chatting. Go back to the source code. In my “stolen” source code, I just call a native API function NetServerEnum to enumerate all computers.

[DllImport("netapi32.dll", EntryPoint = "NetServerEnum")]
        public static extern int NetServerEnum([MarshalAs(UnmanagedType.LPWStr)]string servername,
           int level,
           out IntPtr bufptr,
           int prefmaxlen,
           ref int entriesread,
           ref int totalentries,
           SV_101_TYPES servertype,
           [MarshalAs(UnmanagedType.LPWStr)]string domain,
           IntPtr resume_handle);

For more details on porting this API function from c++ to c# you can download NetApi in C# source code. From the source code file you can use the function GetServerList which returns the ArrayList of SERVER_INFO_101 structs to Enumerate all the servers on a domain or workgroup.

       ArrayList alNetworkComputers = NetApi32.GetServerList(NetApi32.SV_101_TYPES.SV_TYPE_WORKSTATION | NetApi32.SV_101_TYPES.SV_TYPE_SERVER);

            for (int nIndex = 0; nIndex < alNetworkComputers.Count; nIndex++)
            {
                Console.WriteLine(((NetApi32.SERVER_INFO_101)alNetworkComputers[nIndex]).sv101_name);
            }

I think this post is not very interesting, but I think it may be useful for someone who needs it.

UPDATE 18.10.2011
– List all computers with his name and ip addresses.

ArrayList alNetworkComputers = NetApi32.GetServerList(NetApi32.SV_101_TYPES.SV_TYPE_WORKSTATION | NetApi32.SV_101_TYPES.SV_TYPE_SERVER);
string computerName = "";
for (int nIndex = 0; nIndex < alNetworkComputers.Count; nIndex++)
{
	computerName = ((NetApi32.SERVER_INFO_101)alNetworkComputers[nIndex]).sv101_name;
	Console.WriteLine(Dns.GetHostAddresses(computerName)[0].ToString() + "\t\t : \t" + computerName);
}
Console.ReadLine();

Design Pattern – Dependency Injection

Nowadays Design Patter is not only the task of software architects but also the necessary knowledge of programmers. Only by having a thorough grasp of design pattern the programmers can implement the complex software without causing a lot of bugs which will require a lot of time to fix at the maintaining period. Dependency Injection is a well-known pattern used frequently in developing environment. I think you did use this pattern already just don’t know its name. You can find a lot of books out there discussing about it, for example this Dependency Injection book. In this small blog I do not intend to write a long, loong, looong research about this pattern. I just give some code to demonstrate what Dependency Injection is.

Continue reading Design Pattern – Dependency Injection