2009-10-30 5 views
5

Sono un novizio di C#, ASP.NET.Avvio a livello di programmazione di un server HTTP in C#?

Diciamo che ho un progetto C# esistente (da un modello "Applicazione console", lavoro con Visual Studio). Voglio essere in grado di avviare un semplice server HTTP e servire pagine .aspx (o anche testo normale, nel qual caso sto anche cercando una bella libreria di template ^^), ma solo se viene dato un determinato comando a il programma tramite l'interfaccia della riga di comando. (Quindi, il server non è attivo per impostazione predefinita.)

Come potrei realizzare al meglio questo?

Grazie mille per qualsiasi aiuto!

Modifica: Per chiarire, mi piacerebbe che tutte queste funzionalità fossero incorporate in un singolo progetto non-webapp non-web. In altre parole, il progetto è costituito da tre parti: l'interfaccia della riga di comando, l'interfaccia web facoltativa (il server HTTP) e il nucleo che attende e reagisce alle richieste da una di queste due interfacce. Questo è lo stato attuale del progetto esistente, senza l'interfaccia web.

+0

Se serve pagine su computer remoti, o i client http risiedono sullo stesso computer? –

+0

Sviluppare un semplice server HTTP non è un problema, quel problema è servire le pagine .aspx. – Baget

+0

@Fredrik: Verrà utilizzato sia su computer locali che su computer remoti. Mi piacerebbe prendere la funzionalità che ottieni creando un nuovo progetto di applicazione Web e in qualche modo collegandolo a un normale progetto da riga di comando. Sospetto che questo potrebbe essere più facile da fare di quanto penso (?), Ma sono un principiante completo. @Baget: non devono nemmeno essere pagine .aspx. Può essere HTML ordinario. In tal caso, andrei a cercare anche una libreria di template di qualche tipo. –

risposta

9

È possibile ospitare il runtime di ASP.NET all'interno di un'applicazione console. Ecco un esempio:

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

    } 
} 

Si potrebbe ottenere un TypeLoadException quando si esegue questo programma. È necessario creare una sottodirectory bin nella directory corrente e spostare una copia dell'eseguibile su di essa. Questo perché il runtime ASP.NET cercherà una sottodirectory bin. Un'altra opzione consiste nel mettere SimpleHost in un assembly separato che si distribuisce nel GAC.

+0

Per curiosità aumenterebbe la dimensione massima dello stack? In IIS 7 è solo 256K, mentre un'app console * penso * è 1MB se non diversamente specificato. –

+0

Grazie per il codice di esempio. In effetti ottengo un TypeLoadException. Apparentemente 'System.Web' non contiene uno spazio dei nomi' Hosting'. Non ho capito una cosa, però. Quale eseguibile esattamente dovrei inserire nella sottodirectory 'bin'? –

+0

Hai fatto riferimento all'assembly 'System.Web'? Per quanto riguarda la tua domanda, devi inserire l'eseguibile o l'assembly che contiene la classe 'SimpleHost' nella sottodirectory' bin'. –

2

Ecco un buon articolo su questo: http://msdn.microsoft.com/en-us/library/aa529311.aspx

La chiave è l'utilizzo del codice Microsoft.Web.Services3

campione copiato dal articolo collegato:

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

e chiamandolo:

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

E 'davvero bello ... Non ho mai saputo che questa fosse un'opzione. –

2

È possibile utilizzare la 'rete' c Comando per avviare o interrompere i servizi, incluso il servizio utilizzato da IIS (il server Web su Windows).

Assicurarsi che IIS sia installato e che il sito funzioni come un normale sito ASP.Net. Quindi impostare il tipo di avvio del servizio "Pubblicazione sul Web" su Manuale anziché Automatico. Ora si può iniziare in qualsiasi momento mediante l'emissione di un comando come questo alla console (e dal programma tramite Process.Start()):

net start w3svc

Ora dovrete alcuni problemi con questo se stai pensando di scaricare questa app su un vecchio computer. Ma se l'app è pensata per aiutare a gestire un sistema specifico, starai bene.

0

È possibile utilizzare la classe HttpRuntime. Se è necessario, posso fornire una breve demo.

Problemi correlati