• WCF深入浅出学习1


    1、本文主要对WCF的基本使用做简单化介绍,对于初学WCF的来说,初期对于配置文件的理解,比较烦躁吧,相信你看完了该文,能够达到深入浅出的感觉。

    关于WCF的概念 和 应用场景,在此处不做详细介绍,可用参考如下博主的首页:

    http://www.cnblogs.com/artech/archive/2007/02/26/656901.html

    2、好了,开始创建我们的WCF类库、宿主、和测试项目吧。

    首先,先看一下我的解决方案:

    (1)、先创建一个WCF服务库

    (2)添加新项,FirstService,这个是我自己新建的。

    (3)系统会自动给我们创建了上面两个类,一个接口,一个实现:

    对接口定义操作方法(这里的申明都不需要public等限定符):

        public interface IFirstService
        {
            [OperationContract]
            void DoWork();
    
            [OperationContract]
            string HelloWorld(string name);
        }

    (4)、实现部分

        public class FirstService : IFirstService
        {
            public void DoWork()
            {
                Console.WriteLine("This is the method DoWork.");
            }
    
            public string HelloWorld(string name)
            {
                return "Hello" + name;
            }
    
        }

    (5)由于我们创建了两个服务,所以系统会给我们自动生产他们的配置文件,在这里(我们对其只需了解,因为我们并没有使用它,

    因为我们是将WCF类库寄宿于Console应用上,我们的配置文件并不是这个,但和这个很多是相同的)

    上图,对我们的两个服务进行了ABC的配置。我们可用将该类库设置为启动项直接运行,如下图,那么他就读取了该配置文件了。

    请记住这个地址,会和我寄宿的地址不同。上面的也可以在VS提供的界面进行测试WCF服务。


    接下来,我们将上面的库寄宿到控制台应用上。

    创建控制台应用程序WCF1HOST,添加对 System.ServiceModel 和 上面 类库dll的引用;

    代码如下:

    class Program    {
            static void Main(string[] args)
            {
                try
                {
                    ServiceHost host1 = new ServiceHost(typeof(WCF1.Service1));
                    host1.Open();
                    Console.WriteLine("Service1 服务已经开启。");
    
                    ServiceHost host2 = new ServiceHost(typeof(WCF1.FirstService));
                    host2.Open();
                    Console.WriteLine("FirstService 服务已经开启。");
    
                    Console.WriteLine("输入exit可关闭服务并退出");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                while (true)
                {
                    string input = Console.ReadLine();
                    if (input.Equals("exit"))
                    {
                        break;
                    }
                    Console.WriteLine("服务继续...");
                }
                
                
                //单个服务
                //using (ServiceHost host = new ServiceHost(typeof(WCF1.FirstService)))
                //{
                //    try
                //    {
                //        host.Open();
                //        Console.WriteLine("FirstService 服务已经开启。");
                //        Console.ReadLine();
                //    }
                //    catch (Exception ex)
                //    {
                //        Console.WriteLine(ex.Message);
                //    }
                    
                //}
    
                ////创建宿主的基地址,假如我们没有配置 App.config 那么我们就需要指定了。
                //Uri baseAddress = new Uri("http://localhost:8080/FirstService");
                ////创建宿主
                //using (ServiceHost host = new ServiceHost(typeof(WCF1.FirstService), baseAddress))
                //{
                //    //向宿主中添加终结点
                //    host.AddServiceEndpoint(typeof(WCF1.FirstService), new WSHttpBinding(), "");
                //    //将HttpGetEnabled属性设置为true
                //    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                //    smb.HttpGetEnabled = true;
                //    //将行为添加到Behaviors中
                //    host.Description.Behaviors.Add(smb);
                //    //打开宿主
                //    host.Open();
                //    Console.WriteLine("WCF中的HTTP监听已启动....");
                //    Console.ReadLine();
                //    host.Close();
                //}
            }
        }

    对于上面的注视部分,相信大家也很容易理解,这里给出了两种(一种读取配置文件、一种手动配置URI,我们建议配置URI)

    我们查看App.config文件(如果没有就创建)

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
      <system.serviceModel>
    
        <!--Bindings-->
        <bindings>
          <netHttpBinding>
            <binding name="IFirstServiceBinding"/>
          </netHttpBinding>
        </bindings>
        
        <!--Behavior-->
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <!--Services-->
        <services>
          <service name="WCF1.Service1">
            <endpoint address="http://localhost:8888/Service1" binding="basicHttpBinding" contract="WCF1.IService1">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8888/Service1" />
              </baseAddresses>
            </host>
          </service>
          
          <!--第二个Service-->
          <service name="WCF1.FirstService">
            <endpoint address="http://localhost:8888/FirstService" binding="basicHttpBinding" contract="WCF1.IFirstService">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8888/FirstService" />
              </baseAddresses>
            </host>
          </service>
          
        </services>
        <!--结束多个Service-->
        
        
      </system.serviceModel>
    
    </configuration>

    可用看到:<services> 就是我们的服务,我们这里提供了两个服务,此处

    baseAddress="http://localhost:8888/Service1 和我们的类库中的地址已经不同了。 
    但是配置确是相同的,都是配置ABC,这里的配置也是基本的标准配置。开启我们的寄宿程序如下:

    
    
    最后,我们在客户端程序上测试,添加对两个服务的引用,如下

    客户端调用服务引用,和调用类是一样的原理
    class Program
        {
            static void Main(string[] args)
            {
           //创建服务类 WCFTest1.MyService1.Service1Client sev1
    = new MyService1.Service1Client(); Console.WriteLine("调用:Service1.GetData Method: " + sev1.GetData(3)); WCFTest1.MyFirstService.FirstServiceClient firstSev = new MyFirstService.FirstServiceClient(); Console.WriteLine("调用:Service1.MyFirstService Method: " + firstSev.HelloWorld("weiyaowen")); Console.WriteLine("调用:Service1.HelloWorldAsync Method: " + firstSev.HelloWorldAsync("weiyaowen").Result); //获取异步调用WCF的 Result Console.ReadLine(); } }
    查看客户端下的配置文件App.config
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
        <system.serviceModel>
            <bindings>
                <basicHttpBinding>
                    <binding name="BasicHttpBinding_IFirstService" />
                    <binding name="BasicHttpBinding_IService1" />
                </basicHttpBinding>
            </bindings>
            <client>
              <!--以下是配置两个服务的地址,在我们添加了服务引用之后会自动添加-->
                <endpoint address="http://localhost:8888/FirstService" binding="basicHttpBinding"
                    bindingConfiguration="BasicHttpBinding_IFirstService" contract="MyFirstService.IFirstService"
                    name="BasicHttpBinding_IFirstService" />
              <!--IService1-->
                <endpoint address="http://localhost:8888/Service1" binding="basicHttpBinding"
                    bindingConfiguration="BasicHttpBinding_IService1" contract="MyService1.IService1"
                    name="BasicHttpBinding_IService1" />
            </client>
        </system.serviceModel>
    </configuration>

    上面的文件在添加了服务引用之后会自动生成,可用看到,和我们寄宿服务的地址一模一样的,这样我们的客户端就能够顺利的找到WCF服务的地址了。

    查看结果:

    
    

    另外:在看看创建类库自动生产的配置,下面飘红的字体很明确的说了:主机的需要另外配置,那么我们可用选择拷贝过去咯,改下地址就OK了:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" />
      </system.web>
      <!-- 部署服务库项目时,必须将配置文件的内容添加到 
      主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
      <system.serviceModel>
        <services>
          <service name="WCF1.Service1">
            <endpoint address="" binding="basicHttpBinding" contract="WCF1.IService1">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8733//WCF1/Service1/" />
              </baseAddresses>
            </host>
          </service>
          <service name="WCF1.FirstService">
            <endpoint address="" binding="basicHttpBinding" contract="WCF1.IFirstService">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8733//WCF1/FirstService/" />
              </baseAddresses>
            </host>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- 为避免泄漏元数据信息,
              请在部署前将以下值设置为 false -->
              <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
              <!-- 要接收故障异常详细信息以进行调试,
              请将以下值设置为 true。在部署前设置为 false 
                以避免泄漏异常信息-->
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
    </configuration>

    我们完全可用在创建寄宿应用程序时,将该文件,只修改一下BaseAddress 就能够部署:如下测试。


    分享共进步!

  • 相关阅读:
    让CEF支持FLASH(非安装插件的形式)
    解决SQLServer 2008 日志无法收缩,收缩后大小不改变
    HTML Socket实现 .NET
    JS基础之BOM对象
    JavaScript对象
    JS函数
    JavaScript概述
    CSS块级元素和行内元素
    返回顶部示例
    CSS属性操作二
  • 原文地址:https://www.cnblogs.com/imyao/p/5416254.html
Copyright © 2020-2023  润新知