I have a very vague understanding of WCF but after a bit of research I figured out that WCF does not like handling custom objects. I am looking for a feasible workaround.
This is my objective. I aim to create a WCF service that accepts certain values from a client machine, sends them to the server where it invokes an R instance and executes a set of DataFrame transformations and return the resulting DataFrame. DataFrames seem to be in the format of a vector / 2D array. The error I am getting is: the operation is not supported in wcf because it uses type system.object[][]
see example code below -
public string R_to_SQLstring_InsertTable(string table_name, DataFrame Table)
{
string query2 = "INSERT INTO table_name (";
for (int x = 0; x < Table.ColumnCount; x++)
{
if (x == (Table.ColumnCount) - 1)
{
query2 = query2 + Table.Names[x] + "";
}
else
{
query2 = query2 + Table.Names[x] + ", ";
}
}
query2 = query2 + ") Values (";
for (int count1 = 0; count1 < Table.RowCount; count1++)
{
for (int count2 = 0; count2 < Table.ColumnCount; count2++)
{
if (count2 == (Table.ColumnCount) - 1)
{
query2 = query2 + " " + Table[count2][count1];
}
else
{
query2 = query2 + " " + Table[count2][count1] + ",";
}
}
if (count1 == (Table.RowCount) - 1)
{
query2 = query2 + ");";
}
else
{
query2 = query2 + "), (";
}
}
return query2;
}
public DataFrame R_Transformation_MergeTable(string tableloca1, string tableloca2)
{
StartupParameter rinit = new StartupParameter();
rinit.Quiet = true;
rinit.RHome = @"C:\Program Files\R\R-3.4.4\";
rinit.Home = @"C:\R";
REngine.SetEnvironmentVariables();
REngine engine = REngine.GetInstance(null, true, rinit);
try
{
engine.Evaluate("Table1 <- read.csv(file='" + tableloca1+")");
engine.Evaluate("Table2 <- read.csv(file='" + tableloca2 + ")");
DataFrame Table = engine.Evaluate("Merge <- merge(Table1,Table2)").AsDataFrame();
return Table;
}
catch (Exception x)
{
throw new Exception("Please Upload .CSV file");
}
}
I pass generic objects over WCF by manually serializing them to byte[] and passing in the type definition (as a string, Type cannot go over WCF either) then casting it back to the proper type using reflection. Given an object[][], you may have to iterate over it and use reflection to determine the type of each entry for this purpose though.
A better technique if possible would be to cast the objects to a data contract type before sending them over the service.