我的Visual Studio解决方案中有三个项目:
当我在我的测试客户端中使用我的WCF服务时,一切看起来都很棒。生成服务方法的代理,因此我可以传递具有正确类型的参数,如Core.BusinessObj
。但是,当我从Core使用相同的WCF服务时,生成的代理需要使用相同的服务方法,如下所示:ServiceProxy.BusinessObj
。这导致了一个问题,因为我想创建类型为Core.BusinessObj
的对象,并将它们传递给我的服务,无论该服务在哪里使用。我确信这与在定义所有类型的同一项目中引用我的WCF服务有关,但无法弄清楚如何正确识别名称空间。
有谁知道我做错了什么?
答案 0 :(得分:1)
你没有做错任何事 - 这就是WCF的工作方式!
构建服务时,您可以定义服务方法以及这些服务所期望的参数(及其数据类型)。这是在服务器端打包的,通常通过元数据交换(MEX)公开。
当客户端出现并为您的服务创建客户端代理时,它所依赖的只是元数据中的点点滴滴 - 服务方法的描述(名称,参数)以及对服务方法的描述XML看起来像是在客户端和服务器之间传播。
WCF中的客户端和服务器通过序列化(XML)消息相互通信 - 没有其他连接 - 没有直接链接或任何其他内容。所以客户端可以做的就是确保他根据服务元数据创建的数据类型序列化到与服务期望相同的XML中(并且他能够反序列化来自服务器的XML消息)服务器)。
客户端创建新的客户端类型,它们将具有相同的“XML足迹”(在序列化XML中具有相同的结构) - 但这就是他能做的全部。这就是为什么你得到看起来非常相似的类型 - 但它们是不同的(通常在不同的命名空间中)。这也是你不应该在服务器端数据合同中有任何功能(代码)的原因 - 你不能通过XML消息序列化功能......
现在,如果您控制通信线路的两端(服务器和客户端)并在.NET中编写它们,那么您可以使用“快捷方式”重新使用这些类型。基本上,您需要执行您所做的操作 - 将所有类型和接口放入单独的程序集(“Core”)中。接下来:之前在客户端创建WCF代理,确保客户端项目引用表示“Core”程序集。当您使用引用的“Core”程序集创建WCF客户端代理时,您可以告诉WCF“重用已引用程序集中的类型” - 如果您启用此选项(默认情况下它已启用),那么如果引用的程序集已包含一个匹配WCF客户端需求的数据类型,然后将重用该类型(来自“Core”程序集)(而不是创建一个新类型)。
WCF - 添加服务参考 - 高级选项
答案 1 :(得分:0)
确保您的Core.BusinessObj是可序列化的
(例如,假设它适用于.NET 4)
[Serializable]
public class BusinessObj
确保您的服务正常建设(没有错误)
更新服务参考(成功构建服务后)
答案 2 :(得分:0)
我按照你的描述构建了一个解决方案。它没有任何问题通过测试。 在我的解决方案中,现在有3个项目
Project Core有一个类“BusinessObj”
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Core
{
[Serializable]
public class BusinessObj
{
public int id { get; set; }
}
}
项目WCFService有一个名为“Service1”的WebService (已添加对Core的引用)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCFService
{
public class Service1 : IService1
{
public Core.BusinessObj GetBusinessObj()
{
return new Core.BusinessObj()
{
id = 1
};
}
}
}
测试项目,TestClient有一个单元测试“UnitTest1” (已添加对Core的引用) (已添加对Service1的服务引用)
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestClient.ServiceReference;
using Core;
namespace TestClient
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Service1Client ServiceProxy = new Service1Client();
BusinessObj x = ServiceProxy.GetBusinessObj();
Assert.IsTrue(x.id == 1, "Something's wrong dude!!!");
}
}
}
我认为“使用核心”;您的TestClient
缺少