我可以阻止我的WCF生成ArrayOfString而不是string []或List <string> </string>

时间:2009-02-03 03:35:37

标签: wcf

我对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()) - 此构造函数不存在: - (
  • 更改代码生成器使用的数组类型 - 不起作用 - 它总是给我ArrayOfString(!?)
  • 尝试将List<string>投射到ArrayOfString - 失败并且“无法投射”,即使它编译得很好
  • 创建new ArrayOfString()然后AddRange(unsubscribeFrom.ToList()) - 有效,但我无法在一个声明中完成所有操作
  • 创建一个转换函数ToArrayOfString(List<string>),它可以工作,但不是我想要的那么干净。

它只对字符串执行此操作,这很烦人。

我错过了什么吗?有没有办法告诉它不要生成ArrayOfString - 或者其他一些技巧来分配它?

4 个答案:

答案 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的方法现在应该可以正常工作。

(希望这是你要求的,我有点累了,这个问题让我难以阅读。)