Dre*_*kes 8 .net generics wcf known-types
我有一个类型,我们称之为Data<TKey>.我还有一个WCF服务合同,它接受一个带有类型Wrapper属性的类型(让我们调用它)Object(原因我不会进入,这不是可选的).
[DataContract]
public class Data<TKey> { ... }
[DataContract]
public class Wrapper
{
[DataMember]
public object DataItem { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,我要送两个类IntData和LongData:
[DataContract]
public class IntData : Data<int> { /*empty*/ }
[DataContract]
public class LongData : Data<long> { /*empty*/ }
Run Code Online (Sandbox Code Playgroud)
它们都是在已知类型的配置文件中配置的.配置类似于以下内容:
<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>
Run Code Online (Sandbox Code Playgroud)
在这一点上,一切正常.
但我要添加第三个类型,我不喜欢多余的,空的.NET类IntData和LongData.他们只存在是因为......
我不知道如何在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>
Run Code Online (Sandbox Code Playgroud)
这个的正确语法是什么?
(另请注意,我不能放置[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> { ... }
Run Code Online (Sandbox Code Playgroud)
在我Name从属性中删除属性值之前发生了上述错误.希望能帮助其他人.我不知道在这种情况下哪种格式有效.这些没有:
[DataContract(Name = "Data\`1")]
[DataContract(Name = "Data{TKey}")]
Run Code Online (Sandbox Code Playgroud)
有人知道怎么做吗?
编辑2
再次感谢@baretta,他指出正确的语法实际上是:
[DataContract(Name = "Data{0}")]
Run Code Online (Sandbox Code Playgroud)
bar*_*tta 18
泛型类型可以从字符串中实例化,如果字符串遵循以下模式: 类名后跟一个"`"字符,后跟类型参数的数量(在本例中为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>
Run Code Online (Sandbox Code Playgroud)
编辑:我还可以补充一点,如果需要为类型参数指定程序集信息(虽然mscorlib中的东西不是这种情况),则使用嵌套的"[]".
<knownType type="Data`1[[System.Int32, mscorlib]], MyAssembly"/>
Run Code Online (Sandbox Code Playgroud)
编辑:您可以使用字符串格式模式自定义数据协定中泛型类型的名称.
[DataContract(Name = "Data{0}")]
public class Data<TKey>
{...}
Run Code Online (Sandbox Code Playgroud)
默认情况下,为Data <Int32>类型生成的名称类似于"DataOfInt32HJ67AK7Y",其中"HJ67AK7Y"是从字符串"urn:default"生成的哈希值,或者类的名称空间(如果有的话).但"Data {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>
Run Code Online (Sandbox Code Playgroud)
上面的配置指定Circle的泛型参数与声明的Shape类型的泛型参数相同.配置允许定义已知类型的任意复杂性.例如,如果需要将Circle <Dictionary <string,T >>定义为Shape <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>
Run Code Online (Sandbox Code Playgroud)
请注意使用配置元素"parameter",其属性为"type"和"index".
| 归档时间: |
|
| 查看次数: |
8907 次 |
| 最近记录: |