使用可执行应用程序托管Web UI?

时间:2016-04-21 19:24:08

标签: web-services wcf web owin executable

这可能是一个非常愚蠢的问题,但我花了近5个小时在网上进行研究,没有发现任何可以完全澄清我的怀疑。

简而言之,我被要求可能的雇主开发某些可执行应用程序作为“技术测试”的一部分。据说他们正在衡量我与WCF合作的专业知识。我有两天时间开发这样的应用程序,所有相关信息如下:

  

可交付成果:

     

- 可执行文件

     

*运行APP时,它应该托管WCF服务(SERVICE)和

     

Web浏览器可访问的Web UI(UI)。

     

*通过用户界面,用户应该能够添加或删除存储在

中的消息      

数据库(DB)。

     

* UI还应显示存储在数据库中的当前消息列表。

     

*如果对数据库进行了更改,则这些更改应显示在UI

中      

无需重新加载页面。

     

- 所有项目源代码。

     

     

附加说明:

     
      
  • 只要明确引用现有的库,就允许使用现有的库
  •   

现在,我了解您可以使用控制台应用程序(以及其他选项)托管WCF Web服务,只要应用程序正在运行,服务就会处于活动状态。我还知道,任何Web应用程序都可以通过添加服务引用,创建其类型的客户端并调用其方法来访问此服务。当他们要求我将所有内容放在一个可执行的应用程序中时,我的困惑就开始了:

  

当APP运行时,它应该托管WCF服务(SERVICE)以及Web浏览器可访问的Web UI(UI)。

那是什么意思?如何使用可执行文件托管Web UI?我是否应该开发类似IIS的东西,同时以某种方式定义APP上的html和服务器端代码?

我做了一些研究,我找到了一个类(HttpListener),它允许你打开一个http端口,监听然后通过它发回一些html。一个非常简单的课程。如果这是一个解决方案,我看不到如何实现它。除此之外,我在网上找不到任何其他内容。

我很感激对此事的任何意见,即使我无法及时制定解决方案,我也想知道如何做到这一点。如果我遗漏了一些关于WCF或虚拟主机的重要基本概念,请非常感谢一些澄清。提前谢谢。

2 个答案:

答案 0 :(得分:0)

您可以使用OWIN“自托管”网络应用。

可在此处查看概述和更多信息 - http://codeopinion.com/self-host-asp-net-web-api/

答案 1 :(得分:0)

我通过在服务本身托管Web UI解决了这个问题。服务操作可以返回任何内容,甚至是带有html的字节流,供浏览器呈现。这是代码。

[WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
    public Stream GetUserInterface()
    {
        var appDirectoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        var htmlFilePath = appDirectoryName + "\\UI.html";
        var buffer = File.ReadAllBytes(htmlFilePath);
        if (WebOperationContext.Current != null)
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
        return new MemoryStream(buffer);
    }

正如您在同一目录中看到的那样,我放置了一个UI.html文件,该文件包含我的所有UI html,javascript和css。然后我将它转换为一个字节数组并将其返回给浏览器。

因此,我要访问UI的唯一方法是运行应用程序,然后浏览到此操作。例如:http://localhost:8080/MyService/GetUserInterface

对于我使用SQlite的数据库部分,通过这种方式,应用程序成为独立的,可以安装在PC中并立即运行而无需数据库或Web托管。正是测试所要求的。

或者,我在问题中提到的类(HttpListener)也可用于托管Web UI而不是服务。这是另一种解决方案。

private static void HostUI()
    {
        while (true)
        {
            using (var listener = new HttpListener())
            {
                listener.Prefixes.Add("http://localhost:7070/");
                listener.Start();
                var context = listener.GetContext();
                var response = context.Response;

                //The .html file will be in the same folder where the .exe is
                var appDirectoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                var htmlFilePath = appDirectoryName + "\\UI.html";
                var buffer = File.ReadAllBytes(htmlFilePath);

                response.ContentType = "text/html";
                response.ContentLength64 = buffer.Length;
                Console.WriteLine(buffer.Length);
                var output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                output.Close();
                listener.Close();
            }
        }
    }

我使用无限循环的原因是因为HttpListener类实现只按循环处理一个顺序,所以为了能够多次请求UI,你需要这样做。

然后您可以浏览到http://localhost:7070/,您也会看到用户界面。

您可以将此代码放在一个独立的线程中来托管Web UI,而不会影响主线程。