WCF泛型-为什么DataContract和CollectionDataContract允许格式化命名,但不允许DataMember、OperationContract或ServiceContract?

WCF泛型-为什么DataContract和CollectionDataContract允许格式化命名,但不允许DataMember、OperationContract或ServiceContract?,wcf,generics,wsdl,xsd,operationcontract,Wcf,Generics,Wsdl,Xsd,Operationcontract,基本上正如标题所说: [DataContract(Name = "{0}Item")] //This will format properly public class GenericItem<T> { [DataMember(Name = "The{0}")] //This will NOT format properly public T TheItem { get; set; } } [CollectionDataContract(Name = "{0}Ite

基本上正如标题所说:

[DataContract(Name = "{0}Item")] //This will format properly
public class GenericItem<T>
{
    [DataMember(Name = "The{0}")] //This will NOT format properly
    public T TheItem { get; set; }
}

[CollectionDataContract(Name = "{0}Items")] //This will format properly
public SpecialCollection<T> : Collection<T> { }

[ServiceContract(Name = "{0}Service")] //This will NOT format properly
public interface IGenericService<T>
{
    [OperationContract(Name = "Get{0}")] //This will NOT format properly
    GenericItem<T> Get<T>();
}
再说一遍,为什么?显然,我在这里声明了一个具体的Foo类型,这意味着IGenericService是一个IGenericService,那么既然OperationContract名称知道类型,那么它不应该格式化吗


更新:

我只记得为什么我对不能使用通用格式的服务合同感到不安。。。当我实现服务时,我会给它一个具体的类型

//See! I gave it a concrete type to go by!
[ServiceBehavior(...)]
public class MyService : IGenericService<Foo> { ... }
//看!我给了它一个具体的类型去通过!
[服务行为(…)]
公共类MyService:IGenericService{…}

我为此创建了一个请求。如果您想将此功能用于其他属性,请向上投票

读一下:

基本上,似乎命名系统最初设计时没有能够格式化名称,但最终DataContract命名系统(因为散列)惹恼了足够多的人,他们添加了格式化名称的功能

编辑:

“但是,可能有理由更改此默认名称。一个原因是允许现有类型处理必须符合现有数据协定的数据。例如,存在一个名为Person的类型,但XML模式中包含的数据契约要求名称为Customer。可以通过将属性值设置为Customer来满足合同

第二个原因是允许生成作为类型名无效的名称。例如,如果数据协定要求的名称不允许作为类型名称,请将属性值设置为不允许的名称。例如,字符串“$value”不允许作为类型名,但允许作为名称属性值。”

资料来源:


我的猜测是,没有出现这样的需要更改其他人(包括OperationContract、ServiceContract等)的默认名称的情况。 在
System.Runtime.Serialization.DataContract
中,它通过执行以下操作来建立名称:

private static XmlQualifiedName GetDCTypeStableName(Type type, DataContractAttribute dataContractAttribute)
{
  string localName;
  if (dataContractAttribute.IsNameSetExplicit)
  {
    string str = dataContractAttribute.Name;
    if (str == null || str.Length == 0)
    {
       ...
    }
    else
    {
      if (type.IsGenericType && !type.IsGenericTypeDefinition)
        str = DataContract.ExpandGenericParameters(str, type);
      localName = DataContract.EncodeLocalName(str);
    }
  }
因此它显式地构建了通用名称。 对于ServiceContract内容,它在
System.ServiceModel.Description.TypeLoader
System.ServiceModel.Description.NamingHelper
中处理,并且不处理泛型类型(最后我看到的不是这样)


所以我猜,由于这些契约来自不同的程序集和名称空间,它们可能一开始就由不同的团队实现。

我读到了。它从DataContract的角度解释了一些事情,但没有说明为什么其他契约不固定以允许格式化和泛型。+1只是因为我不知道在任何情况下都可以这样做。如果我不得不猜测的话,我会说MS在定义泛型类型并需要区分的两个地方实现了它。例如,你不能有一个
列表
和一个
列表
都有一个数据约定名称“List”“因此,他们必须这样做,以使WCF在内部发挥作用。在Reflector或任何工具中浏览代码,看看他们在哪里实现了这一点,这将是很有趣的。任何读取
DataContract
DataCollectionContract
属性的类都必须与读取其他属性的类不同。这很有意义。。。第一队决定为命名付出额外的努力,第二队没有。。。想想看。。。将通用命名添加到下一个WCF的愿望列表中。叹息
private static XmlQualifiedName GetDCTypeStableName(Type type, DataContractAttribute dataContractAttribute)
{
  string localName;
  if (dataContractAttribute.IsNameSetExplicit)
  {
    string str = dataContractAttribute.Name;
    if (str == null || str.Length == 0)
    {
       ...
    }
    else
    {
      if (type.IsGenericType && !type.IsGenericTypeDefinition)
        str = DataContract.ExpandGenericParameters(str, type);
      localName = DataContract.EncodeLocalName(str);
    }
  }