【问题标题】:How to make Simple WCF Service work in WPF Application?如何使简单 WCF 服务在 WPF 应用程序中工作?
【发布时间】:2017-03-10 00:17:02
【问题描述】:

我一直在关注教程here 并尝试使用 WCF 托管一个简单的 REST 服务器。基本上,我按照教程中的描述创建了 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);
}

以及具体的类:

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);
    }
}

这 2 个 WCF 服务类在我创建的控制台应用程序中完美运行。这是“主要”的样子。 当我向控制台应用程序提交 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();
             }
        }


    }

}

但是,当我想在 WPF 应用程序 中使用这两个类时,它们不再起作用了。这是 WPF 应用程序的 MainWindow 类。 当我向 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();
            }
        }
    }
 }

如何使这 2 个 WCF 类与一个简单的空 WPF 应用程序项目一起工作? 为什么这 2 个 WCF 类适用于空的控制台应用程序项目,而不适用于空的 WPF 应用程序项目?

【问题讨论】:

  • Console.ReadLine 在这种情况下不会导致线程暂停。所以host 打开后会立即关闭。您可能应该将host.Close 移动到某个“退出”按钮。您需要将 host 变量设为成员变量才能使其工作。
  • 我试图从我的 WPF 应用程序中彻底删除 Console.Readline() 和 host.Close() 行。我仍然得到502,但不要认为主机在打开后立即关闭是原因。也许主机只是没有打开?
  • 你能说明你是如何处理你的GET请求的吗?
  • 您还需要删除using 语法。 using 将处理您的 host 对象。另外,我认为您应该将host 设为实例变量。
  • @Alisson 我使用 Fiddler 测试我的 GET 请求,所以基本上是对“1.10.100.126:8899/MyService/GET/a/b”的 GET 请求,这对于 WPF 和控制台都适用

标签: c# .net wpf rest wcf


【解决方案1】:

就如何在 WPF 应用程序中正确托管 WCF 服务给出一个完整、彻底的答案确实有点过于宽泛,但这里有一些指针。

您的 WPF 尝试存在一些主要问题:

  1. 您试图在 UI 线程上托管服务,这是 GUI 设计和编程中的一大禁忌。如果你让它按照你的方式工作,你会锁定你的 UI,用户除了强制关闭你的应用程序之外什么也做不了。
  2. 您在 Window 背后的代码中处理这一切 - WPF 鼓励使用 MVVM 模式,该模式可指导您将视图(窗口、控件等)的呈现方式与使用的服务分开关注/托管/消费。
  3. 您正试图通过在 GUI 应用程序中使用 Console.ReadLine() 来阻止线程,其中没有 Console 监听 - 所以 Console.ReadLine() 只是立即返回(但如果您确实设法阻止线程,您会回到问题 #1)。

有关如何使用更好的设计原则来做您正在尝试的事情的完整教程,请参阅以下blog

其中的一些亮点:

  1. 创建一些控件(例如,显示“开始”和“停止”的按钮)来启动和停止您的服务。
  2. 将这些按钮分别连接到启动服务和停止服务的逻辑。

那里肯定可以进行改进 - 启动和管理服务的生命周期,使用 WPF 中的命令模型,使用 TPL 或 BackgroundWorker 在不同的线程中运行服务,更充分地使用 MVVM 模式- 但这是一个开始。

【讨论】:

    猜你喜欢
    • 2013-06-02
    • 2017-01-20
    • 2018-05-23
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    相关资源
    最近更新 更多