• 使用Winform程序作为WCF服务的宿主


    如果我们自己新建一个WCF服务库,生成了dll文件。那我们需要创建一个宿主程序,在本例中我们新建一个Winform程序作为WCF的宿主程序。

    在网上很多教程里对创建过程写的很模糊,错误也很多。本文是作者在尝试了网上各种失败方法之后,经过自己的改正,总结出的可以正确运行的解决方案。

     1. 创建wcf服务库。

    打开vs, 新建一个 WCF服务库。 什么都不用改,直接生成。 此时会在bin目录下生成一个dll文件(默认名WcfServiceLibrary1.dll)。

    2. 创建宿主程序。

    1). 打开vs,新建一个Windows窗体应用程序。

    2). 添加引用,System.ServiceModel和 刚刚生成的WcfServiceLibrary1.dll。

    3). 创建一个button,在button.click的事件里添加如下代码:

    1. private void button1_Click(object sender, EventArgs e)  
    2. {  
    3.     if (Host == null)  
    4.     {  
    5.         Host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));  
    6.   
    7.         System.ServiceModel.Channels.Binding httpbinding = new BasicHttpBinding();  
    8.   
    9.         Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.Service1), httpbinding, "http://localhost:8002");  
    10.         if (Host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null)  
    11.         {  
    12.             ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();  
    13.             behavior.HttpGetEnabled = true;  
    14.   
    15.             behavior.HttpGetUrl = new Uri("http://localhost:8002/Service1");  
    16.             Host.Description.Behaviors.Add(behavior);  
    17.   
    18.             Host.Open();  
    19.   
    20.             MessageBox.Show("OK");  
    21.         }  
    22.   
    23.   
    24.     }  
    25.   
    26. }  
            private void button1_Click(object sender, EventArgs e)
            {
                if (Host == null)
                {
                    Host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
    
                    System.ServiceModel.Channels.Binding httpbinding = new BasicHttpBinding();
    
                    Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.Service1), httpbinding, "http://localhost:8002");
                    if (Host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null)
                    {
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                        behavior.HttpGetEnabled = true;
    
                        behavior.HttpGetUrl = new Uri("http://localhost:8002/Service1");
                        Host.Description.Behaviors.Add(behavior);
    
                        Host.Open();
    
                        MessageBox.Show("OK");
                    }
    
    
                }
    
            }

    注意本句:

    1. Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), httpbinding, "http://localhost:8002");  
    Host.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), httpbinding, "http://localhost:8002");

    .IService1 为网络教程中出错经作者修改的部分,此处如果写成Service1的话会报如下的错:

    协定类型WcfServiceLibrary1.Service1不具有ServiceContractAttribute特性。若要定义有效协定(协定接口或服务类)必须具有ServiceContractAttribute特性。

    4). 在窗口关闭的事件里添加如下代码:

    1. if (Host != null)  
    2. {  
    3.     Host.Close();  
    4. }  
    if (Host != null)
    {
        Host.Close();
    }

    5). 生成,运行。

    3.  创建客户端程序。

    1). 打开vs,新建一个Windows窗体应用程序。

    2). 右键点击引用,然后选择添加服务引用,在地址栏中输入 http://localhost:8002/Service1 ,即刚刚代码中的behavior的uri,注意不是http://localhost:8002/。

    3). 点击前往,然后点确定即可。

    注意:在网上的好些教程里都写的是在宿主程序用用WCF配置工具生成app.config然后运行宿主程序,那样生成的app.config是有问题的,在客户端程序引用的时候会报错。错误提示:

    下载“http://localhost:8082/wcf2”时出错。 请求因 HTTP 状态 400 失败: Bad Request。 元数据包含无法解析的引用:“http://localhost:8082/wcf2”。 服务 http://localhost:8082/wcf2 不支持内容类型 application/soap+xml; charset=utf-8。客户端和服务绑定可能不匹配。 远程服务器返回错误: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'.。 如果该服务已在当前解决方案中定义,请尝试生成该解决方案,然后再次添加服务引用。

    此问题绝对会发生,但那些教程里并没有指出错误并告知解决办法。困扰我许久之后我终于发现本文中的方法。

    4). 创建一个button,button的click事件中填写如下代码:

    1. private void button1_Click(object sender, EventArgs e)  
    2. {  
    3.     using (ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client())  
    4.     {  
    5.         sc.Open();  
    6.         MessageBox.Show(sc.GetData(10));  
    7.         sc.Close();  
    8.     }  
    9. }  
            private void button1_Click(object sender, EventArgs e)
            {
                using (ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client())
                {
                    sc.Open();
                    MessageBox.Show(sc.GetData(10));
                    sc.Close();
                }
            }

    5).生成,运行即可。

  • 相关阅读:
    CUDA 函数前缀与存储器前缀讨论
    VC++控制台程序中使用定时器
    C++中的RTTI
    C/C++ 时间转换与表示
    [转]winsock和winsock2冲突
    自然归并排序 c++ (原创)
    关于CC++运行时库的多线程版本的工作记录
    关于sizeof(原)
    结构体最后的长度为0或1数组的作用(转载)
    CUDA中常见的错误:the launch timed out and was treminated.
  • 原文地址:https://www.cnblogs.com/yelanggu/p/8311220.html
Copyright © 2020-2023  润新知