I'm a C#, ASP.NET newbie.

Let's say I have an existing C# project (from a "Console Application" template; I work with Visual Studio). I want to be able to start a simple HTTP server and serve .aspx pages (or ordinary text even, in which case I'm also looking for a nice templating library ^^), but only if a certain command is given to the program via the command-line interface. (So, the server is not up by default.)

How could I best accomplish this?

Thank you very much for any help!

Edit: To clarify, I'd like all of this functionality to be embedded in a single non-webapp non-website project. That is, the project is made up of three parts: the command-line interface, the optionally-run web interface (the HTTP server), and the core that waits for and reacts to requests by either of those two interfaces. This is the current state of the existing project, sans the web-interface.

Comments

Should it serve pages to remote computers, or will the http clients reside on the same machine?

Written by Fredrik Mörk

Develop simple HTTP Server is not that problem, that problem is to serve .aspx pages.

Written by Baget

@Fredrik: It will be serving to both local and remote computers. I'd like to take the functionality you get by creating a new Web Application project and somehow plug it into an ordinary command-line project. I suspect this may be easier to do than I think (?), but I'm a complete newbie. @Baget: It doesn't even have to be .aspx pages. It can be ordinary HTML. In that case I'd go and also look for a templating library of some sort.

Written by liszt

What is your target platform? In other words, is this something that will run on servers or desktop machines? If desktop, what OS's do you think will be in use?

Written by Chris Lively

@Chris: This is something that will run on a desktop system, most probably on Windows XP. Performance really isn't important to me here.

Written by liszt

Accepted Answer

You could host the ASP.NET runtime inside a console application. Here's an example:

public class SimpleHost : MarshalByRefObject
{
    public void ProcessRequest(string page, string query, TextWriter writer)
    {
        SimpleWorkerRequest swr = new SimpleWorkerRequest(page, query, writer);
        HttpRuntime.ProcessRequest(swr);
    }
}

class Program
{
    static void Main(string[] args)
    {
        // TODO: Check to see if a given argument has been passed on the command-line

        SimpleHost host = (SimpleHost)ApplicationHost.CreateApplicationHost(
            typeof(SimpleHost), "/", Directory.GetCurrentDirectory());

        HttpListener listener = new HttpListener();
        listener.Prefixes.Add("http://localhost:9999/");
        listener.Start();
        Console.WriteLine("Listening for requests on http://localhost:9999/");

        while (true)
        {
            HttpListenerContext context = listener.GetContext();
            string page = context.Request.Url.LocalPath.Replace("/", "");
            string query = context.Request.Url.Query.Replace("?", "");
            using (var writer = new StreamWriter(context.Response.OutputStream))
            {
                host.ProcessRequest(page, query, writer);
            }
            context.Response.Close();
        }

    }
}

You might get a TypeLoadException when you run this program. You have to create a bin subdirectory to your current directory and move a copy of the executable to it. This is because the ASP.NET runtime will look for a bin subdirectory. Another option is to put SimpleHost into a separate assembly which you deploy into the GAC.

Written by Darin Dimitrov
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki