I have a client-server application, parts of which "talk" to each other through WCF (netTcp binding).
I have my DataContract, which has 1 field of a 3rd party class:
[Serializable]
public class MyResult{
public ThirdPartyResult Result {get;set;}
/* other fields */
}
Using reflection i see this:
[Serializable]
public class ThirdPartyResult {
private IList result;
public IList Result
{
get { return result ?? (result = new ArrayList());}
}
}
When calling the server from client I have the result
as ArrayList
on server. After it comes to client the result
field becomes a fixed size array.
I didn't use Add service reference, but i use assembly sharing and just do
ChannelFactory<IMyContract>.CreateChannel(new NetTcpBinding("Configuration.Name"), address);
UPDATE: the service contract
[ServiceContract]
[ServiceKnownType(typeof(ArrayList))]
[ServiceKnownType(typeof(ThirdPartyResult))]
public interface IMyContract
{
MyResult GetResult();
}
Now the question:
How can I tell WCF to use ArrayList
instead of Array
?
I came up with a very bad solution (from my point of view)
Generally I wanted an ArrayList
to be preserved to be able to add items to it. Finally I came up with the solution below. Yes, I know, this is completely bad, and that's why I'm still looking for some better variant.
if (thirdParty.Results != null && thirdParty.Results.IsFixedSize)
{
var results = new ArrayList(thirdParty.Results);
// Finding result by ReferenceEquals to not be tight to private variable name
var resultsField = thirdParty.GetType()
.GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic)
.Where(f => ReferenceEquals(f.GetValue(thirdParty), thirdParty.Results))
.FirstOrDefault();
if (resultsField != null)
resultsField.SetValue(thirdParty, results);
}
thirdParty.AddResult(otherChild);