2009-10-30 4 views
5

Je suis un débutant C#, ASP.NET. Disons que j'ai un projet C# existant (à partir d'un modèle "Application console", je travaille avec Visual Studio). Je veux être capable de démarrer un simple serveur HTTP et de servir des pages .aspx (ou du texte ordinaire même, auquel cas je cherche aussi une belle bibliothèque de templates ^^), mais seulement si une certaine commande est donnée à le programme via l'interface de ligne de commande. (Ainsi, le serveur n'est pas activé par défaut.)Démarrer par programme un serveur HTTP en C#?

Comment pourrais-je mieux accomplir cela?

Merci beaucoup pour toute aide!

Modifier: Pour clarifier, j'aimerais que toutes ces fonctionnalités soient intégrées dans un seul projet non-webapp non-site Web. Le projet est composé de trois parties: l'interface de ligne de commande, l'interface Web éventuellement exécutée (le serveur HTTP) et le cœur qui attend et réagit aux requêtes de l'une de ces deux interfaces. C'est l'état actuel du projet existant, sans l'interface web.

+0

Doit-il servir des pages à des ordinateurs distants, ou les clients http résident-ils sur la même machine? –

+0

Développer un serveur HTTP simple n'est pas ce problème, ce problème est de servir des pages .aspx. – Baget

+0

@Fredrik: Il servira à la fois aux ordinateurs locaux et distants. Je voudrais utiliser la fonctionnalité que vous obtenez en créant un nouveau projet d'application Web et le brancher en quelque sorte dans un projet de ligne de commande ordinaire. Je suppose que cela peut être plus facile à faire que je ne le pense (?), Mais je suis un débutant complet. @Baget: Il ne s'agit même pas de pages .aspx. Ce peut être du HTML ordinaire. Dans ce cas, j'irais aussi chercher une bibliothèque de modèles. –

Répondre

9

Vous pouvez héberger le runtime ASP.NET dans une application de console. Voici un exemple:

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

    } 
} 

Vous pourriez obtenir un TypeLoadException lorsque vous exécutez ce programme. Vous devez créer un sous-répertoire bin dans votre répertoire actuel et y déplacer une copie de l'exécutable. Cela est dû au fait que le runtime ASP.NET recherchera un sous-répertoire bin. Une autre option consiste à mettre SimpleHost dans un assembly distinct que vous déployez dans le GAC.

+0

Par curiosité, cela augmenterait-il la taille maximum de la pile? Dans IIS 7, c'est seulement 256K, alors qu'une application de console * je pense * est 1MB, sauf indication contraire. –

+0

Merci pour l'exemple de code. J'obtiens en effet une exception TypeLoadException. Apparemment 'System.Web' ne contient pas d'espace de nommage' Hosting'. Cependant, je n'ai pas compris une chose. Quel exécutable exactement dois-je mettre dans le sous-répertoire 'bin'? –

+0

Avez-vous référé l'assembly 'System.Web'? Comme pour votre question, vous devez mettre l'exécutable ou l'assembly qui contient la classe 'SimpleHost' dans le sous-répertoire' bin'. –

2

Voici un bon article sur ce point: http://msdn.microsoft.com/en-us/library/aa529311.aspx

La clé est l'utilisation du Microsoft.Web.Services3

Exemple de code copié de l'article lié:

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

et de l'appeler:

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

C'est plutôt cool ... Je n'ai jamais su que c'était une option. –

2

Vous pouvez utiliser le 'net' c commande pour démarrer ou arrêter les services, y compris le service utilisé par IIS (le serveur Web sous Windows).

Assurez-vous que IIS est installé et que votre site fonctionne comme un site ASP.Net normal. Définissez ensuite le type de démarrage du service "Publication World Wide Web" sur manuel au lieu de Automatique. Maintenant, vous pouvez commencer à tout moment en lançant une commande comme celui-ci à la console (et de votre programme via Process.Start()):

net start w3svc

Maintenant, vous aurez quelques problèmes avec cette Si vous songez à plus sur le dumping de cette application sur un vieil ordinateur. Mais si l'application est destinée à aider à gérer un système spécifique, tout ira bien.

0

Vous pouvez utiliser la classe HttpRuntime. Si vous en avez besoin, je peux vous fournir une courte démo.

Questions connexes