How to get full power from WebApi
-
Upload
raffaele-rialdi -
Category
Technology
-
view
2.141 -
download
0
description
Transcript of How to get full power from WebApi
How to get full power from WebApi
Raffaele Rialdi@raffaeler
http://iamraf.net
Thanks to the sponsors
What is WebApiin one slide
• A library to create HTTP services– HTTP is highly scalable (disconnect, cloud, …)
• Designed to create REST services– WebApi does not automatically imply REST– Use HTTP as an application (not a transport) protocol
• Fits in heterogeneous device/OS scenarios– Avoid typical SOAP versioning problems– It's highly pluggable
• Leverages the Asp.net MVC 4 model
WebApi is flexible
• oData is a work-in progress– look at nightly builds, avoid current pre-release
• Can be Self-Hosted outside IIS and MVC4– Easy way for inter-AppDomain or inter-Process– Console example:
var config = new HttpSelfHostConfiguration("http://localhost:8000");
config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",new { id = RouteParameter.Optional });
using (HttpSelfHostServer server = new HttpSelfHostServer(config)){
server.OpenAsync().Wait();Console.WriteLine("Press any key to exit");Console.ReadKey();
}
THE REQUEST JOURNEY
Routing to a Controller
• Use the standard MVC Routes– extract Controller, Action and parameters
• Controller selection under the hood– IHttpControllerSelector.SelectController• HttpRequestMessage HttpControllerDescriptor
• Plug-in Controllers using IDependencyResolver– Nuget has a lot of ready to use IoC containers
controllerRequest
Selecting an Action
• The easiest way is to modify the default Route
• Can use [ActionName("myaction")]– override the method name as the action name
• Can use [NonAction]– exclude a method from being an action
config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional }); config.Routes.MapHttpRoute(
name: "DefaultApi2",routeTemplate: "api/{controller}/{action}/{x}/{y}" );
actioncontrollerRequest
Selecting an Action by code
• Derive ApiControllerActionSelector– override SelectAction
• Implement IHttpActionSelector– Implement SelectAction– Obtain the previous selector in ctor– Call previous selector
• In SelectAction method:– in: HttpControllerContext– out: HttpActionDescription
actioncontrollerRequest
Use case:Versioning!
Authorization filter
• [Authorize] is Role oriented• Derive AuthorizeAttribute to go Claim
oriented• [AllowAnonymous] is self-explanatory• Starting from Fx4.5 new universal base classes
– ClaimsPrincipal for every Principal– ClaimsIdentity for every Identity
IPrincipal client = Thread.CurrentPrincipal;
ClaimsPrincipal principal = Thread.CurrentPrincipal as ClaimsPrincipal;ClaimsIdentity identity = principal.Identity as ClaimsIdentity;
authoriz.Request actioncontroller I’ll play withClaims
Security considerations
• WebApi authorization model is not built-in– AuthorizationFilters / MessageHandlers are used
to plugin the desired mechanism– Per-route handlers gives finer control
• Use Filters/Handlers to add/modify claims
Model Bind
• IValueProvider (Bind3 example)– useful to populate an action parameter– Require a ValueProviderFactory (applied via attribute)
• HttpParameterBinding (Bind4 example)– Associate a type to a provider
• IActionValueBinder (Bind5 example)– Associate an HttpActionDescription to a provider
• DefaultActionValueBinder (Bind6 example)– Intercept default provider
• IModelBinder (Bind7 example)– Execute the binding. Must provide the value
bindingRequest authoriz.actioncontroller
Action Filters
• Called before and after the action execution
• Implement IActionFilteror better….
• Derive ActionFilterAttribute– OnActionExecuting– OnActionExecuted
action filter
action filterRequest bindingauthoriz.actioncontrollerRequest bindingauthoriz.actioncontroller
Use case:validation & auditing!
Target was reached!
• In the action we have different options:– return an entity that will be embedded in a response– build and return the HttpResponseMessage
• Can be an error (no exceptions imply better performances)
or– throw a CLR exception (a filter will convert it in a msg)– throw an HttpResponseException
• returns the HTTP status code of your choice• it's a full response (specify Content, Headers, ReasonPhrase)
action filter
invokeaction
action filterRequest bindingauthoriz.actioncontrollerRequest bindingauthoriz.actioncontroller
HttpError
• Nice way to create the error message– Errors flow in the same way of the content– Keys/Values can be added for additional infos
var msg = string.Format("Product with id = {0} not found", id);HttpError err = new HttpError(msg);return Request.CreateResponse(HttpStatusCode.NotFound, err);
HTTP/1.1 404 Not FoundContent-Type: application/json; charset=utf-8Date: Thu, 09 Aug 2012 23:27:18 GMTContent-Length: 51
{ "Message": "Product with id = 12 not found" }
var msg = string.Format("Product with id = {0} not found", id);return Request.CreateErrorResponse(HttpStatusCode.NotFound, msg);
Action filter
• Same filter of the request• OnActionExecuted
action filter
invokeaction
Exception Filters
• Do not use MVC [HandleError]• Transform CLR exceptions in HTTP messages• Implement IExceptionFilter or better derive
ExceptionFilterAttribute• Mark actions with the attribute
or• Change the global configuration– GlobalConfiguration.Configuration.Filters.Add(new
MyNamespace.NotImplExceptionFilterAttribute());
exceptionfilter
action filter
invokeaction
Formatting data for the output
• MediaTypeFormatter is the abstract base class to serialize entities in whatever format
• Built-in formatters:– Json.net and Xml formatter are built-in– bson and many others on nuget– your own just deriving this class
• The correct formatter is picked up upon "http content negotiation"
Response formatting exceptionfilter
action filter
invokeaction
GOING DEEPER
Message Handlers
• Message Handlers works at the beginning of the pipeline– They can use the message and pass it over– Or can "short-circuit" to the response (early validation)
• MH still don't know the controller, action, etc.• Every endpoint has different MH instances• Typical usage:
– Early validation of the message / headers (security keys)– Packet inspection
RequestRequest HttpControllerDispatcher
HttpRouting
Dispatcher
customMessageHandler
HttpServer ControllerResponse
Wrap up
• Webapi = extreme pluggability• Just follow the request– Before or later it will become a response
Questions?
Please rate this sessionScan the code, go online, rate this session