我正在运行WCF服务和我工作的客户端,但是目前我已经在我的客户端中引用了该服务。
我想动态创建客户端引用。
这是我的配置文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=e77a5e561934e089" requirePermission="false" />
</configSections>
<system.serviceModel>
<services>
<!-- This section is optional with the new configuration model
introduced in .NET Framework 4. -->
<service name="Service.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://xx.xx.xx.xx:20001/Service/service" />
</baseAddresses>
</host>
<!-- this endpoint is exposed at the base address provided by host: http://xx.xx.xx.xx:20001/Service/service -->
<endpoint address="" binding="wsHttpBinding" contract="Service.IReportData" bindingConfiguration="CustomBinding" />
<!-- the mex endpoint is exposed at http://xx.xx.xx.xx:20001/Service/service/mex -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="CustomBinding" closeTimeout="00:02:00" openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:02:00" maxReceivedMessageSize="2147483647">
<security mode="None">
<transport clientCredentialType="None" />
<message establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
</DbProviderFactories>
</system.data>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
</configuration>
我一直在谷歌搜索大约一个星期,发现我在stackoverflow上找到的以下代码片段。
我找到的帖子的链接是:Configure wcf service programmatically
public virtual ChannelFactory<T> Proxy<T>(string address)
{
//Validate Address
if (string.IsNullOrEmpty(address)) throw new ArgumentNullException("Address can not be null or empty.");
//Address
EndpointAddress endpointAddress = new EndpointAddress(address);
//Binding
WSHttpBinding wsHttpBinding = new WSHttpBinding(SecurityMode.None, false);
wsHttpBinding.OpenTimeout = wsHttpBinding.CloseTimeout = new TimeSpan(0, 1, 0);
wsHttpBinding.ReceiveTimeout = wsHttpBinding.SendTimeout = new TimeSpan(0, 10, 0);
wsHttpBinding.MaxReceivedMessageSize = wsHttpBinding.MaxBufferPoolSize = 2147483647;
wsHttpBinding.BypassProxyOnLocal = wsHttpBinding.AllowCookies = wsHttpBinding.TransactionFlow = false;
wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
wsHttpBinding.TextEncoding = Encoding.UTF8;
wsHttpBinding.UseDefaultWebProxy = true;
wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
wsHttpBinding.ReaderQuotas = new XmlDictionaryReaderQuotas(); //ReaderQuotas, setting to Max
wsHttpBinding.ReaderQuotas.MaxArrayLength = wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
wsHttpBinding.ReaderQuotas.MaxStringContentLength = wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
wsHttpBinding.ReaderQuotas.MaxDepth = 2147483647;
//Create the Proxy
ChannelFactory<T> proxy = new ChannelFactory<T>(wsHttpBinding, endpointAddress);
//Sets the MaxItemsInObjectGraph, so that client can receive large objects
foreach (var operation in proxy.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior operationBehavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
//If DataContractSerializerOperationBehavior is not present in the Behavior, then add
if (operationBehavior == null)
{
operationBehavior = new DataContractSerializerOperationBehavior(operation);
operation.Behaviors.Add(operationBehavior);
}
//IMPORTANT: As 'operationBehavior' is a reference, changing anything here will automatically update the value in list, so no need to add this behavior to behaviorlist
operationBehavior.MaxItemsInObjectGraph = 2147483647;
}
return proxy;
}
当我尝试编译时,我得到两个错误:
错误1'代理&lt; ...&gt;':无法在静态类中声明实例成员
和
错误3找不到类型或命名空间名称“T”(您是否缺少using指令或程序集引用?)
为了使用ChannelFactory类,我缺少什么?
编辑:
我已将ChannelFactory更改为ChannelFactory但现在收到以下错误:
错误1'代理&lt; ...&gt;':无法在静态类中声明实例成员
答案 0 :(得分:2)
Error 1 'Proxy<...>': cannot declare instance members in a static class
查看此方法所在的类,并确保它不是static
。
Error 3 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
当您看到ChannelFactory<T>
或List<T>
等通用类的定义时,T
只是实际类型的占位符,例如List<string>
或{{1} }。从上面的代码看,我猜它是List<DateTime>
。
这是一个非常简单的客户端。我使用了在创建新的WCF应用程序项目时创建的示例服务。
ChannelFactory<IReportData>
来自public class MyServiceClient : ClientBase<IService>, IService
{
public string GetData(int value)
{
return base.Channel.GetData(value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
return base.Channel.GetDataUsingDataContract(composite);
}
}
的{{3}}:
通用的ChannelFactory类用于高级 需要创建可以的渠道工厂的方案 用于创建多个频道。
换句话说,如果您只是想创建一个客户端,那么您可能不需要使用ChannelFactory
。
实际上,我使用documentation来创建我的WCF客户端。这只适用于您对使用依赖注入和使用Castle Windsor感兴趣的情况。我强烈建议学习使用它只是因为依赖注入是一种有用的做法。但除此之外,您还可以方便地使用它来创建和部署您的客户。
结果是您的类永远不会“知道”有关WCF服务的信息。他们只知道他们正在使用ChannelFactory
。他们不知道该接口的实现是WCF客户端。在幕后,Windsor正在创建和部署客户端,在大多数情况下,唯一的配置是app.config中的单行IReportData
元素。