Intro ASP.NET Web API
-
What
So what is the ASP.NET Web API? It is fairly well-named. It's an API that allows you to build web or HTTP-based endpoints, both client and server endpoints on top of ASP.NET. Now if you've been following this space for a while, the space being HTTP programming and the .NET Framework, most of the client-side HTTP-based programming model has been built into system.net and the server-side HTTP programming model, at least when we're talking about services versus serving up HTML, has been handled by Windows Communication Foundation or WCF. In the first version of WCF, there really wasn't much in terms of real HTTP-based endpoints. We could build SOAP-based endpoints, but SOAP really isn't built to take advantage of many of the features of HTTP, things like caching, and other compression, other HTTP-based features. So it wasn't until WCF sort of 2.0, which came out with .NET 3.5, had additional web programming or HTTP programming models and a framework and that was a pretty good framework for building many sort of simple HTTP-based endpoints, but it turned out to be fairly limited. It was kind of limited from one point of view because it was still very much embedded with WCF and the WCF way of doing things, which was although flexible, still sort of highly geared towards SOAP in many ways. And so, what happened was is that the WCF team went off to build sort of a new version of their HTTP-based programming stack and for various reasons it just made the most sense to Microsoft to merge the HTTP server-side programming model really into the ASP.NET team because they had been doing a lot of work in that area, although, mostly again, based upon returning HTML content types, still many of the features that the web API would or you'd want a web API to take advantage of were already built into ASP.NET. ASP.NET now has this routing capability, which allows more flexible URIs, which was one of the things that some people didn't like about the WCF programming model. So with ASP.NET MVC 4, you can use the server-side programming model to essentially build HTTP-based endpoints. It's not really linked to MVC so much, although, there's a lot of similarity with MVC. You can use the ASP.NET Web API in a Web Forms project, in an MVC project, you can download it and make it available to your projects via NuGet, which is a nice way of making sure you have the most recent versions of everything and maintaining the right versions of assemblies between different clients. And again, it also includes a new HTTP client. The whole programming model really is flexible, very extensible, and really geared towards if you want to build just a very straightforward HTTP endpoint or if you want to consume HTTP-based endpoints, the server and client are both there essentially to help you do that in a much more structured way and a much more flexible way.
-
Why
So the why is actually pretty straightforward. Most of you I assume watching this course are watching it because you want to use the web API and you're really looking for more of the what and the how, but some people may be watching this course and just trying to learn about what the web API is, maybe thinking about why they would use and build just a straight HTTP endpoint. You know if you're building services today for an HTML5 application, a mobile application, even a client-server desktop application, all these different types of applications need services, right? Regardless, client server, mobile, HTML5, they all need some form of services in the back-end to provide data or functionality, whatever the case may be, however you've architected your system. Now again, as I mentioned in the last section, when we talk about building services in the Microsoft programming stack, for many years, Microsoft sort of geared us towards building SOAP-based services, which have you know many features that are useful in many different scenarios, but for the most part when we talk about sort of the modern programming landscape and building services that can be easily consumed by the most number of clients, so the most number of different clients, or different mobile applications, or different HTML5 applications, we're typically talking about building things that are just purely based upon HTTP. Typically, they are going to return, especially in the HTML5 application case, they're going to return JSON instead of XML versus let's say something like a SOAP XML, and just in terms of the way the industry is going, this has become more likely to be the default than let's say building a WCF-based SOAP service.
-
Is this REST
Now one of the things that people will talk about in terms of this API and just in general when you start building HTTP-based endpoints and services, they will ask well is this REST, can we call this a REST service, and I'm sure your marketing department if you're building something commercial or to satisfy certain pointy-haired bosses calling this REST probably makes a lot of sense. Feel free to have my permission to go ahead and do that. Whether what you end up building with the web API is RESTful or not will depend on whether or not you meet the architectural style requirements of REST. These were laid down in a PHD dissertation by a guy named Roy Fielding. There's plenty of resources in the Pluralsight library, as well as outside the Pluralsight library about how to build RESTful services and what really a RESTful service means, what are the constraints of a RESTful service. The web API doesn't stop you from building a RESTful endpoint, which is nice. It makes it probably easier than the old WCF HTTP API did in terms of building a service that comports with the architectural style of REST and all the constraints that make up that architectural style. If you want to build a RESTful endpoint, you definitely can. This particular course is not really about building RESTful endpoints, it's just about using the framework, but again if you want to build a RESTful endpoint, you'll first have to learn how to use the framework.
-
Versus the WCF Web Framework
Now I mentioned WCF a few times. Certainly, the WCF HTTP programming model still exists. A question that I often get when I'm talking to people about this web API framework is well should I use the ASP.NET Web API or should I use WCF? There's a couple of different ways to look at this. One way to look at it is, okay well what do your developers know, what are they used to? And if you have a number of developers that are used to ASP.NET, and let's say especially ASP.NET MVC, I probably would just tend towards using the ASP.NET Web API. Now remember, you need to use .NET 4 in order to be able to use the ASP.NET Web API, so you may be limited to .NET 3.5 in which case you're going to go to WCF. Another reason to use WCF would be if you're also exposing SOAP-based services. So let's say that you're building something that maybe a number of different client applications are going to use, you may have some endpoints that are HTTP, just regular HTTP, some that are HTTP SOAP or other protocols in SOAP, and if you're doing that, it kind of makes sense to have one model for building your server-side applications. So picking which model to go with going forward, again, is going to be dependent on what are you trying to build and what are your limitations both in terms of .NET framework and your developers. I think it's pretty safe to say if you can go with ASP.NET Web API, I probably would go with the web API just in terms of resources. Now going forward, Microsoft seems very focused on adding resources and building out the web API. The HTTP-based part of WCF, not so much. If only because they've now come out with the ASP.NET web API. It's sort of superseded that part of the WCF framework. Not that WCF is going to go away, but probably will concentrate more on other parts of WCF and continuing to build on the WS start specifications as they come out and are built. So again, if you're doing HTTP, probably go this way. If you are stuck on other versions of .NET or if you feel like using the WCF Web Framework that makes more sense. Certainly nothing wrong with that. It's going to continue to be supported for quite a long time.
-
Demo - Basics
Okay, so now I'm going to show you a demo of getting up to speed using the web API. And I'm going to go to Visual Studio. I'm using Visual Studio 2012, but if you are on 2010, everything I'm showing you should work pretty much the same. I'm going to go ahead and go to Visual C# and Web Projects, and I'm going to go ahead and put this project in a place that I can put it up for you guys later on the site. I'm going to go ahead and call this HelloWebApiDemo. Now notice the template I picked was an empty ASP.NET website. As I said in the lecture part of the module, you can use the web API from any ASP.NET application, and of course, you can self-host it as well. Getting the web API into your project is as easy as going to NuGet. So I'm going to right-click on the project and go to Manage NuGet Packages. I'm going to go online and just search for web-API and this NuGet package, Microsoft.ASP.NET.WEB API is the package I can install. It will install all of the assemblies that I need. So essentially, sort of automatically into my project gives me all the pieces I need in order to be able to use the web API. I have to accept the agreement. And after this installed, I can close the NuGet window. And if I look at my references, you can see that I've got a number of references that were added under System.Net and System.Web.Http and Http.Webhost, so that's where the web API infrastructure lives. So I'm going to go ahead and add a new class to this project and I'm going to call it HelloApiController. Again, the convention inside of ASP.NET hosting, and we'll talk more about this throughout the course, is that you're going to have a controller class that's going to derive from a base class called ApiController that is in the System.Web.Http namespace. And I'm going to go ahead and add a method. So I'll add a method that returns a string, the method name will be Get, and I'll say return Hello from API at, and then I'll add DateTime.Now.ToString just so we can see that it's actually executing it. Okay, so now I have the convention part of the setup done to use the web API. But the other part that we need to use the web API is the ASP.NET routing. So we've got to tell the ASP.NET routing infrastructure that based upon some URL coming into this website, we want that URL to resolve to this particular controller. So what I'm going to do is I'm going to go ahead and add a global.asax to this project and inside of the global.asax Application_Start, I'm going to go ahead and modify the configuration. So I'm going to go to GlobalConfiguration, which is a class that's also in System.Web.Http and I'm going to go to configuration, which is the static sort of uber instance of the configuration for the web API, and I'm going to go to Routes, and I'm going to say Add. I'm going to add, I'm just going to call it default, it doesn't matter what I call it, and I'm going to add a new HTTP route. This is in the System.Web.Http.Routing namespace. So the route, there's a number of different overloads. I'm just going to use the overload right now that takes a route template, and so I'm going to use a typical route template that's very common if you've, should look very familiar if you've ever done ASP.NET MVC or anything like that. And so what this has done it's basically said hey I'd like to add a new route with the name of default and here is the route information. So what ASP.Net routing's going to do when it sees a request come in that matches this particular pattern, it's going to route it to the appropriate controller, which in this case will be my Hello API Controller. So that build succeeded. I'm going to go ahead and right-click and say View in Browser. Now I get a forbidden. But what I really want to do is I really want to do /HelloApi. If I go over to Fiddler, which I have running, which I highly recommend that you go to fiddlertool.com and download Fiddler if you already don't have it. If I go look at Fiddler and look at the raw response, I can see Hello from API at this particular time and this particular date. The other cool thing about Fiddler for testing the web API is if I drag and drop a request over to the Composer tab, I can execute this request over and over and over again or execute additional requests by changing the verb from Get to Post, to Put, or Delete, I can change the URI, and this system, let me just add one more thing to this particular project before I move on to another project. I'm going to add another class. I'm going to call this second controller. Just to demonstrate the nature of the route, I'm again going to derive this from ApiController and do another public string Get. I'm not going to return anything interesting, just This is the Second Controller. So build succeeded. Now I can go back over here and if I replace HelloApi with Second, you can see that I get a response that says This is the Second Controller. So that first part of the URL is matched against the routing, the name of the URL that path segment is taken, and then they resolve that looking for a class called whatever that replaceable token is, controller, so HelloApiController, Second Controller, and that's how the routing works. And let me do one other thing over here in Fiddler since I'm here is notice that the Accept header here in terms of content negotiation basically says text/HTML,application/xhtml+XML and then */*. Sorry. That basically means I would like HTML first, xhtml second, and then anything. Now what if I wanted specifically XML? Remember I said content negotiation for XML and JSON work automatically inside of ASP.NET Web API. So if I change the Accept header to application/XML, if I look at its response then, notice I'm getting back XML. The headers are going to tell me that the Content-Type is application XML, and if look at the raw result, we can see there's my XML string. Now I wanted to start with an empty project just to give you the feel of what are the basic parts that make up using the web API in ASP.NET and they are the routing and the API controller. They're dependent on each other, right, we need both things in order for the default convention of things in ASP.NET Web API, at least for ASP.NET hosting to work. Now I just want to for completeness go to New Project, and go to MVC 4 Web Application. I'm going to call this HelloApiTemplateDemo. Because when I pick ASP.NET MVC 4 project, one of the templates I get is Web API, so it's going to create a web API project for me or for you when you run this and I just want to show you this so that you can see what gets generated by the project template by default and sort of put together the pieces of what I just talked about in terms of the way that this one works. So by default, it adds a controller called the ValuesController. And now the ValuesController notice it has a GET that returns an IEnumerable so that by itself will get to the root of this whatever the route is for this controller will return two strings. If I do GET on a particular id, I'll get back a value. If I do PUT or DELETE, I can delete or add a value. Now I could make this a little bit more interesting to work with if I said let's create a list of strings and I'm basically going to create a new list of strings here, so var ret = new List of string and let's go ahead and populate it with the same data that the default template does. (Typing) And now here let's say return data and then the individual get for an individual id let's say return data, let's say the id is the index. If we do a Post, let's go ahead and add a new value, so let's say data.Add value. If we're going to do a PUT, we just replace the value at a particular index so data id = the value. And if we were going to remove let's say data.RemoveAt index. Okay, so I've just modified the controller a little bit just so that we can play with the different verbs, not just get, but also Put, Post, and Delete. So let's leave that for a moment and just remember that this value's controller was added for us automatically when I created this project. And then let's look at the other piece, which is the routing. Now the routing, they don't put in the global.asax.cs anymore. This is true for all MVC projects. They've got a static class called WebApiConfig.Register, and if I look at the App_Start folder, there's a WebApi.config class, so here's this static Register method. And notice what the config.Routes.MapHttpRoute. This is actually an extension method, so MapHttpRoute simplifies the code that I showed you in the last part of my demo. And so here we specify the name, the routeTemplate, and any defaults. Now notice the route template here starts with api/controller. Some people think that you have to have API in order for this to work and you don't, you absolutely don't. The reason that you might want to keep this convention of the api/controller that they put into this project type is that if you want some MVC routing to coexist with API routing, it just makes it much cleaner if MVC view routing is done at the root and API routing is done from a /api. That's basically the reason that they have done this. So those are the two things that are a little bit different here. Now of course, if I right-click here and say View in Browser, what I'm going to get is something much different than what I got in my simple empty project because it's talking about web-API. So essentially they have this Helper page, this nice looking page for you to go get information about the web API, which is useful. I'm going to go ahead and go to api/values. So remember api/values was the mapping of routes to a particular controller. The API part came from the route template and the controller part is, of course, replaceable via that path segment and then the web API looks for a controller with that name, finds it, loads it, and then returns a result. If we go look at Fiddler, we can see that here is my result, so those are my two values. So now what if I want to do something like I want to get a particular value, so let's go ahead drag and drop this up here. Let's change the Accept to be more specific, so let's say application/XML and I'm going to say values/1. So if I do values/1 and then execute, I see I can get value2 and if I do value/0, it should be the 0 index, I get value1. And so that's pretty cool. What if I want to add a value? So if I want to add a value, I'd go to the values endpoint, I'd do a post instead of a get. I don't really need an Accept header, although, I can ask for a particular response type. What I do need is a content type header, so I need to say what is the Content-Type I'm asking for and this is actually perfectly valid. I can say I'm sending you JSON, but I would like XML back. It would be a little odd to maybe do that in real life, but it certainly is possible. So I'm going to go ahead and add a request body and this is going to be a simple string, so Hello API and I'm going to go ahead and execute. So I get back a 204 No Content, which basically means you know it didn't return anything. If I go look at the composer again and I change this back to a get, I have to remove the Content-Type, I have to remove the request body because you don't send a request body on a get, and execute. I should be able to look and I should see three strings, so string value1, string value2, and string Hello API. What if I would like to delete one of these? Let's go ahead and delete the first one. So I'm going to say DELETE /0 and execute and it's perfectly happy with that. There's no content that returns. And if I change the request back to a GET on values, and let's say that I would like JSON now instead of XML, and look at the response, value2, Hello API. Okay, so there's a simple example demo of doing both, again, sort of the simple approach from the ground up of the web API in an ASP.NET app and also sort of exploring the default template a little bit.
-
Routing
Okay, so let's talk a little bit more about how the ASP.NET Web API works. As I mentioned earlier, one of the key parts of ASP.NET that the web API takes advantage of is ASP.NET routing. So what ASP.NET routing does is it maps URIs, incoming URIs, and verbs to a class that you create, and specifically, to a method on the class that you create. This class is known as the controller. So in some ways the web API follows at least some parts, at least from a nomenclature point-of-view, of the MVC pattern. Your controller has to derive from a base class that's known as the APIController, so there's a common base class for when you're building and using the web API inside of ASP.NET. In terms of mapping routes, there's a new extension method called MapHttpRoute, so it allows you to essentially register a different handler, and when you register that different handler, it's going to make the difference between the URI and verb getting routed let's say to some MVC controller versus getting routed to the APIController. So this little bit magic, the HttpControllerHandler takes care of. If you don't like mapping URIs and verbs to your methods, you can change this in the web API. Again, as I said earlier, one of the major design goals of the web API was to make everything very extensible, which means you can replace almost everything. And so if you want to handle incoming HTTP requests in a different way, you can actually replace that. If you're doing self-hosting, self-hosting makes it really very easy to replace that routing mechanism, and if you're interested in that, you can go ahead and take a look at the hosting module, which we'll go into detail on that. Or inside of ASP.NET, you can replace it with your own handler, and therefore, you can change the way things are routed to controllers and methods.
-
Assemblies
So just a quick list of the assemblies. Again, most of the time when you're adding the assembly references to your projects when you want to use the web API, you're either going to use one of the Visual Studio project templates, which will add them automatically, or you'll use NuGet, which will also add the appropriate assemblies automatically. But in terms of just making things clear, we've got System.Net.Http, that's where the client is and raw messaging types are. Formatting is where media type formatters live and the model binding facilities. We'll talk more about that quite a bit. The basic hosting infrastructure is in System.Web.Http, so that's just basic hosting infrastructure. All the common APIs are in System.Web.Http.Common. ASP.NET hosting is in System.Web.WebHost. Self-hosting is an assembly called SelfHost. There is a System.Web.Http.Data. This has a special data controller we'll talk about later how it differs a little bit from the APIController, which is its base class. There is an EntityFramework version of the DataController, again we'll talk about that. And then Helpers for the data API are in System.Web.Http.Data.Helpers.
-
Convention or not
Now one of the things that you saw in the demo in earlier in this module is that one of the things about the web API, one of the design goals was very simple to use. So they had to come up with some way of saying okay how are we going to map a particular URI and a particular verb to you know a particular method on a class on your controller class. And again the way they came up with the sort of convention is just to say you know if you have a URI, API, pardon my drawing here, .foo, that's going to look for a controller called foo controller, and if this is a Get request, an HTTP GET request, it's just going to look for a method that's called GET. Right, it's going to assume you have a method on your controller class that has the name Get and the same with Put, Post, Delete. You can follow this convention or you can annotate your method names with attributes and remap your method names to different verbs than would normally happen. Now if you want to redirect different URIs to different classes differently than the convention, that's when you're going to have get involved on a little bit more of the plumbing, but in particular, this part of the plumbing, the mapping of verbs to your controller class you can replace just by changing attributes and we'll talk about that more later in the course.
-
Model binding and Formatters
Now one of the other nice things, of course, that all of these different network, frameworks, programming frameworks do like WCF and ASP.NET MVC. They map incoming network messages into .NET types. That way we don't have to deal with low level you know streams of data, streams of XML, or streams of JSON, or streams of form, encoded data. This is part of what the underlying framework does for us. So the web API will just by you adding type definitions to your parameters figure out how to take those parameters and turn them into .NET types. The parameters can come from the body of the HTTP message, from the header, or the query string. In many ways, it's very similar to the MVC model binding, if you're familiar with that, and in fact, some of the framework will use the same rules as ASP.NET MVC, but the web API takes things a little bit further. One of the things that the web API does in terms of a serialization is instead of just using regular model binders, they will also use something called a MediaTypeFormatter. And MediaTypeFormatters are mapped to content types, so this allows you to be able to let's say accept a post of incoming data let's say in both JSON and XML. And what the framework will do is it will look at the Content-Type of the post, it'll look at that header and say oh, well this is application/XML, let's find the MediaTypeFormatter that deals with application.xml, it will read in the body, and it will then turn it into the appropriate .NET object based upon your definition. If a post comes in you know milliseconds later that is JSON, application/JSON, well then it will find the MediaTypeFormatter for that. So MediatypeFormatters are both for input and output. I just described input, but the same settings happen for output. Are the objects that take care of turning incoming messages into .NET objects and turning .NET objects into outgoing messages based upon media types. So again, very HGP-friendly. It's one of the underlying sort of cool features of HTTP is its ability to be able to have different content types. We can also do additional validation that goes along with that. And again, if you want to move down the stack and deal with things at a lower level, you can use the HttpRequestMessage and the HttpResponseMessage. These two classes can allow you to go down to that lower level and be able to deal with the message directly, although, you still can do formatting and serialization if you use these objects. Typically you use them if you want to have more control over additional headers and things like that. We'll go into that again like many of these other features in more detail later in this course.
-
Content negotiation
Now something that is highly related to this idea of content types and media types is content negotiation. So content negotiation, unlike my earlier example of the post where the post in my first example was XML and the second example was JSON and I said the MediaTypeFormatter system in ASP.NET Web API will take care of that for you in terms of serializing both kinds of data into the proper .NET object. When you return an object, it may be that the client has asked for that object in a particular format. So again, the client may have said hey I'm sending you format coded data, but I would really like JSON back. Totally the goal in HTTP and the web API takes care of this for you automatically. So based upon the content-type, it's just going to do this automatically. You are able to configure content negotiation in additional ways other than the Accept header. A couple of ways that a lot of people like to do additional content negotiation is with a file extension, so .xml and .json. This is for situations where sometimes clients, depending on the environment they live in, can't change headers, so they can't change the Accept headers or query string. These are the two most common cases. You can deal with that additionally with a little bit of extra code.
-
Demo - going deeper
Okay, so in this demo I'm going to go just a little bit deeper in terms of HDP. There are a couple things with this controller, this API as it stands, that it's sort of not very HDP-friendly. One thing is, although I didn't do this in the other demo, if I pass in a, make sure we built this, if I pass in an index that's not available, I'm going to get a 500, which makes sense that that's the way the code's written. So the code should be written in a much more robust way. You know I should say if at least data.Count is greater than id, then return id, otherwise, I should do something else. And what I really want to do is I really want to return a 404. Now if I want to return a 404 sometimes and a message other times, what I can do is I can add an HttpResponseMessage, go down the stack one level, and here I can say return-Request.CreateResponse, which is going to be a string, the StatusCode is going to be OK, and then the value gets passed in as the second parameter to this extension method and that creates a response for me. Otherwise, I'm going to say return Request.CreateErrorResponse, StatusCode is going to be NotFound and I'm going to say Item not found. Okay. So now I've essentially by adding this again slightly lower level construct in the web API, it should be a response message. I've got a lot more control over what the response headers are, what the status codes are, etc. And now if I go back over here, let's get rid of all those requests, I go to the composer, and if I ask for 11, I get a 404, which is what I would expect if I was a API client, an HTTP API client, I would expect if I asked for a resource that wasn't there, I would get back a 404. It would be very informative for me. Now if I asked for 1, I still get back 1, which is good. Now the other thing that I did before was I did a post, so I did a post to /values and I said Content-Type was application/json and I said you know basically New Item. Okay. Now when I did that, it worked, I didn't get any errors back, but the status code that came back was a 204 No Content, which is okay, but again not really in the spirit of HTTP. HTTP says if you add a new item, then the response should be a 201, and so the 201 should have in its header the location of the newly created item. So again, I'm going to change the response here from void to HttpResponseMessage and then I'm going to say return, actually going to have a variable here, msg = Request.CreateResponse and the status code is going to be HttpStatusCode.Created and I want to change one other thing on the message before I return it. I'm going to say msg.Headers.Location, I want to set that to be a Uri. I'm going to say Request.RequestUri + data.Count ToString return msg. So again, what I'm doing here is I'm setting the location header. Location header should always be set when your status code is created because the location should point to the newly created resource. These are just the rules of HTTP. So now if I go back and I go back to my composer, which already has my post saved and I click Execute, I get a 201. If I look at the headers, there is my api/values/3, and if I click on it, it's going to give me a new one, right. (Clicking) Ah, I did that wrong, didn't I? I need to do api values count-1, so there was a bug in my program. So count-1 ToString. My apologies. Try that again. Let's clear those all off, go to composer, go about to do a POST to values, Content-Type application/JSON, Request Body is New Value, and I'll execute 201, and if I go to the Raw headers, here's my new location. Let's just grab that inside of Fiddler. (Working) And so there is my new value. Okay, so that's just showing you how you can take the web API and modify it to your particular needs.
-
OData query syntax
Okay, so one other feature, I'm going to talk about this only in this module. I'm not going to go into details of this in any other modules. OData is a specification that is used by WCF Data Services, it's also an open specification and Microsoft provides essentially a pledge that you can implement OData without having to worry about any patent or trademark issues. Web API includes support for the syntax, which is there's query syntax relating to OData. ASP.NET Web API supports this syntax if your actions on your controller return IQueryable, instead of IEnumerable if you were returning a collection. The fact that it returned IQueryable will allow you to automatically support queries against those objects, the objects in that collection, and this will be provided again by that underlying part of the System.Web that was System.Web.Data.
-
Configuration
Now obviously as a highly customizable extensible system, there has to be some way to tell the system that you want to change things and the way you do that is through a configuration object. Now the configuration object does not read from the Web.config, but what it does do is allow you to similarly to route binding, etc. It has a global object that you can use. So if you're in the ASP.NET hosting model, you're going to use GlobalConfiguration.Configuration. If you're self-hosting, you'll be creating your own instance of the HttpConfiguration class. There also is an IOC mechanism, Inversion of Ctrl mechanism, built into the configuration. It allows you to provide DependencyResolver and additional types that can be resolved. This allows you to have a much better chance of being able to unit test your web API systems. This was another goal of the designers of this API was to make it very easy to build unit tests. Now I talked about hosting a little bit, but again to make it clear, the framework is built-in and easy to host inside of ASP.NET. So you add a reference to the appropriate assemblies and you're good to go. You can also self-host the web API. So if you are building a console application, or a Windows service, or a desktop application even, and you want to expose an API maybe for diagnostic or for callbacks, you can use the web API very easily in those scenarios. Again, you just have to add the proper assemblies. Whether you host inside of ASP.NET or you host inside of a custom app, same programming model so you can very easily choose to move from one to the other. And again, we'll have a whole module on hosting and I'll show you mostly how to do self-hosting. Also, the things you can do inside of the ASP.NET host to change the way that host behaves.
-
Security
Security. There isn't really anything new in terms of the web API and security. There are a lot of new things in .NET 4.0 and 4.5. I highly recommend if you're interested in web API security to watch my colleague's, Dominick Baier's course on authentication and security in .NET 4.5. It's exact coverage of this model. You can of course use any security that you can use with ASP.NET, so you can use basic, you can use Windows, you can use forms. The, again, sort of modern way to do authentication in many cases is going to do some sort of token authentication, and again, if you want to look at that, take a look at Dominick's course.
-
Summary
Okay, so this is the introductory module. Again, we talked about what the ASP.NET Web API is. It's a simple extensible framework that allows you to build HTTP services, as well as HttpClients. You can build RESTful services, as long as you again follow those constraints. And in additional modules of this course, again as I said earlier, we'll go into more detail on all of the different features of the web API and how you can use them.
-
Uniform Interface
Uniform Interface
Hi. This is Jon Flanders with Pluralsight, and in this module of the ASP.NET Web API course, I'm going to talk about implementing the uniform interface. (Waiting) So the outline of this module is we're going to talk about what is REST and what is the uniform interface. We'll talk about how to build out the uniform interface using the web API. We'll talk about content negotiation. We'll dive a little bit deeper into model binding. And then we'll dive a little bit deeper into how you can control more in terms of the HTTP request and response using the web API's extensibility.
-
REST
So REST stands for Representational State Transfer. It is an architectural style for building client server applications introduced by Roy Fielding in his dissertation at the University of California Irvine. The basic idea is if you understand the way that the web works, if you understand URIs, typing in URIs into your browser, clicking on links inside of the content inside of your browser, you understand a lot of what REST is about. REST is taking those same advantages, those same ways that the human web works and applying them to the programmatic web. So using HTTP, addressing all your resources, using a URI, interacting with those URIs using what's referred to as the uniform interface. RESTful system should also be stateless. This facilitates scaling your system. A true RESTful system should be hypermedia-driven, that is clients should know the bare minimum number of URIs into your system and then the client should be programmed to follow those URIs as it moves from state to state. And of course, one of the big advantages of using HTTP is that Get requests, the typical request you see in the web, can be cached. And so, again, building a RESTful system, or building a system on top of HTTP, can give you a lot of advantages in terms of scaling. Both the statelessness constraint and the cache-ability constraint help you to be able to build a system that can handle a greater load.
-
URIs
So a RESTful service models its system as URIs. Again, URIs represent resources as well on the web, normally, on the human web I should say. A resource that we get back from a URI is generally HTML, but it might be an image, it might be a video. So everything in a RESTful system is addressable via a unique URI. Every resource is represented by a unique URI and we're going to interact with that resource using the uniform interface. So you start with a URI and then you add-in your HTTP request and header, the top line of the HTTP request header, what verb you want to use, what part of the uniform interface you want to use.
-
What is the Uniform Interface
So the uniform interface, the main four verbs are Get. So get allows us to get a resource. This is a call that should occur or cause no side effects. It retrieves the resource, and again as I mentioned a couple of slides ago, one of the big benefits is that get requests are cacheable. Post requests are not cacheable. A post request will create a new resource. So if we're talking about a resource that we might have in our system, let's say we have courses, let's say that we're modeling a service for Pluralsight. So we might get a course and that will give us the information about the course. If we need to create a new course, we're going to do a post. So we're going to do a post to a URI and that's going to create a new resource, again, it's the same as SOAP, all the responses are unsafe. We don't know what the side effects of a post are going to be, so you don't want to repeat a post and you don't want to cache the response to a post. If you want to update a resource, you're going to use put. Put is what's called itempotent. An itempotent service or an itempotent interface or method is one that you can call one time and it will have some effect. If you call it a million times with the same parameters, it will still have the same effect. So it's safe to call put and delete multiple times. If you call put to update a resource multiple times, it will just update. So if you were to update a course's let's say author, it would just update the author again. Nothing bad would happen by calling it a million times. Same with delete. If we're going to delete a resource, if we're going to delete a course, if we try to delete it again, it just doesn't do anything, right. It has no effect, but there's no other side effects of calling delete on an already deleted resources, okay. So the nice thing and one of the reasons that I have over the years fallen into wanting to use a REST more than say SOAP is because these two pieces, the URIs and the uniform interface, really map out how you should build a system. There's no guess work involved. You just have to figure out what are your resources, what are the URIs that represent those resources, and then what part of the uniform interface are you going to implement. Not every URI has to have the full uniform interface implemented and you could also security trap the uniform interface. So in my example, obviously you might want to let clients of Pluralsight get the metadata information about courses, but you wouldn't want anybody, except for somebody internal to be able to create a new course. So that would be the pros and the cons there of how you would define what part of the uniform interface would be exposed and exposed to whom.
-
Implementing using Convention
So when we look at the uniform interface in terms of the ASP.NET Web API, by default, the web API allows us to build out the uniform interface based upon conventions and those conventions are basically to create an API controller, so a controller that derives from that base class. And then to have methods on that controller that match, you know, verb by verb with the uniform interface. So we'll create a method called Get, a method called Post, a method called Put, a method called Delete. And by adding those methods, now we've implemented the uniform interface on that particular resource, which is going to be represented by the URI that's going to map through the ASP.NET routing to this particular controller.
-
Demo - using convention
So now I think it'd be appropriate to have another demo where I'm going to build a web API endpoint and I'm going to go through sort of step by step all the different parts of the uniform interface. So I'm going to go ahead and call this TrainingCompany. And what I'm going to do is I'm going to pick the ASP.NET MVC 4 project template web API. Remember that's also going to give me some pages, some MVC views, because what I want to do is fill out a little bit more in terms of using the API, as well as building out the API. So what I'm going to do is I'm going to get rid of the ValuesController. I don't want that. And what I'm going to go ahead and do then is I'm going to go ahead and create a new controller and this is where if you're building out a number of different APIs, this add controller dialog would be helpful because you can go down and select Empty MVC controller, or an empty API controller, or in our case, an empty API controller or potentially an API controller with read/write actions using the Entity Framework or empty read/write actions. You can pick from either of these three final templates. I'm going to start with empty MVC controller, sorry empty API controller, and I'm going to call this CoursesController. Okay, so for CoursesController what I want to do is obviously create a controller that returns a list of courses and an individual course allows me to add a course, modify, and delete a course. So let's start with a course. I'm just going to create a class called course I'm going to say public int id and public string title. Notice I made these types lowercase, that's just so that in the JSON it looks more like natural JSON. I could also add attributes to change the name if I wanted the internal names to be more .NET like with uppercase. So I'm going to add a get that returns an IEnumerable, of course, and I'll say this method is Get, okay. So remember this is the convention approach to building out a web API. I'm going to have a sum data store that's going to contain a list, a set of courses, and I'm going to return them from, all of them, from this Get. Let me go ahead and just cruft up one that's internal here. So I'm going to go ahead and create a new instance of a list of courses. I'll say write that Add new course id equals to 0, title= Web API and then ret.Add new course id = 1, title= Mobile Apps with HTML5. Those are two other courses that I have on Pluralsight. I'll be adding a few more as we go along. And I'll say return ret. So here, just a very simple call in the Get is to say return courses. Okay. So let's just test this out in Fiddler to make sure this works. I'm going to go ahead and say debug start without debugging. That will give me the port 2880. I'm going to go over to Fiddler and go to the Composer, and go to 2880 and go to API because remember I've picked the default template. The template by default adds API as part of the routing information, the routing URLs, paths for web API controllers, and then say courses. Let's clear out all that. And we execute. Then I get a 200 and there are my courses. That's great. Now one of the reasons that I picked this particular template was so that I could do a little bit more with the template in terms of actually using a little bit of client-side code, and in this case, the client-side code I'm going to add. I want that section in there, actually I don't want that section in there. Let's get rid of those sections. Now the code I'm going to want to add is a little bit of JavaScript. Now if we look at the layout, what they've done in this most recent version of MVC is something that's very smart from a performance point of view if you're building web applications, which is at the scripts are being loaded at the end of the body. Sort of traditional web programmers put the scripts inside of the head tag. The problem with that is that the body then can't render until the scripts render so that is a performance issue. What they do is they're using their bundling functionality to bundle all of the scripts here and then they're rendering an extra section, which is called scripts, which allows me inside of my index.cshtml. I can put in a section scripts, then I can put in a script tag, then I can put in my own script and I'll know that this script will not execute until after all the other scripts have already loaded. So let me put in a list, call this courses. So what I'm going to do inside of here is I'm going to use a little bit of jQuery. I'm going to say AJAX url equals to /api/courses, then I'll say success is a function, it gets a list of courses. I'm going to need another curly brace there. And so, inside of my success function, move that down to the next line so you can see it, there we go, I'm going to go ahead and get the list asking for courses, and then I'll just do a for in courses.length, course = courses i, and then I'm going to say list.append, and I'll just create a little concatenated HTML here, course.title. Okay. So let's go back to CoursesController. CoursesController has a get, which implements a collection return so that the default get for this particular controller is going to return all the courses. My individual page here is going to get a list of all the courses. Let's go ahead and see if that works. And there are my two courses. So if I go look in Fiddler, you can actually see that there was a request made by the browser for api/courses and if I go back and look at here in IE, I could even see that if I go to the F12 Tools. F12 tools are another really useful tool for debugging web services that you're calling from browsers, especially if you're using SSL. You don't have to muck around with any of the SSL settings in Fiddler and you'll be able to see all the network traffic here. If I go ahead and refresh, I can see that in fact there was a call to api/courses. It was requested with XMLHttpRequest. If I look at the Response Body, there is the JSON return. So I'm going to go ahead and keep filling out this API. Let's say that the next thing I want to be able to do is I want to be able to get an individual course, so I'll say public course Get int id, this will be fairly easy, var course, should say ret = from c in courses, use a little link here where c.id =id, select C .FirstOrDefault and then I'll say return ret. Now if this is null, (Typing) I should return a 404, but I'm going to implement that later. I'm not going to implement that right now. So there's my Get for an individual item. Let's go ahead and make sure that works. Just go ahead and do that inside of Fiddler. So I'll go to the composer here, make the request courses/1, there we go, Mobile Applications with HTML5. Great. Now I can go back and let's implement adding a new course. So I'm going to say public void Post course c. Now I'm going to have to do something here in terms of making sure that the web API knows where to look for the data I expect to come in on the post because sometimes you expect data to come in on a query string, sometimes you expect it to come in from the body, and because of the way that the model binding and serialization works inside of the web API, the web API kind of needs to know where this is coming from so that's why I'm going to say FromBody and so that tells the web API that this piece of data should be coming from the body. I'm going to go ahead and assign it a new id, so I'll say courses.Count, courses.Add, and then that's it. Alright, that's all. Now of course, I should return a 201 with a location header, but again, I'm going to do that later. So there's adding a new course. Let me see if I can add a new course. Let me go back to the composer. I'm going to change this to /. I'm going to get rid of basically everything here and just say Content-Type is application/json. I'm going to change this to a post and then you know I could just cruft up that JSON, but just to be safe, let me just go ahead and crib it here from this other window. And let's call this a HTTP Fundamentals, which is an important piece of information that you need to know, especially if you're working with these kinds of systems. So I've got my request body. This is again a little bit of JSON. Let me go ahead and execute this and I get 204 No Content. Now of course, if I go over to the browser and look at my list of courses hopefully, I'll see three courses and I do. And so that's cool. So that's working. Let's go ahead and do a modification. So let's go ahead and do a put. So here I'm going to say Put, instead of Post, int id, and now I can crib from these other methods as well, do a little copy and paste inheritance. So let me go ahead and find that particular course. (Working) I'll say retention.title is equal to c.title then you know that pretty much does it, right. There's two Cs here, so let's do course. Okay. Great. So let's go look at my list of courses. What do my list of courses look like at the moment? If I refresh, I only see two courses. Why do I only see two courses? Because it's an end memory list of courses and every time I compile, that memory is flushed, so let's go back over here, go to the composer. Let's go ahead and do a Post. I'm going to go ahead and refresh. So now I've got three. Now if I want to update this particular item, I need to know what its id is. Notice that I didn't get back its id as part of the header, which is why the 201 is so useful, but notice here I get id 2, so I can find that out other means. And so if I go here to courses/2, I'll add 2 here as well, and let's call this Advanced. It used to be Fundamentals, so we're changing item 2. Then I can change Post to Put and go ahead and execute. If I go over and look at the response, there's Advanced HTTP Fundamentals. And delete. Assuming that you choose to implement it in your API, it's similarly easy. You'll just take in the id, find that item in the list, and then you can say courses.Remove and just remove that item. And there you go. If I go back to Fiddler, change this to Delete, get rid of the body since it's not necessary, execute, refresh, it's gone. Let's get rid of another one just to prove a point. (Clicking) Okay, so again that's using this conventional approach, convention-based approach to building out a web API.
-
APIController
So again, the APIController base class is the one that you're going to derive from. It has a number of properties that are useful in terms of figuring out what's going on. You can always get the incoming request message here on the Request property. You can find out what the Url is. ModelState, we'll talk more about that later. That'll clue us into how the model binding and formatting worked. We can get a hold of the ControllerContext and also our Configuration. If you want to handle things at a lower level, you can actually override the ExecuteAsync method, as well as override the Initialize method, which was allow you to do some per controller initialization once the ControllerContext has been created.
-
Verbs to Attributes
So the demo I just showed a couple of minutes ago, we used what I refer to as the web API's convention approach, that is create an API controller. We're going to add custom methods. Those methods names are going to correspond to the verbs of the uniform interface. That works great in a lot of cases. However, you may not want to name your methods that. You may want to name your methods something else. You may have some internal coding convention or just that doesn't necessarily make sense to you in terms of you know naming the methods the same thing as the name of the verbs and that's fine. The ASP.NET Web API is totally fine with you not naming your methods Get, Post, Put, and Delete. If you don't want to do that, all you need to do is name your methods whatever you like, and then add the appropriate attributes, so HttpGet, HttpPost, HttpPut, HttpDelete. So that allows you to implement the uniform interface for a particular resource, for a particular URI using an APIController, and therefore, you can work out what the uniform interface will be implemented by your class. There's also an AcceptVerbs attribute, which allows you to add multiple verbs if you want to have one method handle multiple parts of the uniform interface. Typically that makes the code a little bit messier, but there are some situations where it might make sense.
-
Demo - Using Configuration
Okay, so this particular service that I built in the last demo was again following that convention of methods called Get, Post, Put, and Delete. What if I want to have different method names? So let's change the Get to, from Get to AllCourses. This absolutely will build, no compiler errors will happen. But if I try to go to that endpoint /courses and do a Get, I'm going to get a 404. No action was found on controller Courses that matches the request. Because if I'm not following the convention, I need to add the appropriate attribute. So I need to say HttpGet. If I say HttpGet, now I go back here, I can click courses. And to the client it's transparent. I mean if the client still has a URI to a particular resource, internally inside your code you have the option of not following that simple convention. Again, why would you do that? Maybe you just don't like having your method names be so transparent. Potentially it might conflict with other conventions that you have in your class library or something like that. There's not a really compelling reason to do it one way or the other. Doing it without the attributes just means you sort of have less ceremony to go through, which makes your code a little bit more simple, makes writing your code a little bit easier, understanding the code a little bit easier. So I prefer the approach of convention, but there are some times when the configuration approach would make sense too.
-
Content negotiation
Now an important piece of the way that HTTP works is something called content negotiation. Now if you've never programmed on the web, if you've never built a RESTful system, content negotiation could be something new to you, but it's actually fairly simple. It's just dynamically determining the response type, the media type, based upon the client's request. So in a typical example, when you type in a URL in your browser when you're using the human web, you know you're browser typically says I'll accept anything, anything back from this URL. Most often, the resource or media type you get back is going to be HTML and the browser knows what to do with that HTML and then it renders it. It could be, however, that your browser asks for a specific media type and it would do that by setting the Accept header to something else other than star, which is what a typical browser does. So more often than not, this is not done by a human browser, but by a programmatic client. So the programmatic client could say I accept let's say application/xml, which means when the request gets to that endpoint, gets to the handler for that resource, it's going to look at that Accept header and say oh well I can send back XML, so the server will set the Content-Type header of the response to the appropriate value. If a client is sending a body, that is if it's doing a Put or a Post, it will also send a Content-Type header to let the server know what kind of content it's sending. So again, for example, let's say that I had my mythical API that creates new courses, if the client is going to create a new course, it might send an Accept header with JSON in it. So if I say I'm sending JSON, which is the JavaScript object notation, that way the service will know that body is JSON, it will know how to deserialize it correctly. On the other hand, I might, if I'm asking for a particular course, I might ask for XML. So if in my request header, in my Accept header, I say I would like application/XML, if the service that's implementing that particular resource can give me back XML, it will. So content negotiation is really a back and forth between a client and server to help the client and the server know essentially what the dialect that they want to talk, what data type, what network data representation they want to use. And the cool thing about the web API is the web API provides an automatic content negotiation for the most common cases, that is the cases I've talked about where the client sends an Accept header, the Accept header says I want XML, the web API returns XML. If the client sends an Accept header with JSON, the web API will return JSON. It'll do this just automatically. It will also deal with the Content-Type header on a body where the Content-Type is basically form-Urlencoded, JSON, or XML. So it does all the most common media types, does content negotiation for that automatically. If you want to return a different kind of content or handle different kinds of ways of asking for different media types other than the Accept header like a lot of people will put a .xml file extension on the URL to say I would like to get XML or a query string or if you just want to handle the media type that isn't already handled by the web API, you can implement the MediaTypeFormatter class, an instance of that, or implement a class derived from that base class I should say, and I'll show you an example of that in the extensibility module, so that will be coming later. (Waiting) So again, out-of-the-box the web API supports from the client, JSON, XML, HTML form, and from the server.
-
Model Binding and Formatting
So again, one of the ways that the web API helps you to deal with content negotiation sort of shields you from content negotiation is by doing model binding and formatting. The model binding and formatting systems in the web API will automatically take data that comes in the URI or comes in from the HTTP body and will turn them into .NET objects. So by default, this works pretty well. There may be some customization you might have to do in rare cases. You can add the model binding attribute to specify a specific model binding for a parameter or on a class, you can use the FromBody or FromUri attributes to tell the model binding system where it's getting data from. The one thing you have to watch out for is there is a rule, which is that the body can only be read once. And so that means if you have multiple complex types in your parameters of your method, you are absolutely going to need to use one or more of these attributes to tell the system which one should come from the body and which one should come from the query string.
-
HTTP – Diving Deeper
Okay, so the web API using the routing and controllers take care of the basics of HTTP, that is the URI + verb and content negotiation. But if we want to really follow the HTTP specification, there are a few other things that we might like to do. We might like to send back a particular status types, status codes, messages, we might like to do 404s, we might like to do redirects. We might want to look at additional HTTP headers to figure out what we would like to do. And so if you need to get down to that level, you're going to need to go down one level of the stack from model binding and look at the HTTPRequestMessage and HttpResponseMessage objects. These are objects that represent the non-formatted bound HTTP request and if we're doing a request message, we can change the body type and response message we can change and have it as the return parameter.
-
HttpRequestMessage
So the HttpRequestMessage object is laid out here on the slide. Basically if we're on the client-side, we might be using these two methods, but if we're not on the client-side, we're on the server-side, we're probably just going to be looking at things like the headers, the content, the methods, the RequestUri, and potentially the version.
-
HttpResponseMessage
In terms of generating response we'll create an instance of this HttpResponseMessage and there are a number of extension methods that will help us create the content we need. So the two things that we really need to set are you know what is the StatusCode and what is the content, but we can also do a few other things with this as well and we'll see the HttpRequestMessage and ResponseMessage as well in the client module. So again, the web API is symmetrical. The same objects live on the client-side, as well as on the server-side.
-
Demo - HttpResponseMessage
Okay, now I'm going to fix those couple little HTTP issues. Now I did this in one of the demos in the first module, but again let's complete it just for completeness and to do it without using simple types, let's use this course type. So again, what I'm going to do here is have an HttpResponseMessage be returned from this post. And here I'm going to say return, sorry, msg = Request.CreateResponse, I want to create an HttpStatusCode.Created, and then I want to set the msg.Headers.Location property as a new Uri that's going to combine Request.RequestUri with the new id, which is c.id.ToString. Okay. So, and of course, returning this to stop the compiler from complaining. So this will allow me now, if I go to let's say Fiddler and I want to add a new course, I'm going to go ahead and do a post and I'm going to go ahead and say id is 0,title is equal to Hello 201 and I've set the Content-Type, let's go ahead and do that. So I get a 201 back, 201 Created. The location header points to that new id. So as a programmatic client to be able to take the value of that location header to get and be able to get that resource or know about that resource from then on. So that works great. Let's go and look at the other problem with the simple examples here, which is if I asked for courses 23, and of course I need to get rid of the request body. I get a 200 back, which doesn't really make sense because it's null, right. Again, I don't want to return the null. So you want to go back here and go back to the single get and change the single get from returning just course to returning HttpResponseMessage. And so here I'm going to say if ret is equal to null, else I'm going to do something else, then I'm going to return something completely different, I'm going to return an HttpResponseMessage. So I'll declare the HttpResponseMessage up here. If ret is equal to null, then I know I want to say msg equals to new HttpResponseMessage HttpStatusCode is NotFound Course not found will be my error message and if it is not null, sorry I need to use the extension method, Request.CreateErrorResponse, and then here I'm going to say msg = Request.CreateResponse for a course HttpStatusCode.OK and the value of that will be ret. Okay, so this is just a few simple lines of code going down one level from the formatter to the HttpResponseMessage, I can get this effect, which is really again more in line with the way people interact with HTTP services expect. So I'll say courses 23 is 404. How about courses 1 is 200, so this is working the way I expect it to.
-
Summary
Okay, so from the slides and demos, I think I've shown you that the ASP.NET Web API does allow you to fairly easily implement all of what makes up a RESTful service. Routers and controllers again allow you to implement the uniform interface. If you need to dive down deeper, you can use the attributes, as well as the HttpRequest and ResponseMessage. Again, the defaults work very well for simple HTTP services. Again, if you want to follow those RESTful constraints, you will have to do a little bit more work as I showed you and we'll see little bit more of that as well as we go through the rest of the course.
-
HttpClient
HttpClient
Hi. This is Jon Flanders with Pluralsight, and in this module, in the ASP.NET Web API course, I'm going to talk about the HttpClient. So first I'm going to talk about the basics of this new HttpClient API. I'll talk about customization of that API, as well as I'll briefly touch on security.
-
Why another HTTP Client
So the first question that you might have, it's certainly the first question that I had when the web API came out and they included a new client API, is why do we need another HTTP client class in .NET? We've had the HttpWebRequest since 1.0, added the WebClient in 2.0, so why do we need another client? Well it turns out the HttpWebRequest and the WebClient, which is sort of a simplification of the HttpWebRequest, are great for you know simple to moderately complexed use cases. But for more complex use cases, and when I say complex, I really mean more in tune with the HTTP specification, those clients sort of fall down. They're not tuned very closely to the modern HTTP use cases and they're also not very extensible or flexible. So in order to again both take advantage of the newest ways that clients interact with HTTP servers, as well as to give us an extensible API going forward, the team that built the web API also built the Httpclient. And again, the basic idea is more in tune with HTTP and more control in terms of interacting with of the underlying HTTP protocol.
-
HttpClient model
One really nice thing about the programming model in the HttpClient is that it's symmetrical with the server-side. So for example, if we're going to send a message, it will be the HttpRequestMessage object. If we're going to receive a response, it will be the HttpResponseMessage. So the same classes that we use on the server, we can use on the client. There are some other nice features of HttpClient. It can be used against multiple URIs, that is one instance can be used against multiple URIs even different domains. The underlying API is all based around the task pattern from .NET 4.0, so everything's Async and is based upon tasks. This means that if you're using .NET 4.5, you can use cool new language features like the Async and the Await keyword. It installs with MVC 4, but you can also retrieve the client itself through NuGet for a particular project.
-
Using HttpClient
So here's a simple example of using the HttpClient, obviously first we need to create an instance of the HttpClient, and then we decide what URI we're going to call, and we pass that URI to the appropriate method. In this case, we're calling GetAsync and you can imagine there are a PostAsync, and a PutAsync, and a DeleteAsync. This particular call is going to return a task, and so we can call ContinueWith on that task and we can pass in essentially a lambda, a function that will be called at the end of the completion of that task. We can get back the result. This is a place where the EnsureSuccessStatusCode method on the HttpResponse is very useful. It will throw an exception if it's not a SuccessStatusCode. Then we can use the content of the response. We can read that and so we can use formatting to read that out as different objects. Reading the content is also a task, so we can call it ContinueWith on that task and when the readtask is completed, we can get the result and that will allow us to process the result that we get back from the call to the service.
-
Demo HttpClient
Now I'm going to use the HttpClient. What I'm going to do is build a website that goes out and searches tweets and then displays those in a page. So I'm going to create an ASP.NET MVC 4 application and I'm using Visual Studio 2012, but I'm only using .NET Framework 4, which means you can do everything I'm showing you in Visual Studio 2010 with MVC 4 installed. I'm going to call this TwitterClientMVC. I'm going to create an internet application, and so right away, what I'm going to do is create an instance of the HttpClient. Let's get rid of this message here. Get a little bit more screen here by moving this out of the way. And so I'm going to say var client = new HttpClient and that is in the System.Net.Http namespace. And then everything with the client is based upon the new task programming model. So what I'm going to say is I'm going to say task = client.GetAsync and notice I can pass in a string as a URL. I'm going to call search.twitter.com/search.json?q=Pluralsight. Now that's basically my URL that I'm going to be calling. This is a Twitter API that's open. It doesn't require any sort of authentication or anything like that, so it's a nice one to use. And then what I do from that is I'm getting back a task. The way that the task API works it's sort of affluent API, so I can also add on here ContinueWith and I'll say taskwithmessage, or taskwithresponse I should say, and I will reformat that so you guys can see that clearly. Scroll up here, let's put this on a separate line, put that on a separate line. So what I'm actually doing is I'm chaining together the call to GetAsync with a ContinueWith. ContinueWith is going to get called after GetAsync gets completed. I get passed in the task from the call to GetAsync and inside of ContinueWith this is where I can actually read the message. So I can say var response = taskwithresponse.response, result, and you can see from the IntelliSense that the result is an HttpResponseMessage, so we're back to HttpResponseMessage, HttpRequestMessage. Now what I need to do is I need to go to the response and say give me, actually read the response, read it for me, and this is also an Async operation. So this is going to be the read task and I'm going to say response.Content.ReadAsAsync and you notice ReadAsAsync also returns a task and it also takes an object type of T. So I know I'm getting JSON back. I know that the web API client by default is going to use the Newtonsoft JSON deserializer to basically map the JSON into .NET objects. So what I'm going to do is I'm going to make up a new .NET type and I'm going to call it Tweets, and I'm going to ask Visual Studio to go ahead and generate a class called Tweets for me. Up here at the top, I'm going to go ahead and add a model variable, which is of type Tweets, but that model variable is going to be null until this task is completed, right, this readtask. I'm going to say readtask.Wait and that will allow me to wait until the readtask is done before I move onto the next line of code and then I'm going to say model = readtask.Result and you notice from looking at the IntelliSense, result is of type Tweets. So now the only problem I have is I'm inside of a synchronous MVC action doing all these asynchronous calls. I've taken care of the asynchronous nature here by waiting on that task, but what I really need to do is wait on this task. Now there's a couple other ways to solve this as well. If you want to look up the task programming model, a good thing to look up, we're not going to go into detail here. All I'm going to do is do a task.Wait. And so what this is going to allow is for my action to wait until this whole set of operations is complete before I continue on. Now I created this tweets type, but what I need to do is I need to map that into a .NET type. So what I'm going to do is I'm going to go over to Fiddler and I'm going to go ahead and do an execute on that Get and I want to see what the format of this JSON looks like, okay. And the format of this JSON looks like this where there's a top level object and then there's basically an array of results and then inside of the array of results, there's some properties, so from_user, text, okay, so these are JSON properties. So what I'm going to do is go into that Tweets type and I'm going to go ahead and add a public Tweet and I'm going to say this is results. I'm going to go ahead and create another class called Tweet. And now I have a choice here if you know what do I want to do? Do I want to really map this to a different type in terms of the way it's shaped and is viewed than it is from the JSON? Or would I like to map it more to a .NET type that I would normally create? So let's say string UserName prop string, no TweetText. So I can do that by using the JSON property attribute, which is of the newtonsoft.json, and so I need to go back and take a look at my Tweet elements and results. So from_user is the user, so I'll say from_user and the TweetText, I'm pretty sure that was just text. Okay. Now I actually want to pass that model, whoops, no semicolon there, I want to pass that model to the home controller, so I'm going to say return View of that model and then what I want to be able to do is basically create a page that will display that. Now one of the cools things about MVC is, I'm going to go ahead and delete that index.cshtml and I'm going to right-click here and say add a new view. The view is going to be called index. I'm going to create a strongly-typed view on top of---and of course, I need to make this public for that to show up, public---do a build one more time, add new view, call it index, create a strongly-typed view, actually I think I want to create it on top of Tweet, not Tweets, and I want it to be a list, so let me go ahead and do that and it'll do that for me automatically, and then I'm going to go back to my home controller and instead of saying a model, I'm going to say model.result. Okay, so hopefully that will all work. Let me set a breakpoint and we can step through it. I'll set a breakpoint there, I'll set a breakpoint there, and I'll set a breakpoint here. Let me go ahead and debug this. Do F5. (Waiting) So I'm in the debugger. I'm going to do F10, create the new client, create the task. Notice it goes right to the task.Wait and if I press F5, I'll get into the ContinueWith and then I can step over the ReadAsAsync, Readtask.Wait, get the model, the model now is not null, and there is a list of all the Tweets that are being happening right now about Pluralsight. So that's an example of using the HttpClient in a MVC application. You can use it in any .NET application, .NET 4 and above, and the programming model is essentially the same. It gets a little bit easier if you get into 4.5 because you can use the Await keyword with a task so you don't have to do it as much of the task programming model to make things line up. As I said, there's a couple other ways I could do this. I could also create an asynchronous action, which would be another way to deal with this sort combination of Async and sync methods. But that's just an example of using get with the web API client.
-
Media Types
Now in terms of media types, the HttpClient supports two response media types out-of-the-box, JSON, which by default uses the json.net serializer, and XML, which uses the XmlSerializer. For request bodies, that is for requests that you're sending to an HTTP endpoint, it supports JSON, XML, Form, Multipart Form, a simple string, or byte array. So depending on what you're calling on the server-side, you might use a one or two of these depending on your situation. I personally find myself more often than not using Form or JSON. It just depends on what you're doing.
-
Sending data
Now when you're sending data, when you're calling PostAsync or PutAsync, you can pass in an HttpContent object, that's the content property that's exposed on the HttpRequestMessage, so that object is basically the wrapper around the data that you are sending and there is an ObjectContent of T for JSON or XML.
-
HttpContent types
There are different types, for example, stream, so for raw data, there's a StreamContent type, multipart content, and multipart form content. There are special content types and then byte array, Form-Urlencoded, and string content, again, all have their own derived HttpContent types.
-
Demo Sending Data
Okay, what I'm going to show you now is a slightly more complex example that also incorporates media types. So let me walk through what I have in terms of code that's already there. I've got two projects and a solution, VideoUploadServer and UploadVideoClient. UploadVideoClient is a console application. VideoUploadServer is an MVC 4 application. Inside of my MVC 4 application, I've got a MVC controller that has an action called UploadVideo that takes an HttpPostedFileBase. What this is going to allow me to have is an action on a MVC controller that can be used easily from a web page, but also can called programmatically. Now I do have a web API controller. The web API controller returns information about the videos that have been uploaded to a particular path and then I have an HTML Page, which is a view, which uses jQuery to query the web API and to say are there any videos? Let me go ahead and say debug, start without debugging, so checking for videos, checking for videos, it says hey you don't have any, why don't you upload one? So let's go ahead and do that. Now I could easily create a web page with a file element in it, but let's see how we could do this programmatically. The first thing I want to do is on the UploadVideoClient, I want to get a hold of the right assemblies for the client. So I'm going to go ahead and use NuGet for this. In my first demo, remember, my client was also the MVC application, so we had already had the appropriate assemblies. If I search for web API, I'm going to get a number of packages and this package is the one I want if I want to use a client. So I'm going to go ahead and say install the web API client libraries. That's good. And now I should be able to create an HttpClient. Of course, I'm going to have to add the right using statement. Okay, so that's great. Now I have a video that's in this folder, so I want to be able to read that in, so I'm going to go ahead and say a stream variable is equal to File.Open video.mp4, FileMode.Open. So I'm simply opening up the video as a stream and now I want to be able to upload it using the client. So what I'm going to do is I'm going to create a new content object that represents that content and that is the MultipartFormDataContent object and I'm going to say content.Add. So I'm going to add a new StreamContent, which is wrapping that stream, and then I have to give it a name, which actually has to be a very special name for MVC to understand it, it has to be video, "video, so I need the slashes in there, and then I do need to also specify the filename, so \"video.mp4\"". Okay, so at this point, I've got my client, it's ready to go, I've got my stream, and I've got the content for the client. Now what I'm going to do is get back a task by calling client.PostAsync. I'm going to PostAsync to HTTP localhost:2601, which is the port, home/uploadvideo and remember uploadvideo isn't a web API action, it's a regular MVC action. And then I'm going to specify that this is the content I want to send. I'm going to do a ContinueWith, get back my response (Typing) and then I'm going to say response.Result.EnsureSuccessStatusCode. So EnsureSuccessStatusCode on the HttpResponseMessage is going to let me know whether or not it was a 200, or a 400, or a 500, and so this will throw an exception if it's not the right StatusCode, if it's not a SuccessfulStatusCode, which means it could've thrown an exception inside of this action, which essentially an exception inside of an asynchronous task, which is something that if you're doing Async programming you'll want to handle. So what I can actually do is add another ContinueWith that will be called if there is an exception, okay, and I'll say you know err and I'll say if err.Exception is not equal to null, I'm going to go ahead and read the exception. If I read the exception, then that stops the task parallel library from terminating that thread, which is a good thing. (Typing) Okay. I'm sorry, err.Exception.ToString. There we go. Okay, so now at this point, I still need to wait for the original task to return. It's actually not the original task. It'll actually be this task, and I'll say task.Wait, and then I'll say Video Uploaded. Very excited about that. Okay, so that built. Let me go ahead and set this as the startup project or actually I can just set a breakpoint because I'd like to walk through this code one time. Let me go ahead and say debug. Actually, let's set a breakpoint everywhere. So not there because that will get called a bunch of times. Let's set a breakpoint here and here. And let me go ahead and start debugging. Those are exceptions that can just be ignored. Those are all exceptions that are happening. Let me go ahead and turn those off. If you ever have that happen, you know to go to the Exceptions menu and turn off all exceptions. A little extra bit of knowledge for you. I can go ahead and say Continue. Okay, so now that's running. There are no videos, which is what I would expect. Now I'm going to go ahead and right-click on UploadVideoClient and say debug and I'll say Step into new instance. So there's my HttpClient. I'm going to open up the stream, I'm going to create the content, and then I'm going to go ahead and wait. I'm going to set a breakpoint here, and a breakpoint here, and then a breakpoint at the very end as well. So let me go ahead and do an F5 to continue. So notice now I'm in my upload video. This is an actually HttpPostedFile. I'm going to call now on the client EnsureSuccessStatusCode. Notice that err.Exception is null, although, the ContinueWith does get called. And then I'll say Video Uploaded, F5. Now if I go back to this web page, within a few seconds, I should see that there's a video there. Let's double check that it actually wrote it to the right folder. Yep, there's the video there. If we go look back here, maybe that's a bug in my code. Let's check for it again. There we go. Okay, so great. Now that's an example of doing a post with HttpClient, not only doing a post, but doing a post changing the content type to one of the supported content types, the MultipartFormDataContent.
-
Dealing with Other Issues
Okay, so in the demos you've seen sort of the basic operations of using the HttpClient. There are, however, some other issues that you might want to deal with, some other HTTP type issues, so dealing with things like headers and cookies. On the HttpClient class itself, there is a BaseAddress, so this helps you to set a BaseAddress, and you can use relative addresses for all of the appropriate methods. You can set DefaultRequestHeaders, you can set a MaxResponseContentBufferSize, and Timeout. Now the interesting thing about these properties is these properties are going to be used for all requests made with a particular HttpClient instance. So these are all requests, that all GetAsyncs, PutAsyncs, PostAsyncs, and DeleteAsyncs that are called on a particular instance are going to use the same properties. Now there are some per-request headers that you might want to use, so you're going to set those on the HttpContent object. Now if you want to have per-request headers on Get or Delete, you need something called an HttpClientHandler, which I'll talk about in a couple of slides. For per-request headers, basically when we create a new request message, we can get back the content, and then on the content object, there's a headers property and we can set things like the content type or the except header and then send that along. Now as I said, the HttpClientHandler is a piece of infrastructure I need to provide if you want to do more in-depth processing. Now if you just create a new HttpClient and you don't pass an HttpClient handler to the constructor of HttpClient, you get the default HttpClientHandler. So what is the HttpClientHandler do? It's the underlying class that the HttpClient actually uses to send messages, send HttpRequests and get back HttpResponses.
-
HttpClientHandler
So the ClientHandler is going to allow you to have a lot more, again, control over the usage of your HttpClient. So you can set things on the HttpClientHandler like whether or not you want to allow redirects, whether you want to do AutomaticDecompression, ClientCertificates, Cookies, Credentials, so here's where we're going to add security, whether you want to use a proxy or not, whether cookies are allowed, whether the proxy should be used or not, and then there's the internal overridable method, SendAsync, which you can override if you're a derive class and actually do the low level processing.
-
Using HttpClientHandler
So to use the HttpClientHandler, obviously we're going to create a new instance and you can set those properties. Another common thing to do is to create a subclass. You could also derive from DelegatingHandler, which is a subclass of HttpClientHandler, and then you create an instance of that and pass it to the client constructor.
-
Deriving from DelegatingHandler
Okay, so here's an example in code of creating the DelegatingHandler just like I showed you in the demo a moment ago.
-
UserAgent
Now one thing that I like to point out is UserAgent, oftentimes, UserAgent is important from a server point of view if only for identification. The HttpClient doesn't send one by default, which is different than the behavior of the WebClient and the HttpWebRequest. So this would be a good use case for using the default request headers and adding the user agent, and again, this will last for the lifetime of that client instance.
-
Security
In terms of security, not much new here. The credentials object or property on the HttpClientHandler is a ICredentials, which has been around since .NET 1.0, so it basically supports basic authentication, digest authentication, NTLM/Kerberos authentication. The new hotness in security is token-based authorization and you need to provide a custom HttpClientHandler for that. Look at Dominick Baier's class on Authentication in our library at Pluralsight for more information about that.
-
Summary
So in summary, the HttpClient is a new more HTTP-aware API that allows us to use the more modern HTTP features that we have all come to want to use, but those earlier versions of APIs in .NET didn't really allow us the power and flexibility to use those very easily. So again, HttpClient symmetrical with the server, really flexible and very extensible.
-
Hosting
ASP.NET Web API Hosting
Hi. This is Jon Flanders with Pluralsight, and in this module, I'm going to talk about ASP.NET Web API and hosting options. So we'll talk about configuration of the ASP.NET Web API runtime, then we'll talk about the two hosting options, which are self-hosting or ASP.NET hosting.
-
HttpConfiguration
So the ASP.NET Web API obviously has configuration and unlike various other parts of ASP.NET, this configuration is not in the Web.config, rather it is held inside of an object that is loaded into memory. Now if you are hosting inside of IIS, you can get a hold of that configuration through the GlobalConfiguration.Configuration property, which is a static property. Likely, depending again on what you're doing, you may change the HTTP configuration, especially if you're doing anything with extensibility. So if you're adding any media types, formatters, anything of that nature, you'll most likely be changing the configuration. We'll talk more about those extensibility reasons and features in the next module. So here's the HttpConfiguration object, the definition of the object. It has two constructors, one that takes no parameters and one that takes an HttpRouteCollection, so that's where the routing information inside of ASP.NET Web API when you're routing requests to controllers. There's a list of global filters, as well as a collection of media type formatters. You can determine how much error information you want to display to clients. You can add a list of MessageHandlers. There's sort of a generic property bag where you can put various information. The routes end up in the Routes property. And then we have a DependencyResolver, which you can use to do sort of IoC dependency injection, and you can also get a list of services that have been installed, as well as you can get a hold of the path or the VirtualPath of the system.
-
Self hosting
Now we're going to talk about the two hosting options. Throughout the rest of the course, all the demos and all the slides and everything have been geared towards ASP.NET's IIS hosting, so hosting inside of IIS, inside of the rest of the ASP.NET pipeline and that's probably what most applications will use. However, you may want to create let's say a Windows service or even host a ASP.NET Web API in the random executable that'll allow you to do would be to expose an HTTP endpoint from any .NET executable, and so that can be useful for controlling applications or doing callbacks to client applications. So if you're going the self-hosting route, there are a few things that you have to do, I refer to these as the non-choice steps, and then there's a few things where you have choices, where you get to choose how your self-host will behave. The non-choices are you must create an HTTP configuration object. There's one included in the self-hosting API called HttpSelfHostConfiguration. Then you need to create an HttpServer. Typically this is going to be HttpSelfHostServer or a class that you derive from HttpSelfHostServer. And then you start listening. You call OpenAsync. When that task is completed, your self-host ASP.NET Web API will be up and running. Now the choice is when HTTP requests come into your self-hosting server, what code is going to process incoming requests and generate responses? There is one thing for sure that the first class in the message handling chain will be something called an HttpMessageHandler, so we know that for certain. Now in the ASP.NET Web API inside of IIS, we know that the class that actually handles the request messages and generate response messages are the methods on a controller, so that's the paradigm that is built into that hosting scenario. In the self-hosting scenario, this is where you're going to have a choice of how to do this message processing.
-
Demo - Self Hosting
Okay, so onto self-hosting demos. I'm going to self-host in a console application, so I'm going to create a .NET Framework 4, Console Application, call it WebApiSelfHost, and again, I'm doing this in Visual Studio 2012, doing it in .NET Framework 4, which means you can do it in Visual Studio 2010 as well. So create a console application and then I need to bring in the assemblies for self-hosting. Again, the easiest way to do this is to use the ManageNuGetPackages and if I search for web-api, there's a number NuGet packages. The one that you want (Searching) is the Microsoft ASP.NET Web API Self Host. So I'm going to go ahead and install the self-host, accept all the licensing terms, and now I've got my assemblies. So the first thing I need to do, remember, is create a configuration, so I'm going to say config = new HttpSelfHostConfiguration and that is in that namespace, Web.Http.SelfHost. I'm going to pass in a base address and I'm going to pick a port 8999, just some random port that I'd like to use, put that in a couple different lines. So that's the first step, we need a configuration and then we need a server. So I'm going to go ahead and create a new SelfHostServer and you can see the SelfHostServer takes the configuration as a constructor parameter. I'm going to call server.OpenAsync. I'm going to take that task and do a task.Wait and I'll say Console.WriteLine Server is up and running. And then I'll do a Console.ReadLine to keep my console application up and available. Okay, so this is great. I'm going to have some configuration here. I'm going to go ahead and run this. (Running) So notice the first thing is I can't get a reservation on that HTTP endpoint because I'm not running Visual Studio as admin, okay, so that's one problem that you may run into. I'm going to go ahead and open up Visual Studio as admin and open up that project again. Now let's run it. I should be able to get the reservation. Now of course I've added this reservation for this particular endpoint, so it looks like that was successful. Let me copy that URL and let's go to our friend, Fiddler, and do a Get and we get a 404. Basically, there's nobody there that can process these messages, so this is the second thing that we need on top of the configuration and the server, I should say the third thing, so we need a message handler. We need something that's going to process messages. So that's get passed to the---let's close that server---second parameter of the SelfHost configuration, so I'm going to say new MySimpleHttpMessageHandler and let's go ahead and just have Visual Studio create that for me, and of course, this has to derive from HttpMessageHandler. I'm going to go ahead and override SendAsync. SendAsync is a method that expects a task and you get passed in the RequestMessage and a CancellationToken. So what I'm going to do is go ahead and print out a message that we've received a message and then I'm going to go ahead and generate the response. So I need to create a task, okay. So I'm just going to go ahead and new a new Task up and the task is of type HttpResponseMessage and then I'm going to end up starting that task and then returning that task. Now of course, I have to fill out the actual body of the task, which is going to be a lambda, and inside of that body, I'm going to have to basically return a HttpResponseMessage. So I'm going to say msg = new HttpResponseMessage. I'm going to say msg.Content is equal to new StringContent, Hello Self-Hosting. I'm going to do a Console.WriteLine to say http response sent with a login here and then I'm going to say return msg. Okay, so that succeeded. So I'm going to go ahead and do again start with the debugging, server's up and running, I'm going to go back to Fiddler, and I'm going to go ahead and go to the Composer and notice I don't have any specific URL handling here. I don't have different methods for different URLs. This is a total generic processor, so I'm going to hit that URL and I get Hello Self-Hosting back and look at the output, you notice we say received an HTTP message, HTTP response sent. If I say composer localhost:8999/foo/bar/quux, notice the same thing happens and over here the same handler handled that request and response. So it's inside of this message handler that you're going to take the incoming request, figure out what it is, marshal it off, or send it off to whatever code, however you want to have that partitioned out, architected, and that code then is going to be used to generate a response and that's the simple self-hosting demo.
-
HttpSelfHostServer
Okay, so as you saw in the demo, the HttpSelfHostServer can be used to create a SelfHost, obviously based on its name. There isn't a whole lot to the SelfHostServer other than passing in the configuration and then potentially passing in a message handler. Once you call OpenAsync, once that task is complete, the SelfHostServer will be up and running. You can close it by calling CloseAsync.
-
Hosting the controller infrastructure
Now as I said, I showed you in the earlier demo, you can have any message handling you want plugged into a self-hosting scenario, but it may be that you actually want to continue with the processing paradigm that the ASP.NET IIS hosting uses, which is this idea of controllers. So what you're going to do is use the HttpSelfHostServer's first constructor, you end up with an HttpControllerDispatcher as your HttpMessage handling. You could create the HttpControllerDispatcher yourself if you want to change its configuration, but what essentially this will do is allow you to just have classes with the name of you know X controller that derive from APIController just like you would inside of ASP.NET Web API.
-
Demo - Using Controllers
Okay, so in the last demo, I showed you a simple message handler. What if you want to use the controller configuration mechanism with the controller execution mechanism from ASP.NET hosting in your own self-host, you definitely can do that. The first thing I'm going to have to do is on the configuration before I pass the configuration into the server, I'm going to have to go to config.Routes, and I'm going to have to Add a new HTTP route, okay. If I want to, I can bring in the namespace System.Web.Http, that's where those extension methods are for the route collection, just simplifies the code a little bit. So I can say MapHttpRoute default, I can give it a route template just like inside of ASP.NET, so API controller, I can even specify, you know, id, and I can specify a new object, an id is RouteParameter.Optional. Okay. So this is actually why the first part of the demo I did in the last demo when I ran it and there was nobody to handle a request, that's why there actually was a message handler. It was the default message handler, which is the message handler for controllers. So I'm going to go ahead and add a controller class, a new class, call it MyController. I need to make it public, I need to make sure it derives from ApiController, and I need to make sure it has some methods on it, so I Get method, return Hello from my Controller in Self-Hosting that's what I will say. So I've got my controller. It's available to the execution of the program. I've got my configuration, I've got my server, so this should work. We go ahead and fire it up and see. Server's up and running. You go over to Fiddler. Now if I go to Fiddler and I say foo/bar/quux, I'm going to get an error, right. I'm going to get a 404 because there's no controllers that match that, but if I type in API/my, I get a 200 and if I look at the response, it says Hello from my Controller in Self-Hosting. So there we go. The same self-hosting mechanism, but with a more sort of sophisticated handling mechanism for handling incoming requests that matches the same way that it works inside of ASP.NET hosting. Again, it's all centered around the configuration and all centered around the message handler.
-
Message handler trick
Now throughout the course, I've mentioned a number of times how cool it is that the HttpClient that's built into the web API is symmetrical with the server-side. The fact that both of these use the same classes that, for example, that HttpServer is a message handler means that you can do kind of a cool sort of demo thing. I don't think that this demo that I'm about to show will have any real use scenario, but it does kind of give you the Zen of how these two pieces sort of fit together. We can basically pass the HttpServer to an HttpClient and by passing the server to the client, the server and the client can communicate, but they're essentially communicating directly rather than having to go over an actual HTTP connection.
-
Demo - Message Handler Party Trick
Alright, so this demo I could call fun with message handlers and all the other demo that I've done in this module I've used Fiddler to call into my HttpServer. I could use any client to call in the HttpServer. How about if I do this? How about if I say Console.WriteLine Server is up and running, Hit Enter to call server with client. It seems like a weird thing to write, but once you see the code, it will make sense. So what I'm going to do is create a new client, HttpClient and notice HttpClient, one of the overloads takes an HttpMessageHandler, guess what class derives from HttpMessageHandler? If I go to HttpSelfHostServer definition, it derives from HttpServer. If I go to HttpServer definition, it derives from DelegatingHandler. If I go to DelegatingHandler, it derives from HttpMessageHandler. So the HttpServer class is a direct descendant class, derive class of MessageHandler, so if I go in here and say I'm just going to pass the server, what can I do? Well now I can say client.GetAsync. What's my URL? The URL is the same URL, localhost:8999/API/my. What do we get from that? We get a task, so using the sort of fluent API, I can get back the task that gets returned from that call. I can get the result and the result is going to be an HttpResponseMessage. What can I do with HttpResponseMessage? I can read it. I can say result.Content.ReadAsStringAsync. This is also something that will return a task, so I can also do ContinueWith. I'll call this the Read task and I'll write client got response + rt.re. You can see that rt.re is the string, which is the result of reading the string from the task. Let's put these all on different lines, make it a little bit easier to read. Okay. So let's just go through this again. I'm passing the server to the client. Why can I do that? I can do that because the client derives from HttpMessageHandler, the client API is symmetrical, the client can also have a MessageHandler passed to its constructor that will do its message handling. So the server is going to take care of the message handling. Here we go. Let's go ahead and run this. I need to close the old instance. So hit Enter to call server with client. Client got response, Hello from my Controller in Self-Hosting. So this is sort of an in process way of calling a server. It could also be called from the outside as well. So notice if I start this up, I go back over to Fiddler, right, it still works as a remote server as well. Nothing I've done has made it not do what it typically would do, but it's also now callable from within my own program. So you know, again, I kind of call it a trick, but there are times where you might have something exposed as a HTTP endpoint and you might want to call that from within the same program. Using this trick, you can still use the same HTTP programming model, so that would be the advantage, right. You can still use that same model and not have to come up with some other way of calling into the message handlers or the controllers.
-
ASP.NET Hosting
Now in terms of hosting in ASP.NET, there's really not a lot for us to do. The only thing that we'll typically do is change the GlobalConfiguration. Now you can do more if you want to change more of what the underlying processing pipeline does, but you know typically if you're hosting an ASP.NET, you're doing it for the particular reason of getting the whole processing paradigm, right, the whole convention, and all the sort of defaults that ASP.NET Web API hosting gives you.
-
Summary
Okay, so in this module, we talked about hosting. From a hosting point of view, your main choices are, do you want to host inside of ASP.NET or do you want to self-host. If you self-host, your choices are how do I process incoming messages? Do I provide my own message handler or am I going to reuse that controller convention that's used in the ASP.NET hosting. Either way, you can remember that the configuration object allows you to have a great measure of control regardless if you're self-hosting or hosting in ASP.NET.
-
Security
ASP.NET Web API: Security
Hi. This is Jon Flanders, and in this particular module, I'm going to talk about the ASP.NET Web API and security. I'm going to talk about the basics of security and extending the security basics.
-
Not much here
So the one thing to keep in mind with the ASP.NET Web API and security is that there's not much here and there's really very little, if any, new. If you are hosting inside of ASP.NET, you're going to get the support from ASP.NET for authentication and authorization. If you're self-hosting, the HTTP stack is provided by WCF, so you'll be changing the binding security settings in order to change or enable security in the self-hosting scenario.
-
Authentication
Whether you're self-hosting or hosting inside of ASP.NET, authentication from ASP.NET HTTP point of view is fairly similar. We either have anonymous access, we have forms authentication, we have basic authentication, and we have Windows authentication. We're talking about the classic authentication mechanisms for HTTP. So if you want to explicitly allow anonymous access to a particular action on your controller, you can add the allow anonymous attribute. If you're doing forms authentication, of course, if your API is being called by a browser application, the user will have already been presented with the form, the user will log in, the user will get a cookie, and therefore, will have access to your API. If you're interested in providing access to your API with forms authentication in a non-interactive app, so a non-browser app, maybe even a client app, you can programmatically call the account/jsonlogin endpoint if you use the MVC project templates or there's also the authentication_JSON_AppService. You can enable that from any ASP.NET project for forms authentication. And so then you'll provide the username and password and the application will get the cookie, continue to use the cookie, the application will continue to be authenticated. Basic authentication is well understood by most client libraries and if you're using Windows authentication, HttpClient, WebHttpRequest and WebClient all understand Windows authentication as well.
-
Authorization
Now when it comes to authorization, which of course, is really orthogonal to authentication. You can use the authorize attribute on individual actions or you can go with the good old web.config and modify the web.config in the ways that we've always done in ASP.NET. So again, nothing really new here. If a user is authenticated, but can't call a particular URL because their credentials don't match with the authorize attribute, they'll get a 401 Unauthorized.
-
Demo - adding Authorization to Self Hosting
So now I'm going to show you a demo of adding authentication to a self-hosted web API host. What I've got here is a simple host. This is essentially the first demo I did in the hosting module, so if you didn't watch that module yet, just a little bit of overview. Basically, I'm creating a new SelfHostConfiguration, I'm creating a new SelfHostServer with a simple message handler. My message handler derives from HttpMessageHandler. And then inside of the message handler, I'm receiving the message, generating a task that's going to return the response message, and then generating a simple StringContent message. What I'm going to do is I'm going to add a little bit of code here first. What I want to do is I want to get the username. So I want to go to Thread.CurrentPrincipal.Identity.Name and I want to say Hello back to the user who's logged in. So basically echo back the logged in user, whoever the authenticated user of the service is. Now to actually add authentication requirements to the SelfHost, the first thing I need to do is modify the SelfHostConfiguration and the best way to do this is just to create your own configuration class, so I'm going to create a configuration class called MyConfig. I'm going to let Visual Studio create the class for me. I'm going to make sure that this class derives from the correct base type, which is HttpSelfHostConfiguration. I'm going to add a constructor that takes in the address. Remember, I have to pass in the base address to the constructor of the base class, so let's chain those constructors together. And then I can override OnConfigureBinding. So what OnConfigureBinding is going to do, it's going to have me use some binding types from System.ServiceModel. The problem, of course, is, in this case, I don't have a reference to System.ServiceModel, so I'm going to get rid of these namespaces. I do have a reference to the namespace where the binding exists, but I don't have a reference to the assembly that contains the namespace for BindingParameterCollection. So I'm going to go ahead and add a reference to the appropriate assemblies, which are System.ServiceModel and System.ServiceModel.Channels. Now I can add a using statement for the BindingParameterCollection and what I can do then is modify the binding. So I'm going to say httpBinding.Security.Mode = SecurityMode.TransportCredentialOnly. So that's going to tell the binding, WCF, that I want credentials provided, so I want authentication, the user must be authenticated to the system. And now I need to tell it what kind of authentication to use and I go to the Transport security setting and set the ClientCredentialType to Windows. So let me move this to multiple lines, so you can see this a little bit better. I'm setting the ClientCredentialType to System.ServiceModel.HttpClientCredentialType.Windows. So that being done, I can go ahead and build. I can go ahead and start my service. If I go to the browser and I type in that URL, which is http://localhost:8999, I get back Hello JonWindows8, which is my machine name, Jon, which is the user I'm logged in as. Now if I want to do something different that sort of proves that there's some authentication going on because IE sends the authentication token automatically, I could go to another browser like Safari, which it doesn't send that information automatically. And if I go to http://localhost:8999, it'll ask me to log in, and once I log in, I get the same effect, okay. So that's just a simple example of how you modify the binding through subclassing the HttpSelfHostConfiguration class to get the effect you want, which is adding some sort of security to the SelfHost.
-
Self hosting
From an authorization point of view and authentication point of view, WCF follows a very similar model to ASP.NET. It's just that the switches are slightly different. Again, in self-hosting, we're going to have to modify the binding, so what we're going to do is create our own HttpSelfHostConfiguration object by deriving from this is the base class, we override OnConfigureBinding, the HttpBinding object gets passed into us, and we'll go to the security property of that binding and modify that binding as appropriate.
-
OnConfigureBinding
So in this example, I've got an override here, so I'm changing the mode to TransportCredentialOnly and the ClientCredentialType to ClientCredentialType.Windows, then basically calling the base.OnConfigureBinding and returning the Base configured binding from the OnConfigureBinding override.
-
Summary
So again, not a whole lot in terms of security. One of the things that you might want to do is do some sort of TokenAuthentication using something like OAuth or OAuth2 in the newer sort of modern forms of HTTP authentication that are out there. If you're interested in that, you should go to the Pluralsight website and look up Dominick Baier's course on authentication with ASP.NET 4.5 and 4.0. In that course, he goes into a lot of detail on how to make this work with ASP.NET, and of course, also with the web API as well.
-
Extensibility
Extensibility
Hi. This is Jon Flanders with Pluralsight, and in this module on the ASP.NET Web API, I'm going to talk about extensibility. So the outline of this module, we're going to first talk about the HttpConfiguration type and how we can use an instance of that type to modify configuration. Then we'll talk about the different things we can modify things like filters, and formatters, and message handlers. We'll talk about when to use which of these different objects. And at the end, we'll talk a little bit about dependency resolving.
-
Getting started
So I mentioned this in other modules in the course, but it bears repeating that if you want to modify the way the ASP.NET Web API is working inside of the context that you're running in, you're going to need to modify the appropriate HttpConfiguration instance. If we're talking about ASP.NET hosting, that instance is going to be the GlobalConfiguration.Configuration property. If we're self-hosting, you'll be creating your own instance of the HttpConfiguration object directly. Typically you're going to change the configuration in the global.asax.cs if you're hosting in ASP.NET. Regardless of where you're going to change the HttpConfiguration, you're going to modify those properties that relate to the thing that you want to change. So a couple of miscellaneous properties. One is include error detail policy, so this is similar if you're a ASP.NET web programmer to the custom errors element in the Web.config, but this is for the web API. So we have a LocalOnly, which means exception details will only be shown when you're making requests from localhost. Always show exception detail or never. Generally, LocalOnly is the default and that's probably a good default. The Properties property is essentially a property bag. You can store the objects and values and that will stay around for the whole lifetime of that configuration object, so it's an interesting way to pass data between different pieces of extensibility that you might be adding into the web API processing pipeline.
-
Formatters
Now the first piece of extensibility we're going to talk about is formatters. Formatters are important because if you want to extend the ASP.NET Web API to handle media types that aren't built in, you'll need to create a MediaTypeFormatter. The MediaTypeFormatter is going to be responsible for doing the serialization or deserialization depending on if it's on the request side or the response side. So basically what you're going to do is create a new MediaTypeFormatter, you'll derive from that base class, and then you'll add it to the HttpConfiguration.Formatters collection. This will allow you to handle different types of Content-Types both on request and responses, again, that are built into the web API by default.
-
Demo - Formatter
So what I'm going to do now is a demo of using JSONP. If you're not familiar with JSONP, let me talk about it after I create the web API project because it will take a second. JSONP is a way to interject JavaScript into a page loaded from a different domain. It's used extensively on the web with Facebook, with Twitter, with Bing Maps, Google Maps, and a number of APIs, analytic APIs, web trends. So what I'm going to do is I'm going to modify this class in such a way that I can make it return JSONP. JSONPs media type is application/javascript and that is not a media type that the ASP.NET Web API handles by default. So what I want to do is change this Get method to return not a string, but an HttpResponseMessage and I'm going to take in a second parameter. The second parameter I'm going to take in is going to be a string and I'm going to call it callback. So what callback is going to do is it's going to be the method that the caller of this service wants me as the generator of the JavaScript to call. So what I'm going to do is create a new type as the content of my message. I'm going to call this JSONPReturn. And JSONPReturn, what I'm going to do is I'm going to have two properties, one property is going to be the callback and I'll set that to the value passed in and the other property is going to be some JSON and that I'm going to build up from a string. So I'm going to go ahead and let Visual Studio create this class for me. I'll let it create properties for these two variables. I'm going to go make sure that this is set to public, however, because it needs to be public for the serializer, and then what I'm going to do is, I'm going to come back to this in a second, I'm going to create the message, so I'm going to say msg = Request.CreateResponse. The response type, or I'm sorry, the StatusCode is going to be OK, the content is going to be that content variable, and then the last thing I'm going to pass in is application/javascript. So the overload of CreateResponse that I'm using is the one that takes these three parameters and I'm going to go ahead and say return msg. Okay. So the problem is if I called this right now---and let me go ahead and fill in the JSON quickly here---if I called this right now, the problem is that the ASP.NET Web API infrastructure---sorry I need to put this value in quotes---would return JSON or XML. It would return whatever it could return based upon serializing that data type, but that's not what I want, right. What I want is---and let me go ahead and pass in some data. I'll say Hello from JSONP Web API Style. So there's my string that really is the JavaScript that's going to execute in the browser. What I want it to do is return an actual piece of JavaScript, so I need it to return this content type. And if I want it to return that content type and it's not a content-type that there's already a formatter for, I need to add a formatter. So I'm going to go into the Global.asax and during the configuration of this app, I'm going to go to GlobalConfiguration.Configuration.Formatters, and I'm going to insert a formatter at the beginning of the list of formatters, and I'm going to say new MyJSONPFormatter. Of course I need to get Visual Studio to generate that class for me. If I go to the class, this class needs to derive from the special base class, which is MessageTypeFormatter, (Working) which is MediaTypeFormatter. MediaTypeFormatter is in a different namespace. I'll bring that in. I need to add a constructor, and inside of that constructor, I need to add to the SupportedMediaTypes a new media type header value that that is going to be application/javascript. So that takes care of telling the infrastructure that when you see a message that is of that particular media type. Let's go ahead and see if the JSONP formatter can serialize it. Now I do have to override two methods, CanReadType, I'm just going to return false because I'm never going to read messages, but I also need to override CanWriteType, and CanWriteType, I'm going to say return type== typeof JSONPReturn because in this case, there's a fairly tight relationship between my type and my MediaTypeFormatter. Okay. The last thing I need to do is actually override the method that's going to allow me to write to the stream, and so what I can do is, again, this is going to be one of those task returns. I get passed in the type, I get passed in the object, I get passed in the stream I need to write to, I get passed in a context, and I get passed in transportContext. In this case, the only thing I really need to do is return a task, so I'm going to say return Task.Factory.StartNew, and inside of StartNew what I'm going to do cast the object to the right type, so var jsonp = JSONPReturn value. I'm going to create a StreamWriter on top of the output stream, (Typing) and then I'm going to specify the encoding is UTF8Encoding, and then I'm going to write to the stream, so I'm going to call sw.Write. I'm going to go ahead and pass in a format string, and my format string is going to look like this. What the format string is creating is essentially a line of JavaScript that's going to execute and that line of JavaScript is going to have the jsonp.Callback and the jsonp.JSON. So those will get filled in when the string gets formatted and then I'll go ahead and say sw.Flush. Okay, so let's just go back over this. I created a controller that returns an HttpResponseMessage that has a particular content, its object content, and it has a particular content type. I've got the return type that contains the Callback and the JSON and then the formatter takes care of putting the two together and writing to the output stream. The advantage here is I would be able to create multiple types and have the formatter be able to deal with all of them, right, if I needed slight variations in the way I needed to deal with JSONP. Now I need to create a client. I'm going to go ahead and start that while I'm creating the client project. So what I need to do is I'm going to create an empty ASP.NET project as the client. Let's leave that JSONClient. To the JSONClient I'm going to add an HTML file. Let's call that default for good measure. In the default HTML, what I want to do is I want to bring in that script, so I'm going to say script src equals to, I need to get the port of the site. Let's go back to the browser for a second. So this is 3403. So I can say http://localhost:3403/API/jsonp, I'll say id equals to 42 and callback equals to myCallBack. So what I need to do is put in a little script that has a function with that same name. So myCallBack, it's going to get in an object, JavaScript object. Then what I'm going to do is put in an h1 tag. I'm going to give it an id of message, and inside of this callback, I'm going to say element equals to document.querySelector on the id of msg and then I'm going to say element.innerText equals to obj.data. Okay. So let's go see that this works. I'm going to go ahead and go here and right-click and say View in Browser and you can see that this works. Interesting thing to do would be to look at the F12 Developer Tools. I'm going to go ahead and doc them back into the browser window, go to Network, Start capturing, and refresh, and you can see there's the call to the callback and the response body is this particular piece of JavaScript, which automatically executes and calls the callback function.
-
Filters
Another piece of extensibility is filters. So filter allow you to do things like pre and post process requests before they go into a controller and a method on the controller. Filters hook into the model binding and controller execution pipeline. So anything you want to do that's a very generic sort of addition to your web project, your web API project, you can create a filter. AuthorizeAttribute, for example, is an Ifilter instance or implements Ifilter. So AuthorizeAttribute is that thing that makes a particular method on a particular controller require authentication credentials before you can get into it.
-
Message Handlers
Now another piece of infrastructure that you can modify is the actual processing pipeline and that's done by creating what's referred to as a message handler, okay. There is another class called DelegatingHandler that you're going to derive from if you're going to build your own message handler, but the whole stack, both in the client and the server, are built based upon this particular message type. So the HttpClientHandler, the HttpControllerDispatcher that dispatches to ApiControllers, all of these pieces of infrastructure are message handlers, and so if you can plug your own message handler in replace of one of these, you can control the way that messages are processed.
-
Demo - Message Handler
Okay, so now I'm going to show you message handlers. I'm going to show you this in the context of another very typical HTTP issue. Let me go ahead and start creating my web API project. I'm going to call it XMethodOverride. Here's the issue, we want to create a uniform interface that is based upon Get, Post, Put, and Delete. Unfortunately, some HttpClients have limited access to certain verbs. Many HttpClients can only do Get and Post. Many are forbidden from doing Put or Delete. Flash is one, you know, there are a number of them. So the way that many people have gotten around this is by allowing those types of clients to add an extra header, which is the X-HTTP-Method-Override, and adding that header then allows the infrastructure to say oh you're doing a post, but then you're telling me in this header that you'd really like to do a delete, let's make that happen. Now of course, in the web API like most other frameworks, you're going to have to do something to make that happen. The thing we're going to do to make that happen is we're going to add an additional message handler. So here in the Global.asax of all places, we're going to go to GlobalConfiguration.Configuration.MessageHandlers and we're going to Add a new message handler, call it MyMethodOverrideHandler, go ahead, and create that. So I've added this to the configuration. Now of course, I need to derive that class from the appropriate base class, which is a DelegatingHandler. What I'm going to do is create a const string called header, that's the header that I'm looking for, X-HTTP-Method-Override, and then I'm going to override the SendAsync method. So SendAsync method as you can probably imagine returns a task that generates an HttpResponseMessage. SendAsync method gets in the request, as well as a CancellationToken and we should watch for a cancellation in case the infrastructure decides to cancel. So what I'm going to do is just check to see if the request.Method==Http Post and if the request.Headers collection Contains my header, I'm going to get the realverb by going to request.Headers.GetValues header at FirstOrDefault assuming that that's not null, which it shouldn't be at this point, but let's just be safe. I'm going to say request.Method equals to new HttpMethod realverb. So basically what I'm doing here is--realverb does not equal null---what I'm doing here is just adding a little bit to the context, changing the context so that if it's a post and there's an X-HTTP-Method-Override found inside of the headers, then it's going to go ahead and route that to the appropriate header, rather than to post. So let me go ahead and set a breakpoint in put, and a breakpoint in delete, breakpoint in post for that matter, and let me go ahead and debug this. I'm going to use my friend, Fiddler, to go to localhost:3488, 3488/API/values. Let's just make sure that's correct. Okay, we're getting back a 200. So this is the way this would work, the client would do a post, then it would add the HTTP-Method-Override and say no I really want to do a put and then the request body would contain the correct body. (Working) And let me go ahead and execute this and notice that we get thrown into the put. How did we get thrown into the put even though we did a post and that's the magic of the Method-Override handler, so let's go set a breakpoint here, so that we can see that if I go back and do a post again, the message handler is going to get that, it's going to look at the context, it's going to say yes the request.Method is post and it does contain that header. Let's get out the realverb, the realverb is put. Go ahead and change the method to the realverb and now the routing infrastructure is going to take it and drop it into the right place in my controller.
-
Deriving from DelegatingHandler
Okay, so here's an example of creating a DelegatingHandler. Essentially, you're just going to do your work inside of the SendAsync method. You get passed in the RequestMessage and a CancellationToken in case the requester cancels the request, and then you'll return the task, which will result in an HttpResponseMessage.
-
Action Filter vs Message Handler
Now the real pivot point or choice point here becomes if I want to build something additional, do I create an action filter or message handler? Basically have to think about where in the processing pipeline these objects live. So MessageHandler lives before model binding, so it's more at the HTTP message-level. An ActionFilter, Ifilter, I more geared towards doing operations after the method that's going to be invoked has been selected, so things like object validation would be done at that point. If you want to do something like schema validation if you had XML messages, you'd probably want to do that in a message handler. As-is the case with any sort of processing pipeline, there are sometimes when you could do the same thing in either level, and so then it's just a design choice based upon your preferences, maybe based upon are you building everything else as an action filter, well why muddy the waters and create a MessageHandler, why not just create another action filter. Oftentimes, it's more of a pragmatic choice than a technology choice.
-
ServiceResolver
The last thing I'll talk about briefly is this idea of the ServiceResolver, the dependency resolver. Basically, one of the design goals of the web API was to make it extremely to unit test. One of the ways that objects become easier to unit test if you can replace functionality at runtime very easily with you know not the real object. So the web API was built from the ground up with this in mind, and so if you want to have your own IoC container plugged into the configuration, you can implement IDependency Resolver, set the appropriate property, and then your dependency resolver will be used in place of the built-in one.
-
Summary
So the whole ASP.NET Web API processing pipeline is built from the ground up for its sensibility. You can use message handlers to deal with HTTP, you can use filters for action and model-related issues, and if you're doing different kinds of content negotiation, then the web API supports out-of-the-box, you can create your own MediaTypeFormatters. Regardless of which of these pieces of extensibility that you plug into the processing pipeline, you'll always use the HttpConfiguration object to modify the current state.