题
之前,我在尝试在 ASMX Web 服务和 .aspx 页面 (webclient) 之间共享类型定义时遇到了问题
据我了解该建议,可以通过将客户端中创建的对象数组复制到 ASMX 代理类定义的新对象数组来解决所产生的“问题”。
作为 C# 的菜鸟,我仍在努力完成这个简单的任务。以下是我的代码的更多部分(上一篇文章中的其他片段保持不变):
...这是我填充要传递给网络服务的“测试数据”的地方:
// create an array of MetaData objects
MetaData[] nvPairs = new MetaData[20]; // arbitrary length of 20 pairs
// create arbitrary MetaData objects in the array
nvPairs[0] = new MetaData("Grant Number", "2577-9912");
nvPairs[1] = new MetaData("OPEAnalyst", "Simpson");
...在这里,我尝试使用一个函数将 TRIMBrokerUtil 命名空间中定义的“真实”类型(由于代理而无法完全使用)“复制”到该类型的代理版本:
protected TRIMBrokerASMXProxy.ASMXProxy.MetaData[] CopyMetaData(
MetaData utilArray)
{
TRIMBrokerASMXProxy.ASMXProxy.MetaData[] outArray =
new TRIMBrokerASMXProxy.ASMXProxy.MetaData[utilArray.Name.Length];
int i;
for (i = 0; i < utilArray.Name.Length; i++)
{
outArray[i].Name = utilArray.Name;
outArray[i].Value = utilArray.Value;
}
return outArray;
}
...然后这是我尝试调用该函数的地方(编译器在这一行标记了 2 个错误:
TRIMBrokerASMXProxy.ASMXProxy.MetaData[] kvData =
CopyMetaData(metaDataArray);
下面的两个编译错误都指向同一行:
错误 1 “_Default.CopyMetaData(TRIMBrokerUtil.MetaData)”的最佳重载方法匹配有一些无效参数
错误 2 参数“1”:无法从“TRIMBrokerUtil.MetaData[]”转换为“TRIMBrokerUtil.MetaData”
我很接近吗?
解决方案
您已将参数声明为 MetaData
而不是 MetaData[]
- 换句话说,它不是一个数组。然后你正在使用 utilArray.Name
相当多,但不清楚为什么。
我怀疑你实际上想要:
protected TRIMBrokerASMXProxy.ASMXProxy.MetaData[]
CopyMetaData(MetaData[] utilArray)
{
TRIMBrokerASMXProxy.ASMXProxy.MetaData[] outArray =
new TRIMBrokerASMXProxy.ASMXProxy.MetaData[utilArray.Length];
for (int i = 0; i < utilArray.Length; i++)
{
outArray[i] = new TRIMBrokerASMXProxy.ASMXProxy.MetaData();
outArray[i].Name = utilArray[i].Name;
outArray[i].Value = utilArray[i].Value;
}
return outArray;
}
顺便说一句,您可能想考虑 using
指令使其更易于阅读:
using ProxyMetaData = TRIMBrokerASMXProxy.ASMXProxy.MetaData;
...
protected ProxyMetaData[] CopyMetaData(MetaData[] utilArray)
{
ProxyMetaData[] outArray = new ProxyMetaData[utilArray.Length];
for (int i = 0; i < utilArray.Length; i++)
{
outArray[i] = new ProxyMetaData();
outArray[i].Name = utilArray[i].Name;
outArray[i].Value = utilArray[i].Value;
}
return outArray;
}
另一种选择是 Array.ConvertAll
:
ProxyMetaData[] output = Array.ConvertAll(input,
metaData => new ProxyMetaData(metaData.Name, metaData.Value));
如果您不使用 C# 3,则可以使用匿名方法。如果 ProxyMetaData
没有合适的构造函数,而你 是 使用 C# 3,您可以使用对象初始值设定项:
ProxyMetaData[] output = Array.ConvertAll(input,
metaData => new ProxyMetaData { metaData.Name, metaData.Value });
如果您受困于 C# 2 并且没有合适的构造函数,那么:
ProxyMetaData[] output = Array.ConvertAll(input, delegate(MetaData metaData)
{
ProxyMetaData proxy = new ProxyMetaData();
proxy.Name = metaData.Name;
proxy.Value = metaData.Value;
});
我 思考 这涵盖了所有基础:)
其他提示
我只想使用 LINQ 来做到这一点:
TRIMBrokerASMXProxy.ASMXProxy.MetaData[] kvData =
metaDataArray.Select(d =>
new TRIMBrokerASMXProxy.ASMXProxy.MetaData(
d.Name, d.Value)).ToArray();
此外,如果您使用 .NET 3.5,则意味着您也可以使用 WCF,这就是您应该用来生成代理的工具。您可以将 TRIMBrokerASMXProxy.ASMXProxy.MetaData 类型归为 DataContract 属性,并将成员序列化为 DataMember 属性。然后,您将能够使用实际类型定义合约,而根本不必执行转换。
您还可以使用Array.ConvertAll。我知道您对此比较陌生,所以让我尝试解释一下。它有 2 个通用参数。第一个是它想要转换的数组的类型(我们称之为 I)。第二个是你想要转换的类型(我们称之为 O)。它接受 I 类型的数组并返回 O 类型的数组。第二个参数是 Converter 委托。应用命名,我们就得到了它的签名。
delegate O Converter(I input);
委托的主体必须包含执行转换所需的代码。在 ConvertAll 函数内部,代码迭代输入数组中的每个值,然后传递给委托。然后,委托返回的值被存储到输出数组中。所有值转换后,输出数组将返回给用户。
using ProxyMetaData = TRIMBrokerASMXProxy.ASMXProxy.MetaData;
ProxyMetaData[] convertedArray = Array.ConvertAll<MetaData, ProxyMetaData>(utilArray,
delegate(MetaData metaData)
{
ProxyMetaData returnValue = new ProxyMetaData();
returnValue.Name = metaData.Name;
returnValue.Value = metaData.Value;
return returnValue;
});