技术开发 频道

WCF中的Data Contract:对Generic的支持


   我们可以通过上面的code,注意到下面的细节:

  · Generic class Bill<THeader, TDetail>没有了,取而代之的是使用了具体OrderHeader和OrderDetial的新的非Generic class:BillOfOrderHeaderOrderDetailLZ9Dq20o。正如我们在上面所说,Neutral Contract根本就不知道Generic为何物。

  · 新的Class name的名称很难看,它有下面几个部分组成:Bill(Generic Type Name)+ Of + OrderHeader(Generic Type的第一个类型参数对应的具体类型名称)+OrderDetail(Generic Type的第二个类型参数对应的具体类型名称)+lLZ9Dq20o(Generic Type参数类型Namespace的Hash Value)。

  · 原本使用IList表示的DetailList变成了Array(public OrderDetail[] DetailList),这个将在和面的部分介绍。

   我想你也不能容忍生成的如此冗长、甚至没有太大意义的Class name。我们有办法生成一个友好的名称。那就是显示指定Data Contract的Name:

[DataContract(Name="OrderBill")] 
public class Bill<THeader, TDetail>
{
[DataMember]
public THeader Header
{ get; set; }

[DataMember]
public IList<TDetail> DetailList
{ get; set; }
}
   现在对应的Data Contract Name将变成我们指定的名称。
public partial class OrderBill : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {}
   但是上面的做法是不对的。原因很简单,如果我们在Service中添加一个处理Sales Bill的Operation(当然我们会添加两个额外的Header和Detail:SalesHeader和SalesDetail):

[ServiceContract] 
public interface IBillManager
{
[OperationContract(Name=”ProcessOrderBill”)]
void Procss(Bill<OrderHeader, OrderDetail> orderBill);

[OperationContract(Name =”ProcessSalesBill”)]
void Procss(Bill<SalesHeader, SalesDetail> salesBill);
}

   很显然,WCF需要为Order Bill和Sales Bill创建两个Data Contract,但是现在你却把他们的名称显示地限定到一个固定的名称,很显然这会造成命名的冲突。如果你通过Browser试图访问Service,你会得到如下的Error: 

The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.

0
相关文章