无配置实现WCF访问

场景:多个相同的Windows服务(部署在不同的服务器上, 仅配置文件不同)需要附加WCF服务, 而网站在访问这些类似的WCF服务时, 不知道其明确地址所以无法直接引用。于是, 无配置便成了必然的选择!


下面是无配置访问WCF服务的简单Demo:

直接下载源码: 点击打开链接


1. 解决方案基本结构:



2. 代码:

2.1 ITest.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace CommonLib
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        int Add(int a, int b);
    }
}

2.2 Service1.svc.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using CommonLib;

namespace WcfService1
{
    // 注意: 如果更改此处的类名“Service1”,也必须更新 Web.config 和关联的 .svc 文件中对“Service1”的引用。
    public class Service1 : ITest
    {
        #region ITest 成员

        public int Add(int a, int b)
        {
            return a + b;
        }

        #endregion
    }
}

2.3 Web.config

<?xml version="1.0"?>
<!--
    注意: 除了手动编辑此文件以外, 
    还可以使用 Web 管理工具来配置应用程序的设置。
    可以使用 Visual Studio 中的“网站”->“Asp.Net 配置”选项。
    设置和注释的完整列表在 
    machine.config.comments 中,该文件通常位于 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
	<configSections>
		<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
			<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
				<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
				<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
					<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
					<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
					<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
					<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
				</sectionGroup>
			</sectionGroup>
		</sectionGroup>
	</configSections>
	<appSettings/>
	<connectionStrings/>
	<system.web>
		<!--
            设置 compilation debug="true" ,将调试符号 
            插入已编译的页面中。但由于这会影响性能, 
           因此请只在开发过程中 
            将此值设置为 true。
        -->
		<compilation debug="true">
			<assemblies>
				<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
				<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			</assemblies>
		</compilation>
		<!--
            通过 <authentication> 节可以配置
            ASP.NET 使用的安全身份验证 
            模式,以标识传入的用户。 
        -->
		<authentication mode="Windows"/>
		<!--
            通过 <customErrors> 节可以配置在执行请求过程中出现未处理错误时, 
           应执行的操作。 
            具体说来,开发人员通过该节 
            可以配置要显示的 html 错误页 
            以代替错误堆栈跟踪。

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
		<pages>
			<controls>
				<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			</controls>
		</pages>
		<httpHandlers>
			<remove verb="*" path="*.asmx"/>
			<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
		</httpHandlers>
		<httpModules>
			<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</httpModules>
	</system.web>
	<system.codedom>
		<compilers>
			<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
				<providerOption name="CompilerVersion" value="v3.5"/>
				<providerOption name="WarnAsError" value="false"/>
			</compiler>
		</compilers>
	</system.codedom>
	<system.web.extensions>
		<scripting>
			<webServices>
				<!--
              取消对此节的注释以启用身份验证服务。如果适用,请加入 
              requireSSL="true"。

          <authenticationService enabled="true" requireSSL = "true|false"/>
          -->
				<!--
              取消对这些行的注释,以启用配置文件服务并选择 
              可在 ASP.NET AJAX  应用程序中检索和修改的
              配置文件属性。

          <profileService enabled="true"
                          readAccessProperties="propertyname1,propertyname2"
                          writeAccessProperties="propertyname1,propertyname2" />
          -->
				<!--
              取消对此节的注释,以启用角色服务。

          <roleService enabled="true"/>
          -->
			</webServices>
			<!--
        <scriptResourceHandler enableCompression="true" enableCaching="true" />
        -->
		</scripting>
	</system.web.extensions>
	<!--
        在 Internet 信息服务 7.0 下,运行 ASP.NET AJAX 要求 
      system.webServer 节。这在以前版本的 IIS 中并非必需。
    -->
	<system.webServer>
		<validation validateIntegratedModeConfiguration="false"/>
		<modules>
			<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</modules>
		<handlers>
			<remove name="WebServiceHandlerFactory-Integrated"/>
			<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</handlers>
	</system.webServer>
	<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="NoneSecurity"
          maxBufferPoolSize="12000000" maxReceivedMessageSize="12000000" useDefaultWebProxy="false">
          <readerQuotas maxStringContentLength="12000000" maxArrayLength="12000000"/>
          <security mode="None"  />
        </binding>
      </wsHttpBinding>
    </bindings>
		<services>
			<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
				<!-- Service Endpoints -->
				<endpoint address="" binding="wsHttpBinding" bindingConfiguration="NoneSecurity" contract="CommonLib.ITest">
					<!-- 
              部署时,应删除或替换下列标识元素,以反映
              在其下运行部署服务的标识。删除之后,WCF 将
              自动推导相应标识。
          -->
					<identity>
						<dns value="localhost"/>
					</identity>
				</endpoint>
				<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
			</service>
		</services>
		<behaviors>
			<serviceBehaviors>
				<behavior name="WcfService1.Service1Behavior">
					<!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点-->
					<serviceMetadata httpGetEnabled="true"/>
					<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息-->
					<serviceDebug includeExceptionDetailInFaults="false"/>
				</behavior>
			</serviceBehaviors>
		</behaviors>
	</system.serviceModel>
</configuration>

2.3 InvokeContent.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.ServiceModel.Channels;


/// <summary>
/// 动态调用WCF的工具类库
/// </summary>
public class InvokeContext
{

    #region Wcf服务工厂
    public static T CreateWCFServiceByURL<T>(string url)
    {
        return CreateWCFServiceByURL<T>(url, "wsHttpBinding");
    }


    public static T CreateWCFServiceByURL<T>(string url, string bing)
    {
        if (string.IsNullOrEmpty(url)) throw new NotSupportedException("this url isn`t Null or Empty!");
        EndpointAddress address = new EndpointAddress(url);
        Binding binding = CreateBinding(bing);
        ChannelFactory<T> factory = new ChannelFactory<T>(binding, address);
        return factory.CreateChannel();
    }
    #endregion

    #region 创建传输协议
    /// <summary>
    /// 创建传输协议
    /// </summary>
    /// <param name="binding">传输协议名称</param>
    /// <returns></returns>
    private static Binding CreateBinding(string binding)
    {
        Binding bindinginstance = null;
        if (binding.ToLower() == "basichttpbinding")
        {
            BasicHttpBinding ws = new BasicHttpBinding();
            ws.MaxBufferSize = 2147483647;
            ws.MaxBufferPoolSize = 2147483647;
            ws.MaxReceivedMessageSize = 2147483647;
            ws.ReaderQuotas.MaxStringContentLength = 2147483647;
            ws.CloseTimeout = new TimeSpan(0, 10, 0);
            ws.OpenTimeout = new TimeSpan(0, 10, 0);
            ws.ReceiveTimeout = new TimeSpan(0, 10, 0);
            ws.SendTimeout = new TimeSpan(0, 10, 0);

            bindinginstance = ws;
        }
        else if (binding.ToLower() == "netnamedpipebinding")
        {
            NetNamedPipeBinding ws = new NetNamedPipeBinding();
            ws.MaxReceivedMessageSize = 65535000;
            bindinginstance = ws;
        }
        else if (binding.ToLower() == "netpeertcpbinding")
        {
            NetPeerTcpBinding ws = new NetPeerTcpBinding();
            ws.MaxReceivedMessageSize = 65535000;
            bindinginstance = ws;
        }
        else if (binding.ToLower() == "nettcpbinding")
        {
            NetTcpBinding ws = new NetTcpBinding();
            ws.MaxReceivedMessageSize = 65535000;
            ws.Security.Mode = SecurityMode.None;
            bindinginstance = ws;
        }
        else if (binding.ToLower() == "wsdualhttpbinding")
        {
            WSDualHttpBinding ws = new WSDualHttpBinding();
            ws.MaxReceivedMessageSize = 65535000;

            bindinginstance = ws;
        }
        else if (binding.ToLower() == "webhttpbinding")
        {
            //WebHttpBinding ws = new WebHttpBinding();
            //ws.MaxReceivedMessageSize = 65535000;
            //bindinginstance = ws;
        }
        else if (binding.ToLower() == "wsfederationhttpbinding")
        {
            WSFederationHttpBinding ws = new WSFederationHttpBinding();
            ws.MaxReceivedMessageSize = 65535000;
            bindinginstance = ws;
        }
        else if (binding.ToLower() == "wshttpbinding")
        {
            WSHttpBinding ws = new WSHttpBinding(SecurityMode.None);
            ws.MaxReceivedMessageSize = 65535000;
            ws.Security.Message.ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows;
            ws.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
            bindinginstance = ws;
        }
        return bindinginstance;

    }
    #endregion

}

2.4 Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonLib;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://localhost/ws/Service1.svc?wsdl";

            ITest testInterface = InvokeContext.CreateWCFServiceByURL<ITest>(url);
            int a=1, b=1;
            int result = testInterface.Add(a, b);
            Console.WriteLine("{0}+{1}={2}", a, b, result);
            Console.ReadLine();
        }
    }
}

结果:



好吧, 这就是折腾了哥一个晚上的结果, 呵呵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值