我对WCF服务代理有一个小问题,其中消息包含List<string>
作为参数。
我在Visual Studio中使用“添加服务引用”来生成对我的服务的引用。
// portion of my web service message
public List<SubscribeInfo> Subscribe { get; set; }
public List<string> Unsubscribe { get; set; }
这些是我的MsgIn
为我的某个网络方法生成的属性。
我在使用ArrayOfString
时可以看到它使用List<string>
,而另一个使用List<SubscribeInfo>
- 它与我上面的原始C#对象匹配。
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)]
public System.Collections.Generic.List<DataAccess.MailingListWSReference.SubscribeInfo> Subscribe {
get {
return this.SubscribeField;
}
set {
if ((object.ReferenceEquals(this.SubscribeField, value) != true)) {
this.SubscribeField = value;
this.RaisePropertyChanged("Subscribe");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)]
publicDataAccess.MailingListWSReference.ArrayOfString Unsubscribe {
get {
return this.UnsubscribeField;
}
set {
if ((object.ReferenceEquals(this.UnsubscribeField, value) != true)) {
this.UnsubscribeField = value;
this.RaisePropertyChanged("Unsubscribe");
}
}
}
生成的ArrayOfString类看起来像这样。这是在我的代码中生成的类 - 它不是.NET类。它实际上生成了一个继承自List的类,但是没有'decency'来创建任何构造函数。
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.CollectionDataContractAttribute(Name="ArrayOfString", Namespace="http://www.example.com/", ItemName="string")]
[System.SerializableAttribute()]
public class ArrayOfString : System.Collections.Generic.List<string> {
}
问题在于我经常创建这样的信息:
client.UpdateMailingList(new UpdateMailingListMsgIn()
{
Email = model.Email,
Name = model.Name,
Source = Request.Url.ToString(),
Subscribe = subscribeTo.ToList(),
Unsubscribe = unsubscribeFrom.ToList()
});
我真的很喜欢这给我的干净的外观。
现在针对实际问题:
我无法将List<string>
分配给Unsubscribe
属性ArrayOfString
- 即使它继承自List。事实上,我似乎无法找到任何方式来分配它而无需额外的陈述。
我尝试了以下内容:
new ArrayOfString(unsubscribeFrom.ToList())
- 此构造函数不存在: - (List<string>
投射到ArrayOfString
- 失败并且“无法投射”,即使它编译得很好new ArrayOfString()
然后AddRange(unsubscribeFrom.ToList())
- 有效,但我无法在一个声明中完成所有操作ToArrayOfString(List<string>)
,它可以工作,但不是我想要的那么干净。它只对字符串执行此操作,这很烦人。
我错过了什么吗?有没有办法告诉它不要生成ArrayOfString
- 或者其他一些技巧来分配它?
答案 0 :(得分:7)
任何实现名为“Add”的方法的.NET对象都可以像数组或字典一样进行初始化。
由于ArrayOfString实现了“添加”方法,您可以像这样初始化它:
var a = new ArrayOfString { "string one", "string two" };
但是,如果你真的想根据另一个集合初始化它,你可以为它编写一个扩展方法:
public static class U
{
public static T To<T>(this IEnumerable<string> strings)
where T : IList<string>, new()
{
var newList = new T();
foreach (var s in strings)
newList.Add(s);
return newList;
}
}
用法:
client.UpdateMailingList(new UpdateMailingListMsgIn()
{
Email = model.Email,
Name = model.Name,
Source = Request.Url.ToString(),
Subscribe = subscribeTo.ToList(),
Unsubscribe = unsubscribeFrom.To<ArrayOfString>()
});
答案 1 :(得分:3)
我不想首先在服务边界上返回泛型类型。而是将取消订阅作为string[]
,将 SubscriptionInfo 作为SubscriptionInfo[]
。如有必要,可以在客户端上轻松地将数组转换为通用列表,如下所示:
Unsubscribe = new List<string>(unsubscribeFrom);
Subscribe = new List<SubscriptionInfo>(subscribeTo);
答案 2 :(得分:3)
太晚了但可以帮助将来的人......
使用svcutil并显式告知命令行util您希望代理类由 XmlSerializer 而不是DataContractSerializer(默认)序列化。这是样本:
svcutil /out:c:\Path\Proxy.cs /config:c:\Path\Proxy.config / async / serializer:XmlSerializer / namespace:*,YourNamespace http://www.domain.com/service/serviceURL.asmx
请注意,Web服务是 ASP.NET Web服务确定?!
答案 3 :(得分:1)
如果您使用VS 2008来使用服务,那么有一个简单的解决方案。
单击添加服务引用时显示的代理对话框上的“高级...”按钮。在Collection Type下拉列表中,您可以选择System.Generic.List。返回List的方法现在应该可以正常工作。
(希望这是你要求的,我有点累了,这个问题让我难以阅读。)