I am trying to POST to my ServiceStack service and retrieve the Location header from the response of my CREATED entity. I am not sure whether using IReturn is valid but I am not sure how to access the Response headers from my client. Can someone help me understand how to interact with the HttpResult properly? There is a test case at the bottom of the code to demonstrate what I want to do. Here's the codz:
public class ServiceStackSpike
{
public class AppHost : AppHostHttpListenerBase
{
public AppHost() : base("TODOs Tests", typeof(Todo).Assembly) { }
public override void Configure(Container container)
{
//noop
}
}
[Route("/todos", "POST")]
public class Todo:IReturn<HttpResult>
{
public long Id { get; set; }
public string Content { get; set; }
public int Order { get; set; }
public bool Done { get; set; }
}
public class TodosService : Service
{
public object Post(Todo todo)
{
//do stuff here
var result = new HttpResult(todo,HttpStatusCode.Created);
result.Headers[HttpHeaders.Location] = "/tada";
return result;
}
}
public class NewApiTodosTests : IDisposable
{
const string BaseUri = "http://localhost:82/";
AppHost appHost;
public NewApiTodosTests()
{
appHost = new AppHost();
appHost.Init();
appHost.Start(BaseUri);
}
[Fact]
public void Run()
{
var restClient = new JsonServiceClient(BaseUri);
var todo = restClient.Post(new Todo { Content = "New TODO", Order = 1 });
Assert.Equal(todo.Headers[HttpHeaders.Location], "/tada"); //=>fail
}
public void Dispose()
{
appHost.Dispose();
appHost = null;
}
}
}
See the Customizing HTTP Responses ServiceStack wiki page for all the different ways of customizing the HTTP Response.
A HttpResult
is just one way customize the HTTP Response. You generally want to include the Absolute Url if you're going to redirect it, e.g:
public object Post(Todo todo)
{
var todo = ...;
return new HttpResult(todo, HttpStatusCode.Created) {
Location = base.Request.AbsoluteUri.CombineWith("/tada")
};
}
Note HTTP Clients will never see a HttpResult
DTO. HttpResult is not a DTO itself, it's only purpose is to capture and modify the customized HTTP Response you want.
All ServiceStack Clients will return is the HTTP Body, which in this case is the Todo
Response DTO. The Location is indeed added to the HTTP Response headers, and to see the entire HTTP Response returned you should use a HTTP sniffer like Fiddler, WireShark or Chrome's WebInspector.
If you want to access it using ServiceStack's HTTP Clients, you will need to add a Response Filter that gives you access to the HttpWebResponse
, e.g:
restClient.ResponseFilter = httpRes => {
Assert.Equal(httpRes.Headers[HttpHeaders.Location], "/tada");
};
Todo todo = restClient.Post(new Todo { Content = "New TODO", Order = 1 });
Another lightweight alternative if you just want to inspect the HTTP Response is to use ServiceStack's Convenient WebRequest extension methods, e.g:
var url = "http://path/to/service";
var json = url.GetJsonFromUrl(httpRes => {
Assert.Equal(httpRes.Headers[HttpHeaders.Location], "/tada");
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With