ServiceContract中层次结构中的通用接口

时间:2015-11-17 12:00:58

标签: c# wcf generics

我有一个通用界面:

[ServiceContract]
public interface IGenericDataRepository<T> where T : class
{
    [OperationContract]
    IList<T> GetAll(params Expression<Func<T, object>>[] navigationProperties);

    [OperationContract]
    IList<T> GetList(Func<T, bool> where, params Expression<Func<T, object>>[] navigationProperties);

    [OperationContract]
    T GetSingle(Func<T, bool> where, params Expression<Func<T, object>>[] navigationProperties);

    [OperationContract]
    void Add(params T[] items);

    [OperationContract]
    void Update(params T[] items);

    [OperationContract]
    void Remove(params T[] items);
}

哪个应该在WCF服务中使用,如下所示:

[ServiceContract]
public interface ICustomerService : IGenericDataRepository<Customer>
{
    [OperationContract]
    Customer GetCustomers();
}

该服务通过以下代码行公开:

Uri baseHttpAddress = new Uri("http://localhost:9999/CustomerService");
ServiceHost customerServiceHost = new ServiceHost(typeof(CustomerService), baseHttpAddress);
customerServiceHost.AddServiceEndpoint(typeof(ICustomerService), new WSHttpBinding(), "");

 ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior { HttpGetEnabled = true };
 ServiceDebugBehavior serviceDebugBehavior = new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true};    customerServiceHost.Description.Behaviors.Add(serviceMetadataBehavior);

  customerServiceHost.Open();

但是,这似乎不起作用。在ServiceConrtacts的层次结构中是否不可能有通用接口?我无法找到有关它的一些信息。

问题是,当我想将其添加为服务引用时,我无法连接到服务 - 通过使用WCF TestClient,我得到以下异常:

Error: Cannot obtain Metadata from http://localhost:9999/CustomerService If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.  For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error    URI: http://localhost:9999/CustomerService    Metadata contains a reference that cannot be resolved: 'http://localhost:9999/CustomerService'.    <?xml version="1.0" encoding="utf-16"?><Fault xmlns="http://www.w3.org/2003/05/soap-envelope"><Code><Value>Sender</Value><Subcode><Value xmlns:a="http://schemas.xmlsoap.org/ws/2005/02/sc">a:BadContextToken</Value></Subcode></Code><Reason><Text xml:lang="de-DE">The message could not be processed. This is most likely because the action 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.</Text></Reason></Fault>HTTP GET Error    URI: http://localhost:9999/CustomerService    There was an error downloading 'http://localhost:9999/CustomerService'.    The request failed with the error message:--<HTML><HEAD><STYLE type="text/css">#content{ FONT-SIZE: 0.7em; PADDING-BOTTOM: 2em; MARGIN-LEFT: 30px}BODY{MARGIN-TOP: 0px; MARGIN-LEFT: 0px; COLOR: #000000; FONT-FAMILY: Verdana; BACKGROUND-COLOR: white}P{MARGIN-TOP: 0px; MARGIN-BOTTOM: 12px; COLOR: #000000; FONT-FAMILY: Verdana}PRE{BORDER-RIGHT: #f0f0e0 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #f0f0e0 1px solid; MARGIN-TOP: -5px; PADDING-LEFT: 5px; FONT-SIZE: 1.2em; PADDING-BOTTOM: 5px; BORDER-LEFT: #f0f0e0 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #f0f0e0 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e5e5cc}.heading1{MARGIN-TOP: 0px; PADDING-LEFT: 15px; FONT-WEIGHT: normal; FONT-SIZE: 26px; MARGIN-BOTTOM: 0px; PADDING-BOTTOM: 3px; MARGIN-LEFT: -30px; WIDTH: 100%; COLOR: #ffffff; PADDING-TOP: 10px; FONT-FAMILY: Tahoma; BACKGROUND-COLOR: #003366}.intro{MARGIN-LEFT: -15px}</STYLE><TITLE>Service</TITLE></HEAD><BODY><DIV id="content"><P class="heading1">Service</P><BR/><P class="intro">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 SDK documentation and inspect the server trace logs.</P></DIV></BODY></HTML>--.

非常感谢!

2 个答案:

答案 0 :(得分:2)

您无法在WCF中使用泛型。主要原因是因为WCF要交换消息。

现在您可以使用known type而不是T。

的基础对象

您也无法通过服务传递函数指针,因为它们无法序列化。请记住,序列化的经验法则是实现必须具体。

[DataContract]
[KnownType(typeOf(Customer)]
public abstract class GenericType
{
}

[DataContract]
public class Customer : GenericType
{
}

现在我会重新考虑你的设计。请记住,WCF是您需要对其进行处理的服务。您感觉到的界面就像是直接与数据存储对话的东西。您可能需要一层前面的图层。

答案 1 :(得分:1)

错误

  

“元数据包含无法解析的引用”

root子句System.Linq.Expressions.Expression类不是Serializable。 如果您删除那些包含FuncExpression参数的方法,则会有效。

您必须实现自己的查询类或使用 wcf data services