tags:

views:

460

answers:

4

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.

+2  A: 

Here is a good article on this: http://msdn.microsoft.com/en-us/library/aa529311.aspx

The key is the usage of the Microsoft.Web.Services3

Sample code copied from the linked article:

public partial class WindowsServiceToHostASMXWebService  : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        Uri address = new Uri("soap.tcp://localhost/TestService");
        SoapReceivers.Add(new EndpointReference(address), typeof(Service ));
    }
    protected override void OnStop()
    {
        SoapReceivers.Clear();
    }
}

and calling it:

static void Main()
{
    System.ServiceProcess.ServiceBase[] ServicesToRun;
    // Change the following line to match.
    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new WindowsServiceToHostASMXWebService() };
    System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
tster
That's pretty cool... I never knew that this was an option.
Andrew Flanagan
+2  A: 

You can use the 'net' command to start or stop services, including the service used by IIS (the web server on windows).

Make sure IIS is installed and your site works like a normal ASP.Net site. Then stop the "World Wide Web Publishing" service startup type to manual instead of Automatic. Now you can start it at any time by issuing a command like this at the console (and from your program via Process.Start()):

net start w3svc

Now you'll have some issues with this if you're thinking more about just dumping this app on any old computer. But if the app is intended to help manage a specific system you'll be fine.

Joel Coehoorn
+1  A: 

You can use HttpRuntime class. If you need, I can provide an short demo.

Zote
+5  A: 

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.

Darin Dimitrov
Out of curiosity would this increase the max stack size at all? In IIS 7 it's only 256K, whereas a console app *I think* is 1MB unless otherwise specified.
blesh
Thanks for the code sample. I do indeed get a TypeLoadException. Apparently `System.Web` doesn't contain a `Hosting` namespace. I didn't understand one thing, though. Which executable exactly should I put into the `bin` subdirectory?
liszt
Did you reference the `System.Web` assembly? As for your question, you need to put the executable or the assembly that contains the `SimpleHost` class in the `bin` sub-directory.
Darin Dimitrov