views:

99

answers:

5

For a simple appliance that runs on a Windows & .NET operating system, we need to create a simple configuration web interface to control it. Just like your router's configuration page, nothing more complicated than that.

Installing IIS or any other web server should be avoided, what we need is a self supporting process within a windows service on a basic windows XP installation + .NET.

Mono compatibility is a plus.

Thanks a million

A: 

You could use UtilDev Cassini with your windows service. It is based on the original MS casini that is bult into visual studio and is free and redistributable.

Ben Robinson
A: 

If you were using Windows 7 you could use IIS7's Hostable Web Core feature to host a subset of IIS inside your service, without installing IIS7 itself.

What you are looking for is an embedded web server. While you can write your own, I suggest you check C# WebServer, an embedded web server written in C#.

Panagiotis Kanavos
A: 

If you want a simple solutions, I would suggest you try Kayak.

From the site:

Kayak is a simple web server. It listens for connections, creates an in-memory representation of requests, and allows you to easily generate responses. It can be used in any C# program. Your code loads Kayak into its process space—not the other way around!

It works well with mono also. Give it a shot! :)

Update

Your can also try aspnet serve

LightX
+3  A: 

Actually the easiest way is to use the built-in WCF stuff (.Net 3.5)... To do this you create a interface for your 'WCF' service that contains one or more methods that return Stream:

[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebInvoke(UriTemplate = "/{*arguments}", Method="GET", BodyStyle=WebMessageBodyStyle.Bare)]
    Stream Get(string arguments);
}

You can define several methods and arguments and let WFC do the work, or as the example above, push everything into a single method. The resulting implementation can access the full Uri and query parameters as follows:

public class ServiceType : IService
{
    public Stream Get(string arguments)
    {
        UriTemplateMatch uriInfo = WebOperationContext.Current.IncomingRequest.UriTemplateMatch;
        WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";

        MemoryStream rawResponse = new MemoryStream();
        TextWriter response = new StreamWriter(rawResponse, Encoding.UTF8);
        response.Write("<html><head><title>Hello</title></head><body>");
        response.Write("<b>Path</b>: {0}<br/>", arguments);
        response.Write("<b>RequestUri</b>: {0}<br/>", uriInfo.RequestUri);
        response.Write("<b>QueryParameters</b>: {0}<br/>", uriInfo.QueryParameters.ToString());
        response.Write("</body></html>");
        response.Flush();

        rawResponse.Position = 0;
        return rawResponse;
    }
}

Now all you have to do is start up the WCF web/http self-host ...

static void Main()
{
    Uri baseAddress = new Uri("http://localhost:8000/");
    WebServiceHost svcHost = new WebServiceHost(typeof(ServiceType));

    ServiceEndpoint svcEndpoint = svcHost.AddServiceEndpoint(typeof(IService),
      new WebHttpBinding(), baseAddress);
    svcEndpoint.Behaviors.Add(new WebHttpBehavior());

    svcHost.Open();
    Console.WriteLine("Press enter to quit...");
    Console.ReadLine();

    svcHost.Close();
}

NOTE: for the above example to work on Vista/Win7 you need to grant permissions with the following command-line:

netsh http add urlacl url=http://+:8000/ user=DOMAIN\USER
csharptest.net
+1  A: 

You can host the ASP.Net runtime in your own process. Rick Strahl has an old article about it called "Using the ASP.Net Runtime for extending desktop applications with dynamic HTML Scripts".

It should work fine for Windows XP, .Net 2.0 and up. If you combine this with the WCF code in @csharptest.net answer you should be able to use the power of ASP.Net pages and having an endpoint for it.

Mikael Svenson