Created
September 11, 2012 13:07
-
-
Save darrelmiller/3698325 to your computer and use it in GitHub Desktop.
Some Web API techniques
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Net.Http; | |
using System.Web.Http; | |
using System.Web.Http.SelfHost; | |
namespace WebApiSelfHost | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var baseAddress = new Uri("http://localhost:8080/"); | |
var configuration = new HttpSelfHostConfiguration(baseAddress); | |
configuration.Routes.MapHttpRoute( | |
name: "DefaultApi", | |
routeTemplate: "api/{controller}/{id}", | |
defaults: new { id = RouteParameter.Optional } | |
); | |
var host = new HttpSelfHostServer(configuration); | |
host.OpenAsync().Wait(); | |
Console.WriteLine("Host open. Hit enter to exit..."); | |
Console.Read(); | |
host.CloseAsync().Wait(); | |
} | |
} | |
public class Foo | |
{ | |
public string A { get; set; } | |
public string B { get; set; } | |
} | |
public class Error | |
{ | |
public string Code { get; set; } | |
public string Message { get; set; } | |
} | |
// Helper class to allow actions that return HttpResponseMessage to easily embed CLR types | |
public class HttpResponseMessage<T> : HttpResponseMessage | |
{ | |
public HttpResponseMessage(HttpRequestMessage request, T value) | |
{ | |
var config = request.GetConfiguration(); | |
var contentNegotiator = config.Services.GetContentNegotiator(); | |
var connegResult = contentNegotiator.Negotiate( | |
typeof(T), request, config.Formatters | |
); | |
request.CreateResponse(HttpStatusCode.Accepted, value); | |
Content = new ObjectContent<T>(value, connegResult.Formatter); | |
} | |
} | |
// Return a HttpResponseMessage that has a strongly typed payload | |
public class FooController : ApiController | |
{ | |
public HttpResponseMessage Get() | |
{ | |
var value = new Foo() | |
{ | |
A = "Hello", | |
B = "World" | |
}; | |
return new HttpResponseMessage<Foo>(Request, value); | |
} | |
} | |
// Return an error message along with a status code | |
public class BarController : ApiController | |
{ | |
public HttpResponseMessage Get() | |
{ | |
return new HttpResponseMessage(HttpStatusCode.BadRequest) { ReasonPhrase = "You have failed"}; | |
} | |
} | |
// Return error message by throwing an exception | |
public class BazController : ApiController | |
{ | |
public Foo Get() | |
{ | |
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest ) {ReasonPhrase= "You have failed"}) ; | |
} | |
} | |
// Return an error message body by throwing an exception | |
public class BlahController : ApiController | |
{ | |
public Foo Get() | |
{ | |
throw new HttpResponseException(new HttpResponseMessage<Error>(Request,new Error() {Code = "911", Message="You failed"}) {StatusCode = HttpStatusCode.BadRequest} ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That's ok, by comparison different ways to do error handling in ServiceStack:
Also if you have a FooResponse DTO you also get typed, structured error handling back in the client: https://github.com/ServiceStack/ServiceStack/wiki/Validation e.g:
The error is just a serialized JSON / XML FooResponse DTO so can easily be read by dynamic clients as well.