Reputation: 2748
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
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
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.
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.
lstNewItems
to be of type Item[]
instead.List<T>
as the default collection type.The latter can be done through a call to ToArray
:
ControlFiles_Result = Client.FilesToControl(lstNewItems.ToArray());
Upvotes: 0