1
votes

This may be a very stupid question but I have spent nearly 5 hours doing research on the web and found nothing to fully clarify my doubts.

In few words I have been asked for a possible employer to develop certain executable application as part of a "Technical Test". Supposedly they're measuring my expertise working with WCF. I was given two days to develop such App and all the information about it is the following:

Deliverable:

                - An executable that

                                * When APP is ran, it should host a WCF service (SERVICE) as well as a

web UI (UI) accessible by web browsers.

                                * Through the UI, user should be able to add or delete messages stored in a

database (DB).

                                * The UI should also display the current list of messages stored in the DB.

                                * If changes are made to the DB, those changes should show up in the UI

without the need to reload the page.

                - All of the project source code.

               

Additional notes:

  • Use of existing libraries is allowed as long as they are clearly referenced

Now, I understand that you can host a WCF Web Service using a Console Application (among other options) and the Service will be alive as long as the application is running. I also know that any Web Application can access this service by just adding a Service Reference, creating a client of its type and calling its methods. My confusion begins when they ask me to put all together in one executable application:

When APP is ran, it should host a WCF service (SERVICE) as well as a web UI (UI) accessible by web browsers.

What is that supposed to mean?? How can I host a Web UI using an executable?? Am I supposed to develop something like IIS and at the same time somehow define the html and server side code on the APP?

I did some research and I found a class(HttpListener) that allows you to open an http port, listen and then send back some html thru it. A very simple class. If this is a solution I can't see how to implement it. Other than that I couldn't find anything else on the web.

I would appreciate any opinion on the matter, even if I'm not able to develop the solution in time I would like to know how to do it. And if I'm missing some important basic concept regarding WCF or Web Hosting please I would greatly appreciate some clarification. Thanks in advance.

2

2 Answers

0
votes

You can use OWIN to "self host" web apps.

An overview and further information can be found here - http://codeopinion.com/self-host-asp-net-web-api/

0
votes

I solved the problem by hosting the web UI in the service itself. A service operation can return anything, even a Stream of bytes with the html for the browser to render. Here's the code.

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

As you can see on the same directory than the executable I placed a UI.html file, this file contains all my UI html, javascript and css. Then I convert it to an array of bytes and return that to the browser.

So the only thing I have to do to access the UI is run the application and then browse to this operation. Eg: http://localhost:8080/MyService/GetUserInterface.

For the database part I used SQlite, in this way the application became a standalone that can be installed in a PC and run immediately without the need of Database or Web hosting. Exactly what the test requested.

Alternatively the class that I mentioned in my question (HttpListener) can also be used to host the Web UI instead of the service. This is another solution.

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

The reason why I used an infinite loop is because the HttpListener class implementation processes only one order by loop, so in order to able to request the UI multiple times you need to do this.

Then you can browse to http://localhost:7070/ and you'll see the UI too.

You can put this code in an independent thread to host the Web UI without affecting the main thread.