Click here to Skip to main content
15,885,546 members
Articles / Web Development / ASP.NET
Article

TinyWebServer, an ideal portable webserver for ASP.NET project development

Rate me:
Please Sign up or sign in to vote.
4.61/5 (19 votes)
17 Nov 2007CPOL4 min read 123.8K   8.1K   80   22
A tiny portable webserver, called TinyWebServer, which can be used wherever IIS is not availabe.

TinyWebServer : main window

Introduction

Have you ever wanted to show up an ASP.NET project where IIS was not accessible? Have you ever thought of if there can be a way to carry your web server wherever you go, i.e., on a USB flash stick or even a CD?

If so, then this cool TinyWebServer is for you! This tiny portable web server can be used for testing and developing ASP.NET projects, wherever IIS is not available.

Background

Very often, I had looked for a way to run an ASP.NET project without needing IIS to be installed. I had wondered how Microsoft Visual Studio 2005 could run its ASP.NET Development Webserver regardless of IIS. I tried more and more to find such a solution ... I made Google angry with my no-result searches, but still there was no solution. Therefore, I decided to find a way to write my own ...

As you know, VS2005 has a nice development server included, called "ASP.NET Development Server". If you look at how it actually does this, you'll find a console application named WebDev.WebServer.EXE located in your .NET 2.0 installation folder, which usually is "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727". If you run it, you will see something like this:

ASP.NET Development Server

As you see, there are command-line options that can be set in order to run the ASP.NET Development Server on your specified folder. Well, seems to be okay, but there still are some issues remaining:

  • You should pass the parameters you specified whenever you want to run it again, or you should make a batch file to do it for you. There should be a better way!
  • Working with a console application such as this in a GUI-based platform is not so interesting. There should be a better way!
  • Although VS2005 finds a free and available port to run the web server for you, this console application will take it from a parameter you pass, which means the port you specify in your command line or batch file may not necessarily be available.
  • This console application uses a component called WebDev.WebHost.dll which is registered in the GAC (Global Assembly Cache). Since you won't see it and it won't be available in your search results, it can't be copied using XCOPY, as you might think!

What can we do then?

TinyWebServer at a Glance

The main part of the server is in a nice and tiny component named WebDev.WebHost.dll which we will try to reach. This tiny DLL is located in the following directory:

c:\WINDOWS\assembly\GAC_32\WebDev.WebHost\8.0.0.0__b03f5f7f11d50a3a\

While you try to reach to this path through Explorer, you will find out that Explorer can not easily show the folder due to an Explorer extension for GAC that gets installed while installing the Microsoft .NET framework.

So what? Easily try to reach this path using the command prompt? Found it? OK! Copy it to an accessible path and do the following ...

Start Microsoft Visual Studio 2005, create a new Windows Forms VB.NET project, add a reference to the DLL you copied, and create a class and name it WebSite.

VB
Imports Microsoft.VisualStudio.WebHost
Imports System.IO
Public Class WebSite
    Inherits Server
    Implements IDisposable
' ...

This class I've inherited from Server, is the main class used for approaching the Web Server I was looking for. This class provides a constructor with these parameters: Port [the port you are going to use for your site], PhysicalPath [used for specifying the folder your site will be on], VirtualPath [which is used as your website virtual root], and Start and Stop methods to start and stop your service.

As you can see, the main idea and tool was what was mentioned above, all other things are done just for the GUI, finding a random available port, loading and saving configuration into an XML file, and etc.

Points of Interest

  • One of the things I encountered since developing is that the Server class which my WebSite class is inherited from has no writable properties to set the Port, PhysicalPath, and VirtualPath. They are all read-only properties!
  • But I needed to be able to change a particular website I've defined whenever I needed to. To solve this problem, I decided to create a shadow class named WebSiteData, which would be serializable and could contain all the properties from WebSite, and some other properties like a GUID, and a property named Enabled to store the started/stopped status of the website.

  • Another interesting thing is how I approached to find a random available port, and also checking the availability of a specified port:
  • VB
    Imports System.Net
    Imports System.Net.Sockets
    Public Class PortHelper
        Public Shared Function RandomPortAvailable() As Integer
            Dim _portAvailable As Boolean = False
            Dim _port As Integer = 0
            Dim _listener As TcpListener = Nothing
            Dim _rnd As New Random(Now.Millisecond)
            While Not _portAvailable
                _port = _rnd.Next(1001, 1999)
                Dim _ipEntry As IPHostEntry = _
                        Dns.GetHostEntry(Environment.MachineName)
                Dim _ipAddr() As IPAddress = _ipEntry.AddressList
                Try
                    _listener = New TcpListener(_ipAddr(0), _port)
                    _listener.Start()
                    _portAvailable = True
                    _listener.Stop()
                Catch ex As Exception
                    _portAvailable = False
                End Try
            End While
            Return _port
        End Function
        Public Shared Function IsPortAvailable(ByVal iPort As Integer) _
                As Boolean
            Dim _listener As TcpListener = Nothing
    
            Dim _ipEntry As IPHostEntry = _
                Dns.GetHostEntry(Environment.MachineName)
            Dim _ipAddr() As IPAddress = _ipEntry.AddressList
            Try
                _listener = New TcpListener(_ipAddr(0), iPort)
                _listener.Start() : _listener.Stop()
                Return True
            Catch ex As Exception
                Return False
            End Try
        End Function
    End Class

    TinyWebServer : properties window

  • And the thing is, I wanted to use the PropertyGrid object for my website properties dialog, so, I was looking for a way to enable a user to randomly find and select a free port through the PropertyGrid interface. As you can see, the UITypeEditor inherited class is the result.
  • VB
    Imports System.Drawing.Design
    Imports System.Windows.Forms.Design
    Imports System.ComponentModel
    Public Class PortEditor
        Inherits UITypeEditor
        Public Overrides Function GetEditStyle _
           (ByVal context As ITypeDescriptorContext) _
                As System.Drawing.Design.UITypeEditorEditStyle
            Return UITypeEditorEditStyle.Modal
        End Function
        Public Overrides Function EditValue(ByVal context As ITypeDescriptorContext, _
                ByVal provider As System.IServiceProvider, _
            ByVal value As Object) As Object
            Return PortHelper.RandomPortAvailable
        End Function
    End Class

    And a part of the WebSiteData class in which I defined the Port property:

    VB
    <Category("Service")> _
    <Description("Specifies the port, on which service will be available.")> _
    <Editor(GetType(PortEditor), GetType(System.Drawing.Design.UITypeEditor))> _
    Public Property Port() As Integer
        Get
            Return _port
        End Get
        Set(ByVal value As Integer)
            If PortHelper.IsPortAvailable(value) Then
                _port = value
                If _name.IndexOf("WebSite on Port:") > -1 Then
                    Me.Name = String.Format("WebSite on Port:{0}", _port)
                End If
            Else
                MessageBox.Show(String.Format("The port you specified, {0}, " & _
            "is busy by another process. try another.", value), _
                    "Alert", MessageBoxButtons.OK, MessageBoxIcon.Warning, _
                   MessageBoxDefaultButton.Button1)
            End If
        End Set
    End Property

History

  • Version 1.0.0.1: 17th Nov., 2007

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Iran (Islamic Republic of) Iran (Islamic Republic of)
I was born in 1982, Tehran, IRAN. I have been Programming since I was 11, and I'm experienced in :

1) Software Designing, Programming, Developing and Implementing.
2) Windows Forms based Solutions & Apps
3) Component Designing & Programming
4) Web Solutions and Apps
5) Webservices, XML platform developing
6) Smart Device Solutions & Apps
7) Database Solutions & Programming
8) ...

Some of programming languages and techniques, I've experienced :

[Most, are microsoft based. ]

*) BASICA [ Can you remeber ?! ]
*) GWBASIC
*) Microsoft Assembler
*) Turbo Assembler
*) Turbo Pascal 7.0
*) QuickBasic v4.5, v7.0
*) VBDOS v1.0
*) VB4WIN v1.0
*) VB v2.0 upto VB v6.0
*) VB.NET v1.0, v1.1, v2.0, 3.5, 4.0
*) C#.NET v1.0, v1.1, v2.0, 3.5, 4.0
*) ASP v3.0
*) ASP.NET v1.0, v1.1, v2.0, 3.5, 4.0
*) HTML, DHTML
*) VBScript
*) Javascript
*) jQuery
*) AJAX
*) CSS 1.0, 2.0, 3.0
*) XML
*) LINQ
*) SQL Server 2000, 2005, 2008
*) ...

Comments and Discussions

 
QuestionUsing Ip address instead of local host Pin
Member 1453745121-Jul-19 22:11
Member 1453745121-Jul-19 22:11 
QuestionI have downlaoded the code and while running it from my local machin, I am getting below mentioned exception, can you please help me on this Pin
Mahendra Vishwakarma7-Feb-14 3:57
Mahendra Vishwakarma7-Feb-14 3:57 
GeneralMy vote of 5 Pin
Member 194323517-Mar-13 18:24
Member 194323517-Mar-13 18:24 
GeneralMy vote of 5 Pin
Basarat Ali Syed5-May-11 20:02
Basarat Ali Syed5-May-11 20:02 
Awesome article. Read it a long time ago. Just wanted to update that there is now a portable version of IIS available called IIS Express. Read more here : http://www.basarat.com/2011/05/protable-iis-iis-express-75.html
Questiondata access? Pin
Mugutu1-Sep-09 0:55
Mugutu1-Sep-09 0:55 
GeneralMy vote of 1 Pin
popsy brown10-Mar-09 17:13
popsy brown10-Mar-09 17:13 
GeneralPhysical Path Drive Letter Pin
Micah Burnett19-Nov-08 7:26
Micah Burnett19-Nov-08 7:26 
GeneralRe: Physical Path Drive Letter Pin
Flominator11-Jan-09 22:50
Flominator11-Jan-09 22:50 
QuestionTinyWebServer quits with error Pin
ovi roatis19-Oct-08 3:57
ovi roatis19-Oct-08 3:57 
AnswerRe: TinyWebServer quits with error Pin
Flominator11-Jan-09 22:49
Flominator11-Jan-09 22:49 
AnswerRe: TinyWebServer quits with error Pin
xc2k12-Aug-10 6:34
xc2k12-Aug-10 6:34 
GeneralRe: TinyWebServer quits with error Pin
EverPresent2-Mar-13 19:43
EverPresent2-Mar-13 19:43 
QuestionWhat about asp files Pin
alymayoung15-Aug-08 11:05
alymayoung15-Aug-08 11:05 
General.NET Framework on CD/USB Flash Pin
AndrewMooney19-May-08 4:26
AndrewMooney19-May-08 4:26 
JokeRe: .NET Framework on CD/USB Flash Pin
Mehran Ghanizadeh20-May-08 9:30
Mehran Ghanizadeh20-May-08 9:30 
GeneralIsLocal is still limit Pin
martin.nedopil19-Nov-07 5:42
martin.nedopil19-Nov-07 5:42 
GeneralRe: IsLocal is still limit Pin
Mehran Ghanizadeh19-Nov-07 12:39
Mehran Ghanizadeh19-Nov-07 12:39 
GeneralYour search... Pin
Juergen Posny17-Nov-07 23:07
Juergen Posny17-Nov-07 23:07 
GeneralRe: Your search... Pin
Mehran Ghanizadeh17-Nov-07 23:57
Mehran Ghanizadeh17-Nov-07 23:57 
GeneralRe: Your search... Pin
Juergen Posny18-Nov-07 7:13
Juergen Posny18-Nov-07 7:13 
GeneralRe: Your search... Pin
per-i20-Nov-07 2:45
per-i20-Nov-07 2:45 
GeneralRe: Your search... [modified] Pin
Mehran Ghanizadeh20-Nov-07 8:37
Mehran Ghanizadeh20-Nov-07 8:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.