Mittels Owin ist es einfach, statische Inhalte über einen Webserver zur Verfügung zu stellen. Dieser Beitrag zeigt, wie ein einfacher Fileserver implementiert wird und welche Möglichkeiten insgesamt zur Verfügung stehen.

In wenigen Zeilen kann mit Katana ein statischer Fileserver implementiert werden. Dazu benötigt man die Assemblies Microsoft.Owin.StaticFiles und Microsoft.Owin.FileSystems. Diese können als Paket einfach via NuGet (beide Assemblies enthalten) bezogen werden.

Der gezeigte Code basiert auf der Katana-Version 2.1.0.

Dateien zur Verfügung stellen

Mit diesen Zeilen Code können Dateien zur Verfügung gestellt werden:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var root = AppDomain.CurrentDomain.BaseDirectory;
        var staticFileOptions = new StaticFileOptions()
        {
            RequestPath = new PathString("/web"),
            FileSystem = new PhysicalFileSystem(Path.Combine(root, "Client"))
        };
        app.UseStaticFiles(staticFileOptions);
    }
}

Der RequestPath beschreibt den virtuellen Teil in der URL. Läuft der Server also unter localhost:15000 würde der Zugriff im Beispiel via localhost:15000/web/{dateiname} möglich sein, wobei {dateiname} mit der eigentlichen Datei zu esetzen wäre. Via FileSystem wird das physische Verzeichnis im Dateisystem angegeben.

Für den Start wird folgender Code verwendet:

class Program
{
    static void Main(string[] args)
    {
        var apiUri = "localhost:15000";

        using (WebApp.Start<Startup>(apiUri))
        {
            Console.WriteLine("Listening on " + apiUri);
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }
}

Unter der Annahme es existiert nun eine Datei index.html im Unterverzeichnis Client würde die URL localhost:15000/web/index.html die gewünschte Datei zurück liefern. Ein Aufruf ohne der HTML-Datei würde jedoch einen HTTP Status Code 404 (Not Found) ergeben, da Standarddokumente nicht unterstützt werden.

Standarddokumente unterstützen

Mit Hilfe der Klasse DefaultFileOptions können entsprechende Einstellungen vorgenommen werden. Da Standarddokumente für definierte Request-Pfade zu setzen sind (diese müssen mit den StaticFileOptions identisch sein), sollten wir die Klasse SharedOptions verwenden:

var sharedOptions = new SharedOptions()
{
    RequestPath = new PathString("/web"),
    FileSystem = new PhysicalFileSystem(Path.Combine(root, "Client"))
};

Diese können nun allen weiteren *Options übergeben werden:

var defaultFileOptions = new DefaultFilesOptions(sharedOptions)
{
    DefaultFileNames = new[] { "index.html" }
};
app.UseDefaultFiles(defaultFileOptions);

In diesem Fall wird index.html als Standarddokument gesetzt und anschließend registriert. Ab sofort sollte unter der URL localhost:15000/web die index.html zu sehen sein – sofern vorhanden.

Besonders wichtig ist die Reihenfolge der Registrierung. UseDefaultFiles muss unbedingt vor UseStaticFiles gesetzt werden, da diese Einstellung sonst nicht berücksichtigt werden würde.

In der Kürze liegt die Würze

Die gesamte Owin-Middleware kann auch via UseFileServer geschalten werden. Hierzu stehen eigene FileServerOptions zur Verfügung. Diese definieren, welche Middleware tatsächlich zum Zug kommt.

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var root = AppDomain.CurrentDomain.BaseDirectory;
        var fileServerOptions = new FileServerOptions()
        {
            EnableDefaultFiles = true,
            EnableDirectoryBrowsing = false,
            RequestPath = new PathString("/web"),
            FileSystem = new PhysicalFileSystem(Path.Combine(root, "Client"))
        };
        app.UseFileServer(fileServerOptions);
    }
}

Fazit

Dieser Beitrag hat gezeigt, wie Dateien über einen Fileserver zur Verfügung gestellt werden können. Auch die Konfiguration von Standarddokumenten wurde gezeigt. Die gezeigte Funktionalität lässt sich auch zusammen mit der Web API nutzen, wodurch weitere Möglichkeiten gegeben sind.

Über den Autor

Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler und Fotograf. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.