Search code examples
nancy

Add additional Link header


This may be a stupid question, but how is it possible to add an extra Link header to a response in Nancy?

I can't do that

context.Response.Headers.Add("Link", "value");

because that fails if there is already a header set. I also cannot use the extension

context.Response.WithHeader("Link", "value");

because it replaces any preexisting headers.

So isn't there a convenient way to work with multiple headers?


Solution

  • This is what I do with an extension method. Notice the check to see if the Link header already exists

        public static Response AsCreatedResourceWithLinks(this IResponseFormatter formatter, Resource resource)
        {
            return CreateResponse(formatter, resource.Id.ToString(), resource.Links);
        }
    
        private static Response CreateResponse(IResponseFormatter formatter, string id, IEnumerable<ResourceLink> links = null)
        {
            string url = formatter.Context.Request.Url.ToString();
            var response = new Response { StatusCode = HttpStatusCode.Created, Headers = { { "Location", url + "/" + id } } };
    
            if (links != null && links.Any())
            {
                foreach (var resourceLink in links)
                {
                    var link = "<" + url + "/" + resourceLink.Link + ">; anchor=\"" + url + "/" + resourceLink.Anchor + "\"; rel=\"" + resourceLink.Rel + "\"";
                    if (response.Headers.ContainsKey("Link"))
                    {
                        response.Headers["Link"] += "," + link;
                    }
                    else
                    {
                        response.Headers.Add("Link", link);
                    }
                }
            }
    
            return response;
        }
    

    The Resource & ResourceLink classes look like so:

    public class Resource
    {
        public int Id { get; set; }
        public List<ResourceLink> Links { get; set; }
    }
    
    public class ResourceLink
    {
        public string Link { get; set; }
        public string Anchor { get; set; }
        public string Rel { get; set; }
    }
    

    The usage is then like so:

    Post["/"] = _ => 
    { 
      //Returns Id and Links for Location/Links headers 
      var resource = something.SaveResource(); 
    
      return Response.AsCreatedResourceWithLinks(resource);`
    }