2009-10-30 20 views
5

Soy un C#, Novato de ASP.NET.¿Iniciar programáticamente un servidor HTTP en C#?

Digamos que tengo un proyecto de C# existente (de una plantilla de "Aplicación de consola", trabajo con Visual Studio). Quiero poder iniciar un servidor HTTP simple y publicar páginas .aspx (o incluso texto común, en cuyo caso también estoy buscando una biblioteca de plantillas agradable ^^), pero solo si se da un cierto comando a el programa a través de la interfaz de línea de comandos. (Entonces, el servidor no está activo por defecto.)

¿Cómo puedo lograr esto?

Muchas gracias por cualquier ayuda!

Editar: Para aclarar, me gustaría que toda esta funcionalidad se integre en un solo proyecto que no sea de webapp. Es decir, el proyecto se compone de tres partes: la interfaz de línea de comandos, la interfaz web ejecutada opcionalmente (el servidor HTTP) y el core que espera y responde a las solicitudes de cualquiera de esas dos interfaces. Este es el estado actual del proyecto existente, sin la interfaz web.

+0

¿Debe servir páginas a computadoras remotas, o los clientes http residirán en la misma máquina? –

+0

Desarrollar servidor HTTP simple no es ese problema, ese problema es servir páginas .aspx. – Baget

+0

@Fredrik: se publicará en computadoras locales y remotas. Me gustaría aprovechar la funcionalidad que obtienes al crear un nuevo proyecto de aplicación web y, de alguna manera, conectarlo a un proyecto de línea de comando ordinario. Sospecho que esto puede ser más fácil de lo que creo (?), Pero soy un completo novato. @Baget: Ni siquiera tiene que ser .aspx páginas. Puede ser HTML ordinario. En ese caso, iría y también buscaría una biblioteca de plantillas de algún tipo. –

Respuesta

9

Puede alojar el tiempo de ejecución de ASP.NET dentro de una aplicación de consola. He aquí un ejemplo:

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

    } 
} 

Es posible obtener una TypeLoadException cuando se ejecuta este programa. Debe crear un subdirectorio bin en su directorio actual y moverle una copia del ejecutable. Esto se debe a que el tiempo de ejecución de ASP.NET buscará un subdirectorio bin. Otra opción es poner SimpleHost en un ensamblaje separado que implemente en el GAC.

+0

Por curiosidad, ¿esto aumentaría el tamaño máximo de la pila? En IIS 7 es solo 256K, mientras que una aplicación de consola * Creo * es de 1MB a menos que se especifique lo contrario. –

+0

Gracias por la muestra de código. De hecho, recibo una TypeLoadException. Aparentemente 'System.Web' no contiene un espacio de nombres' Hosting'. Sin embargo, no entendí una cosa. ¿Qué ejecutable exactamente debería poner en el subdirectorio 'bin'? –

+0

¿Hizo referencia al ensamblado 'System.Web'? En cuanto a su pregunta, debe colocar el ejecutable o el conjunto que contiene la clase 'SimpleHost' en el subdirectorio' bin'. –

2

Aquí es un buen artículo sobre esto: http://msdn.microsoft.com/en-us/library/aa529311.aspx

La clave es el uso del código Microsoft.Web.Services3

Muestra copiado del artículo enlazado:

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

y decir que es:

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); 
} 
+0

Eso es genial ... Nunca supe que esta era una opción. –

2

Puede usar la 'red' c ommand para iniciar o detener servicios, incluido el servicio utilizado por IIS (el servidor web en Windows).

Asegúrese de que IIS esté instalado y su sitio funcione como un sitio ASP.Net normal. A continuación, configure el tipo de inicio del servicio "World Wide Web Publishing" como manual en lugar de Automático. Ahora puede comenzar en cualquier momento mediante la emisión de un comando como este en la consola (y de su programa a través de Process.Start()):

net start w3svc

Ahora vamos a tener algunos problemas con este si estás pensando más en simplemente dejar esta aplicación en cualquier computadora vieja. Pero si la aplicación está destinada a ayudar a administrar un sistema específico, estarás bien.

0

Puede utilizar la clase HttpRuntime. Si lo necesita, puedo proporcionar una breve demostración.

Cuestiones relacionadas