# self hosting WebApi

This is just a short howto as I think it might come handy, as I struggled a bit on some points.

I needed a simple way to self-host a REST-like service (returning XML data) with fine control on the structure of the results.
I had a look at Nancy and others but finally choose to use Microsofts WebApi as it’s fine for what I am trying to do.

## preparing the solution

First thing to do is grab the nuget-package Microsoft.AspNet.WebApi.SelfHost.
In addition I needed references to System.Xml as I want to use XmlDocument.

## helper class for XML content

I want the replies to have content type text/xml (instead of application/xml) and the only way I found is to use a helper class:

type XmlContent (document : System.Xml.XmlDocument) =
inherit System.Net.Http.HttpContent ()

let _stream = new System.IO.MemoryStream ()
do
document.Save _stream
_stream.Position <- int64 0
("text/xml")

override this.SerializeToStreamAsync
( stream : System.IO.Stream
, context : System.Net.TransportContext) =
async {
_stream.CopyTo stream
return ()

override this.TryComputeLength (length : byref<int64>) =
length <- _stream.Length
true

override this.Dispose (disposing : bool) =
base.Dispose(disposing)
if disposing then
_stream.Dispose()


As you can see you create an instance of this given a XmlDocument and it just saves this to the output-stream using the right content-type (for me).

In addition I need the reply to have a XML declaration like <?xml version="1.0" encoding="UTF-8"?> so I added these two helpers (the second giving you a simple clue on the usage):

let respond
(fillResult : System.Xml.XmlElement -> unit)
request =

fillResult element

let msg = new System.Net.Http.HttpResponseMessage ()
msg.RequestMessage <- request
msg

let respondText (text : string) =
respond (fun element ->
element.OwnerDocument.CreateTextNode text
|> element.AppendChild
|> ignore)


## the controller

Nothing special here – a simple one like this will do:

type RootController() =
inherit ApiController ()

[<HttpGet()>]
member this.Echo (echo : string) =
this.Request
|> respondText echo


## setting up the self-hosting

I use a simple console application for this and so the Program.fs just looks like:

open System
open System.Net
open System.Web.Http

open System.Web.Http.SelfHost

[<CLIMutable>]
type Route = { controller : string; action : string }

[<EntryPoint>]
let main argv =
try
use config = new HttpSelfHostConfiguration
("http://localhost:8083")
config.Formatters.XmlFormatter.UseXmlSerializer <- true
config.Routes.MapHttpRoute (
"default",
"{action}",
{ controller = "Root"; action = "Echo" } )
|> ignore

use server = new HttpSelfHostServer(config)
server.OpenAsync().Wait()


• it might not be strictly needed here but in case I don’t use the respond function I added UseXmlSerializer to get a nice way to serialize F#-records and stuff (just add [<CliMutable>]).
• the try/with is just there to give me a handle to ex – to some reason if the debugger breaks int a AggregateExcpetion VS2013 will no longer show me the detail of it 🙁
• you will have to run VisualStudio (or the program) as an local administrator – if not the URL rewrite will fail with an AggregateException.