user1438082
user1438082

Reputation: 2748

WCF Call Function from asp.net

I am trying to pass an object via WCF. I can pass strings, ints etc no problem, but this list of objects will not work.

Here are my 2 specific errors:

Error 1:

The best overloaded method match for
 'test.ServiceReference1.JobsClient.FilesToControl(test.ServiceReference1.Item[])'
 has some invalid arguments

Error 2:

Argument 1: cannot convert from 'System.Collections.Generic.List<test.Site1.Item>'
 to 'test.ServiceReference1.Item[]'

This is the function I am trying to call within asp.net:

// Commit the files
ServiceReference1.JobsClient Client = new ServiceReference1.JobsClient();
Client.Endpoint.Address = new System.ServiceModel.EndpointAddress("http://" +   DropDownListSystems.SelectedValue + ":8732/FactoryAudit/");
test.ServiceReference1.ReturnClass ControlFiles_Result;
ControlFiles_Result = Client.FilesToControl(lstNewItems);

lstNewItems (the object I am trying to pass) is defined as the following code:

List<Item> lstNewItems = new List<Item>(); // Control Items  

Item is defined as:

public class Item
{
    public Item(string Paramater, string Type)
    {
        _Paramater = Paramater;
        _Type = Type;

    }

    private string _Paramater;

    public string Paramater
    {
        get { return _Paramater; }
        set { _Paramater = value; }
    }

    private string _Type;

    public string Type
    {
        get { return _Type; }
        set { _Type = value; }
    }
}

Now in the WCF service I have the following function which accepts a list of items:

//Files Manager
public  ReturnClass FilesToControl(List<Item> ItemsToControl)

{ return new ReturnClass(1, String.Empty, String.Empty, null, null, null); }

The service contract is defined as:

[ServiceContract]
public interface IJobs
{
     //Files Manager
     [OperationContract]
     ReturnClass FilesToControl(List<Item> ItemsToControl);      
}

The items class is defined in WCF as follows:

[DataContract]
[KnownType(typeof(List<Item>))]
[KnownType(typeof(Item))] 
public class Item
{
   public Item(string Paramater, string Type)
   {
       _Paramater = Paramater;
       _Type = Type;

   }
   [DataMember]
   private string _Paramater;
   [DataMember]
   public string Paramater
   {
       get { return _Paramater; }
       set { _Paramater = value; }
   }
   [DataMember]
   private string _Type;
   [DataMember]
   public string Type
   {
       get { return _Type; }
       set { _Type = value; }
   }
}

Upvotes: 1

Views: 1252

Answers (2)

user1438082
user1438082

Reputation: 2748

Thanks to Abel i was able to figure it out. Below is the solution. I hope this helps someone else.

Note you also have to right click on the service reference in asp.net and click "configure service reference" and set the "collection type" to Systems.Collections.Generic.List

here is now how i call the function in asp.net

Item NewItem = new Item();
        foreach (GridViewRow PendingItemUnderControl in GridViewPendingList.Rows)
        {
            NewItem.Paramater = PendingItemUnderControl.Cells[0].Text.ToLower();
            NewItem.Type = (String)Session["BrowseType"];
            lstNewItems.Add(NewItem);
        }
       ControlFiles_Result = Client.FilesToControl(lstNewItems);

The definition of the lstItems is as follows in asp.net

  List<Item> lstNewItems = new List<Item>(); // Control Items  

Abel was correct in saying i needed to add a reference at the top of my asp project. Also note that item is declared in the WCF application and hence no need to declare it in asp.net as we have referenced it in the line below as follows:

using test.ServiceReference1;

Now down in WCF the code in IJobs.cs. Note the Private and Public as for testing i had all these to public and it caused havoc.

using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Collections;
namespace WCFJobsLibrary
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IJobs" in both code and config file together.
    [ServiceContract]
    public interface IJobs
    {
         //Directoy Manager
         [OperationContract]
        ReturnClass FindDrives();
         //Directoy Manager
         [OperationContract]
         ReturnClass FindSubfolders(String Folder_To_Search);
         //Directoy Manager
         [OperationContract]
         ReturnClass FindSubFiles(String Folder_To_Search);
         //Directoy Manager
         [OperationContract]
         ReturnClass FilesToControl(List<Item> ItemsToControl);        

    }


        [DataContract]
      //  [KnownType(typeof(List<Item>))]
        [KnownType(typeof(Item))] 
           public class Item
       {
           public Item(string Paramater, string Type)
           {         
               _Paramater = Paramater;
               _Type = Type;
           }
           private string _Paramater;
            [DataMember]
           public string Paramater
           {
               get { return _Paramater; }
               set { _Paramater = value; }
           }
            private string _Type;
            [DataMember]
           public string Type
           {
               get { return _Type; }
               set { _Type = value; }
           }

       }




}

And Jobs.cs - with a simple test to make sure it was working.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Collections;
using System.Web;
using Microsoft.Win32;
namespace WCFJobsLibrary
{

        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Jobs" in both code and config file together.
       public class Jobs : IJobs
    {


       #region IJobs Members            



        //Files Manager
        public ReturnClass FilesToControl(List<Item> lstNewItems)
       {
           try
           {
               String ThisisAnItemToControl = "";
               String ThisIsItsType = "";

               for (int i = 0; i < lstNewItems.Count; i++) // Loop through List with for
               {
                   ThisisAnItemToControl = lstNewItems[i].Paramater;
                   ThisIsItsType = lstNewItems[i].Type;

               }

               return new ReturnClass(1, ThisisAnItemToControl, String.Empty, null, null, null);

           }

           catch (Exception ex)
           {

               return new ReturnClass(-1, ex.Message.ToString(), ex.InnerException.ToString(), null, null, null);

           }           


       }

        }
       #endregion

Finally the definition of ReturnClass in the class ReturnClass.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.ComponentModel;
    using System.Data;
    using System.IO;
    using System.Collections;
    using System.Web;
    using Microsoft.Win32;

    namespace WCFJobsLibrary
    {
        public class ReturnClass
        {
            //private members
            private int _errorCode;
            private string _errorMessage;
            private string _exMessage;
            private ArrayList _drives;
            private string[] _folders;
            private string[] _filePaths;


            #region Constructors

            //constructor 1
            public ReturnClass()
            {

            }

            //constructor 2
            public ReturnClass(int iErr, string sErrMsg, string ExMsg, ArrayList arrDrives, string[] sfolders, string[] sFilePaths)
            {
                ErrorCode = iErr;
                ErrorMessage = sErrMsg;
                ExMessage = ExMsg;
                Drives = arrDrives;
                Folders = sfolders;
                FilePaths = sFilePaths;
            }

            #endregion

            #region methods

            //Error Code
            public int ErrorCode
            {
                get { return this._errorCode; }
                set { this._errorCode = value; }
            }

            //error message
            public string ErrorMessage
            {
                get { return this._errorMessage; }
                set { this._errorMessage = value; }
            }

            //exception message
            public string ExMessage
            {
                get { return this._exMessage; }
                set { this._exMessage = value; }
            }

            //drives
            public ArrayList Drives
            {
                get { return this._drives; }
                set { this._drives = value; }
            }

            //folders
            public string[] Folders
            {
                get { return this._folders; }
                set { this._folders = value; }
            }

            //File Paths
            public string[] FilePaths
            {
                get { return this._filePaths; }
                set { this._filePaths = value; }
            }

            #endregion

        }
    }

Upvotes: 2

Anders Abel
Anders Abel

Reputation: 69250

What's lstNewItems in your asp code?

To work it should be an Item[]. Even though you take a List<Item> in the WCF code, the default settings for proxy code generated by WCF is to use arrays for collections.

Edit

With the latest edit in place, the problem is possible to find:

The error message shows that the FilesToControl proxy method accepts an array (Item[])

Error 1 The best overloaded method match for 'test.ServiceReference1.JobsClient.FilesToControl(test.ServiceReference1.Item[])' has some invalid arguments

You pass in a List<Item>:

List<Item> lstNewItems = new List<Item>();
//....
ControlFiles_Result = Client.FilesToControl(lstNewItems);

There are three ways to fix this.

  • Change lstNewItems to be of type Item[] instead.
  • Change the settings of the service reference (which you've added to be able to call your WCF) to use List<T> as the default collection type.
  • Change the call to convert to an array.

The latter can be done through a call to ToArray:

ControlFiles_Result = Client.FilesToControl(lstNewItems.ToArray());

Upvotes: 0

Related Questions