Up until now we have used the browser to look at our data. In other words Nancy created a view for us and returned html to the client that requested that information. But wouldn’t it be nice if we could use the same for returning html and/or other formats like json or xml. It turns out to be very easy to do with Nancy.

The code can still be found on github.

Content negotiation

This can only work if Nancy is able to change the response based on the request. In other words content negotiation.

According to their wiki.

The content negotiation pipeline will inspect the incoming Accept headers and determine which of the requested media types is the most suitable and format the response accordingly.

The server

For this to work we need to change our Module just a little bit.

Lets take the treesmodule. And change the Get that returns all trees from this

MyBase.Get("/trees") = Function(parameters)
                                       Return View(New TreesModel() With {.Trees = treeService.AllTrees()})
                                   End Function
to this

MyBase.Get("/trees") = Function(parameters)
                                       Return Negotiate.WithModel(New TreesModel() With {.Trees = treeService.AllTrees()})
                                   End Function
Instead of returning a View I now use Negotiate.WithModel and that’s all the changes I made.

## Easyhttp client

YOu can now make a newproject and add easyhttp to that and read the list of trees like this.

Imports System.Net
Imports EasyHttp.Http

Module Module1

    Sub Main()
        Dim http = New HttpClient()
        http.Request.Accept = HttpContentTypes.ApplicationJson
        Dim trees = http.Get("http://localhost:55360/trees")
        For Each t In trees.DynamicBody.Trees
    End Sub

End Module

With this as the result.







And of course all this time the browser client will just keep on working like nothing happened.


We can now also change our second Get in that module to return the data based on the id. To this.

MyBase.Get("/trees/{Id}") = Function(parameters)
                                            Dim result As Integer
                                            Dim isInteger = Integer.TryParse(, result)
                                            Dim tree = treeService.FindById(result)
                                            If isInteger AndAlso tree IsNot Nothing Then
                                                Return Negotiate.WithModel(tree)
                                                Return HttpStatusCode.NotFound
                                            End If
                                        End Function
Again just change the return view call to return Negotiate.WithModel.


We can now add an easyhttp call like this.

Dim result = http.Get("http://localhost:55360/trees", New With {.Id = 1})
        Dim tree = result.DynamicBody

Sadly that won’t work. Because easyhttp translates that call to http://localhost/trees?id=1 and Nancy wants you to use routes instead. Like this http://localhost/trees/1 . I know how easyhttp does this too, since it was me who added that feature to easyhttp ;-). So I guess I will have to change easyhttp to use it this way.

Anyway if you change your easyhttp call to this

vbnet Dim result = http.Get("http://localhost:55360/trees/1") Dim tree = result.DynamicBody Console.WriteLine(tree.Id) Console.WriteLine(tree.Genus) it will work, until I have time to harass Hadi enough so that he does the change or (more likely) until I do the change myself.


It is extremely easy to make Nancy return the response formatted based on the request.