Search code examples
asp.netweb-serviceswcfsoapasmx

Migrate ASMX web method to WCF which accepts string array


I have one legacy ASMX service which is consumed by many clients (java, .Net, Python etc). I want to upgrade ASMX service to WCF without impacting my clients (means they will not do any change in their code)

Below function works fine in ASMX:

[WebService(Namespace = "http://example.com/Report", Description = "Save")]
    public class Report : WebService
    {
      
        [WebMethod(Description = "Save")]

        public void Save(string name, string[] skills)
        {
        }
    }

It means when client calls Save method and pass name (string) and skills (string[]) parameter then I get it at service end which I further save in database.

In WCF I wrote below interface and class:

[ServiceContract(Namespace = "http://example.com/Report")]
public interface IReport
{
    [OperationContract(Action = "http://example.com/Report/Save")]
    void Save(string name, string[] skills);
}

public class Report : IReport
{
    public void Save(string name, string[] skills)
    {
       
    }
}

When I call WCF service from same legacy client then I get name value but not skills value (which is string[]).

Please help how I can get the string[] values. I cannot change client code.

I expect that when I change ASMX to WCF then it should work without impacting my clients. I am unable to get value of skills (which is string array).

It seems in WCF, system is unable to desterilize the string array. I tried with List instead of string[] but also did not work.


Solution

  • I got a solution. I created ArrayOfString class and added CollectionDataContract attribute. Like below

    [ServiceContract(Namespace = "http://example.com/Report")]
    public interface IReport
    {
        [OperationContract(Action = "http://example.com/Report/Save")]
        void Save(string name, string[] skills);
    }
    
    public class Report : IReport
    {
        public void Save(string name, ArrayOfString skills)
        {
           
        }
    }
    
    
    [CollectionDataContract(Name = "ArrayOfString", Namespace = "http://example.com/Report", ItemName = "string")]
       [Serializable]
       public class ArrayOfString : List<string>
       {
       }
    

    Now if client will call the method like below:

    ReportClient client = new ReportClient();
    client.Save("David", new string[] {".Net", "C#", "WCF"});
    

    At service end I will get the array values in object of ArrayOfString.

    By this I don't need to change my legacy clients who created proxy (ReportClient) using ASMX service.