我有一个WCF主机,如下所示:
[ServiceContract]
public interface IMountToOs
{
[OperationContract]
char GetMountDriveLetter();
[OperationContract]
MyTestClass MyTest();
}
public class MyTestClass
{
public string A { get; set; }
public string B { get; set; }
}
客户
private IMountToOs _proxy;
public IMountToOs Proxy
{
get
{
if (_proxy == null)
{
NetTcpBinding binding = new NetTcpBinding();
binding.MaxReceivedMessageSize = 2147483647;
binding.OpenTimeout = TimeSpan.FromMilliseconds(50000);
EndpointAddress address = new EndpointAddress("net.tcp://localhost:1234/MountToOsHost");
//_proxy = new MountToOsClient(binding, address);
ChannelFactory<IMountToOs> factory = new ChannelFactory<IMountToOs>(binding);
_proxy = factory.CreateChannel(address);
}
return _proxy;
}
}
虽然我可以访问
MessageBox.Show("Okay - " + Proxy.GetMountDriveLetter());
我不能调用此方法:
MessageBox.Show("Okay - " + Proxy.MyTest().A);
完整的扩展不起作用。但仅在扩展中使用它时。即使我在扩展的第一行插入消息框,也不会命中。我不知道为什么。它似乎运行了预检查并找到被拒绝的自定义类的调用...... 如果我使用wform左右,则没有问题。
.net 3.5
奇怪的是,我有一个断点和主机方的消息。所以我看到该方法没有被调用
更新现在我在扩展的加载方法中移动了 wcf 调用并得到一个异常:
系统。缺少方法异常: 找不到方法: "Contracts.Interfaces.MyTestClass Contracts.Interfaces.IMountToOs.MyTest()".
我的winform 测试和此扩展使用相同的接口,因此该方法应该从两者中知道。 没有合同过时
根据我在这里和帖子评论中发现的内容:"要使用客户端通道工厂方法创建动态服务代理,您将需要服务的数据合同。如果您没有数据合同,但有服务 URL,则可以使用反射在运行时创建代理并调用服务方法。
似乎MyTestClass类型在客户端是未知的,所以我认为您可以使用反射,或者在客户端和服务器之间共享类,或者更简单的是,使用datacontract属性。
另外,在MSDN上发现了类似以下内容的内容:
"什么时候使用代理?
我们使用 svcutil.exe 创建代理。此工具的输出提供代理类,并对应用程序配置文件进行相应的更改。如果您知道某个服务将被多个应用程序使用,或者该服务足够通用,可以在多个位置使用,则需要继续使用生成的代理类。我们在 WCF 中使用代理,以便能够与客户共享服务协定和实体。代理有几个限制,例如它们需要有 get 和 set ,构造器不能公开,服务合约以外的方法不能公开,代码重复,每次我们添加/修改服务合约/数据合约/消息合约时,我们都需要为客户端重新生成代理。
何时使用通道工厂
另一种选择是使用 ChannelFactory 类在客户端和服务之间构造通道,而无需代理。在某些情况下,您可能具有与客户端应用程序紧密绑定的服务。在这种情况下,直接引用接口 DLL 并使用 ChannelFactory 使用该 DLL 调用您的方法是有意义的。ChannelFactory 路由的一个显著优势是,它使您可以访问使用 svcutil.exe..
何时使用 ChannelFactory 与 Proxy 类?
如果客户端代码由您控制,并且您希望与客户端共享的不仅仅是服务协定,例如与实体关联的一些实用程序方法,并使客户端和服务代码更紧密地绑定,则DLL非常有用。如果您知道您的实体不会发生太大变化并且客户端代码较少,则 DLL 将比代理更好地工作。如果服务的客户端位于系统外部(例如 API),则使用代理是有意义的,因为它通过提供代码文件而不是 DLL 使共享协定变得更加容易。
我们看不到类 MountToOsClient: IMountToOs所以我们只能假设它没问题。
[DataContract] // Missing
public class MyTestClass
{
[DataMember] // Missing
public string A { get; set; }
[DataMember] // Missing
public string B { get; set; }
}
如果没有这些属性,MountToOsClient 将无法公开 Mytestclass。