WCF 101 - 对象属性和KnownTypes问题

时间:2014-08-13 08:19:15

标签: c# wcf

我是Web服务的新手,我在我的wcf服务中定义了一个名为MyValue的对象属性。

数据合约类看起来像这样:

[DataContract(Namespace = Namespaces.DEFAULT_NAMESPACE)]
[KnownType(typeof(string))]
[KnownType(typeof(int))]
[KnownType(typeof(double))]
[KnownType(typeof(long))]
public class MyRequestMessage : DefaultRequestMessage
{
    [DataMember(IsRequired = true)]
    public int Id { get; set; }

    [DataMember(IsRequired = true)]
    public int Nr { get; set; }

    [DataMember(IsRequired = true)]
    public string Name { get; set; }

    [DataMember(IsRequired = true)]
    public object MyValue { get; set; }
}

在我的测试解决方案中部署服务并更新引用后,我意识到reference.cs文件看起来完全不同。

看一下生成的代码行:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="MyRequestMessage", Namespace="...")]
[System.SerializableAttribute()]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<string>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.Dictionary<string, object>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<object>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<double>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<decimal>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<int>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<bool>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<System.DateTime>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Collections.Generic.List<System.Collections.Generic.Dictionary<string, object>>))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Type))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.SystemException))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Exception))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.Reflection.MemberInfo))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.IO.FileNotFoundException))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(System.IO.IOException))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(...)]
public partial class MyRequestMessage : DefaultRequestMessage {

    [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
    public int Id { get; set; }

    [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
    public int Nr { get; set; }

    [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
    public string Name { get; set; }

    [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
    public object MyValue { get; set; }
}

在我的测试解决方案中点击F5后,我收到以下错误消息:

System.InvalidOperationException: Type cannot be added to list of known types since another type with the same data contract name is already present. If there are different collections of a particular type - for example, List<Test> and Test[], they cannot both be added as known types. Consider specifying only one of these types for addition to the known types list.

为什么那里有那么多KnownTypeAttribute?任何想法如何解决这个问题?

提前致谢

2 个答案:

答案 0 :(得分:1)

&#34;任何想法如何解决这个问题?&#34; ...既然你表示你是WCF的新手,我会提出一个相当基本的“想法”来解决这个问题;重构服务接口以消除对“对象”类型的需要。

通常,在设计WCF服务接口时,参数和返回值由客户端和服务通过共享数据协定建立并“知道”。但是,在使用DataContract参数类型定义object时,必须指定其他信息(KnownType属性),以便序列化程序能够处理数据。

如果您想继续使用“对象”参数类型,以下文章提供了全面的讨论:

http://msdn.microsoft.com/en-us/library/vstudio/ms730167(v=vs.100).aspx

答案 1 :(得分:-1)

你不能拥有一个类型为对象的DataMember - 它需要可以为WCF序列化。