简体   繁体   English

如何在WPF应用程序中使简单WCF服务工作?

[英]How to make Simple WCF Service work in WPF Application?

I've been following tutorial here and trying to host a simple REST Server using WCF. 我一直在这里学习教程并尝试使用WCF托管一个简单的REST服务器。 Basically, I created the WCF interface and class file as described in the tutorial: 基本上,我按照教程中的描述创建了WCF接口和类文件:

[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebInvoke(Method = "GET", UriTemplate = "/GET/{msg}/{msg2}")]
    string GetRequest(string msg, string msg2);

    [OperationContract]
    [WebInvoke(Method = "PUT", UriTemplate = "/PUT/{msg}")]
    void PutRequest(string msg, Stream contents);
}

and the concrete class: 和具体的课程:

class Service : IService
{
    static string Message = "Hello";

    public string GetRequest(string msg, string msg2)
    {
        return Message + msg + msg2;
    }

    public void PutRequest(string msg, Stream contents)
    {
        Service.Message = msg + msg + msg;

        string input = new StreamReader(contents).ReadToEnd();
        Console.WriteLine("In service, input = {0}", input);
    }
}

These 2 WCF service classes work perfecting in a Console Application I created. 这两个WCF服务类在我创建的控制台应用程序中完善。 Here is how "Main" looks like. 这是“主要”的样子。 When I submit a GET request to the Console Application, I get a 200 OK : 当我向控制台应用程序提交GET请求时,我得到200 OK

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
             using (var host = new ServiceHost(typeof(Service)))
             {
                 var ep = host.AddServiceEndpoint(typeof(IService), new   WebHttpBinding(), new Uri("http://1.10.100.126:8899/MyService"));

                 ep.EndpointBehaviors.Add(new WebHttpBehavior());
                 host.Open();
                 Console.WriteLine("Service is running");
                 Console.ReadLine();
                 host.Close();
             }
        }


    }

} }

However, when I want to use those 2 classes in a WPF Application , they don't work anymore. 但是,当我想在WPF应用程序中使用这两个类时,它们不再起作用。 Here is the MainWindow class for the WPF Application. 这是WPF应用程序的MainWindow类。 When I submit a GET Request to the WPF Application, I get error 502 BAD GATEWAY : 当我向WPF应用程序提交GET请求时,我收到错误502 BAD GATEWAY

namespace WpfApplication1
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            using (var host = new ServiceHost(typeof(Service)))
            {
                var ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), new Uri("http://1.10.100.126:8899/MyService"));

                ep.EndpointBehaviors.Add(new WebHttpBehavior());
                host.Open();
                Console.WriteLine("Service is running");
                Console.ReadLine();
                host.Close();
            }
        }
    }
 }

How do you make those 2 WCF classes work with a simple empty WPF Application project? 如何使这两个WCF类与一个简单的空WPF应用程序项目一起工作? Why does those 2 WCF classes work with an empty Console Application project, but not an empty WPF Application Project? 为什么这两个WCF类使用空的控制台应用程序项目,而不是空的WPF应用程序项目?

Giving you a complete, thorough answer on how to properly host a WCF service properly in a WPF application is really a bit too broad, but here are some pointers. 为您提供有关如何在WPF应用程序中正确托管WCF服务的完整,全面的答案,实际上有点过于宽泛,但这里有一些指示。

You have a few major problems with your WPF attempt: 您的WPF尝试有几个主要问题:

  1. You're attempting to host the service on the UI thread, a big no-no in GUI design and programming. 您正在尝试在UI线程上托管服务,这是GUI设计和编程中的一个重要禁忌。 If you got it working the way you have it, you'd lock your UI and the user wouldn't be able to do anything but force-close your application. 如果你按照它的方式使用它,你就会锁定你的用户界面,除了强制关闭你的应用程序之外,用户将无法做任何事情。
  2. You're handling it all in a code behind for a Window - WPF encourages the MVVM pattern, which guides you to separate concerns of how your view (window, controls, etc.) is rendered vs. what services are used/hosted/consumed. 你在窗口的代码中处理它全部--WPF鼓励MVVM模式,它指导你分别关注你的视图(窗口,控件等)的呈现方式以及使用/托管/使用的服务。
  3. You're attempting to block the thread by using Console.ReadLine() in a GUI application, where there is no Console listening - so Console.ReadLine() is just returning immediately (but if you did manage to block the thread, you'd be back to problem #1). 您试图通过在GUI应用程序中使用Console.ReadLine()来阻止线程,其中没有Console监听 - 因此Console.ReadLine()只是立即返回(但如果您设法阻止该线程,那么' d回到问题#1)。

For a full tutorial on how to do what you're attempting with better design principles, see the following blog 有关如何使用更好的设计原则进行操作的完整教程,请参阅以下博客

Some highlights from that: 一些亮点:

  1. Create some controls (eg buttons that say 'Start' and 'Stop') to start and stop your service. 创建一些控件(例如,“开始”和“停止”按钮)以启动和停止服务。
  2. Wire up those buttons to the logic to start your service and stop your service respectively. 将这些按钮连接到逻辑以启动服务并分别停止服务。

There's definitely improvements that could be made there - starting and managing the lifetime of the service, using the Commanding model in WPF, using the TPL or a BackgroundWorker to run the service in a different thread, making fuller usage of the MVVM pattern - but it's a start. 在那里可以做出明显的改进 - 启动和管理服务的生命周期,使用WPF中的命令模型,使用TPL或BackgroundWorker在不同的线程中运行服务,更充分地使用MVVM模式 - 但它是一个开始。

Service Host is getting closed as soon as it is opened. 服务主机一打开就会关闭。

By Default, WPF application is created with OutputType as Windows Application. 默认情况下,使用OutputType作为Windows应用程序创建WPF应用程序。 Console doesn't show up when it runs, hence Console.ReadLine() will not wait for user input and moves to the next line. 控制台在运行时不会显示,因此Console.ReadLine()不会等待用户输入并移动到下一行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM