我有一个类型,我们称之为 Data<TKey>. 。我还有一个接受类型的 WCF 服务合约(我们称其为 Wrapper) 具有类型属性 Object (由于我不会详细讨论的原因,这不是可选的)。

[DataContract]
public class Data<TKey> { ... }

[DataContract]
public class Wrapper
{
    [DataMember]
    public object DataItem { get; set; }
}

现在我正在发送两节课 IntDataLongData:

[DataContract]
public class IntData : Data<int> { /*empty*/ }

[DataContract]
public class LongData : Data<long> { /*empty*/ }

它们都在已知类型配置文件中配置。配置类似于这样:

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
        <add type="Wrapper, TheirAssembly">
          <knownType type="IntData, MyAssembly"/>
          <knownType type="LongData, MyAssembly"/>
        </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>

至此,一切正常。

但我即将添加第三种类型,并且我不喜欢拥有不必要的空 .NET 类 IntDataLongData. 。它们的存在只是因为...

我不知道如何在 WCF 配置中指定泛型类型!

我想做这样的事情,但不知道确切的语法。

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
        <add type="Wrapper, TheirAssembly">
          <!-- this syntax is wrong -->
          <knownType type="Data{System.Int32}, MyAssembly"/>
          <knownType type="Data{System.Int64}, MyAssembly"/>
        </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>

正确的语法是什么?

(还要注意,我不能把 [KnownType(...)] 属性上 Wrapper 因为这不是我的类型。配置似乎是唯一的方法。)

编辑

@baretta 的回答效果很好。但请注意,最初我收到此错误:

类型“MyAssembly.Data`1[System.Int64]”无法添加到已知类型列表,因为另一个类型“MyAssembly.Data`1[System.Int32]”具有相同的数据协定名称“http://www.mycompany.com/MyAssembly:数据' 已经存在。

我在原来的问题中没有提到它,但我的类型有一个明确的数据契约名称。像这样的东西:

[DataContract(Name = "Data")]
public class Data<TKey> { ... }

直到我删除了上面的错误 Name 来自属性的属性值。希望对其他人也有帮助。我不知道在这种情况下什么格式有效。这些没有:

[DataContract(Name = "Data\`1")]
[DataContract(Name = "Data{TKey}")]

有人知道怎么做吗?

编辑2

再次感谢@baretta,他指出正确的语法实际上是:

[DataContract(Name = "Data{0}")]
有帮助吗?

解决方案

一个通用类型是从字符串实例化,如果字符串遵循以下模式: 类名,后跟一个“`”字符,随后的类型参数的数量(在这种情况下,它1),接着于“[]”包围的类型参数,并且使用逗号作为类型参数分离器

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
        <add type="Wrapper, TheirAssembly">
          <!-- this syntax is all good -->
          <knownType type="Data`1[System.Int32], MyAssembly"/>
          <knownType type="Data`1[System.Int64], MyAssembly"/>
        </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>

编辑:我还可以补充的是,如果组件信息需要为类型参数中指定(althoug它并不适合在mscorlib程序的东西的情况下),则嵌套“[]”被用来

<knownType type="Data`1[[System.Int32, mscorlib]], MyAssembly"/>

编辑:您可以自定义泛型类型的数据协定名称,使用字符串格式模式

[DataContract(Name = "Data{0}")]
public class Data<TKey>
{...}

默认情况下,对于数据<的Int32>类型产生的名字是类似“DataOfInt32HJ67AK7Y”,其中“HJ67AK7Y” 从该串产生的哈希“瓮:默认”,或者你的类的命名空间,如果您有任何。但 “数据{0}” 会给它取名为 “DataInt32”。

更多此处。看看在“自定义数据协定名称为通用类型”部分下的页面。

其他提示

这里 ...

  

已知   类型也可以在配置定义为   如下所示。

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
         <add type="MyCompany.Library.Shape`1,
              MyAssembly, Version=2.0.0.0, Culture=neutral,
              PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
            <knownType type="MyCompany.Library.Circle`1,
                       MyAssembly, Version=2.0.0.0, Culture=neutral,
                       PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
                    <parameter index="0"/>
            </knownType>
         </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>
  

上面的配置指定了   为圆泛型参数是   相同的泛型参数   声明类型形状。该配置允许   已知类型的定义   任意复杂。例如,如果   它需要定义   圆<字典<串,T >>作为   已知类型的形状(当然这的   是纯学术的),它可以作为完成   如下:

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
         <add type="MyCompany.Library.Shape`1,
              MyAssembly, Version=2.0.0.0, Culture=neutral,
              PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
            <knownType type="MyCompany.Library.Circle`1,
                       MyAssembly, Version=2.0.0.0, Culture=neutral,
                       PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
                   <parameter type="System.Collections.Generic.Dictionary`2">
                      <parameter type="System.String"/>
                      <parameter index="0"/>
                   </parameter>                
            </knownType>
         </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>
  

请注意使用config元素   “参数”与属性“类型”   和“索引”。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top