我有一个客户端 - 服务器应用程序,其中一部分通过WCF(netTcp绑定)相互“交谈”。
我有我的DataContract,它有一个第三方类的字段:
[Serializable]
public class MyResult{
public ThirdPartyResult Result {get;set;}
/* other fields */
}
使用反射我看到了:
[Serializable]
public class ThirdPartyResult {
private IList result;
public IList Result
{
get { return result ?? (result = new ArrayList());}
}
}
从客户端调用服务器时,我在服务器上有result
为ArrayList
。在客户端之后,result
字段变为固定大小的数组。
我没有使用添加服务参考,但我使用程序集共享而只是
ChannelFactory<IMyContract>.CreateChannel(new NetTcpBinding("Configuration.Name"), address);
更新服务合约
[ServiceContract]
[ServiceKnownType(typeof(ArrayList))]
[ServiceKnownType(typeof(ThirdPartyResult))]
public interface IMyContract
{
MyResult GetResult();
}
现在的问题是:
如何告诉WCF使用ArrayList
代替Array
?
我提出了一个非常糟糕的解决方案(从我的角度来看)
通常我希望保留ArrayList
以便能够向其添加项目。最后我想出了下面的解决方案。是的,我知道,这是完全糟糕的,这就是为什么我还在寻找更好的变体。
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);
答案 0 :(得分:1)
在Visual Studio中创建新的服务引用(或配置现有引用)时,有一个类似“将数组反序列化”的属性,您可以选择数组/列表/等。您可以查看生成的代码并更改代码以实现您的目标。
答案 1 :(得分:1)
请参阅以下内容:
WCF: Serializing and Deserializing generic collections
这解决了我的问题:私有成员和自定义属性方法都适用于我。
[DataMember]
private List<Person> members = new List<Person>();
或者将属性更改为:
[DataMember]
private Iist<Person> members = new Iist<Person>();
[DataMember()]
public IList<Person> Feedback {
get { return m_Feedback; }
set {
if ((value != null)) {
m_Feedback = new List<Person>(value);
} else {
m_Feedback = new List<Person>();
}
}
}
答案 2 :(得分:0)
最终,您的合同中不包含任何可以选择任何特定实施的信息。解决这个问题的最佳方法是:使result
输入良好,可能为ArrayList
:
private ArrayList result;
public IList Result {
get { return result ?? (result = new ArrayList());}
}
个人我希望看到List<T>
与[DataContract]
/ [DataMember]
等,但是......
答案 3 :(得分:0)
如果没有别的话我会写一个扩展类来扩展ThirdPartyResult
public static class ThirdPartyResultExtension
{
public static ArrayList ResultsAsArrayList(this ThirdPartyResult d)
{
ArrayList list = new ArrayList();
list.AddRange(d.Result);
return list;
}
}
public class ThirdPartyResult
{
private IList result;
public IList Result
{
get { return result ?? (result = new ArrayList()); }
}
}
并像
一样使用它 ThirdPartyResult r;
ArrayList arrlist = r.ResultsAsArrayList();