 Hi, folks. Welcome. My name is Daniel Roth. I'm a program manager on the ASB.NET team. In this session, we're going to be talking about what's new in ASB.NET Core. Hopefully, you heard earlier today at the keynote that ASB.NET Core 2.2 Preview 2 is now available for you to download, to install, and to try out. In this session, I'm going to talk about many of the new features that are now available with this preview release. I'll also talk about some of the additional investments that we're planning to make for the final 2.2 release. To get started with ASB.NET Core 2.2 Preview 2, you're going to want to go and download and install the latest.NET Core SDK, the 2.2 Preview 2 SDK. You can get that from the ..NET website and install the Preview 2 version. If you are on Windows and you're using Visual Studio, you're going to want to get the latest preview release version of Visual Studio 2017. That would be 15.9 Preview 2. You can get that from visualstudio.com slash preview. Or also, if you already have the preview channel installed, you can just update to the latest release. Now, all of these installations are side-by-side installations with existing stable releases. I have on my machine multiple stable and pre-release versions of the .NET Core SDK. I've had two different preview releases and a stable release of Visual Studio. They all work great side-by-side so you can install them without fear that they will have any impact on your development workflow. Let me show you quickly how to go and do that. Let's just hop over to a browser real fast. To get the 2.2 SDK, you're going to want to go to ..NET and then go to the Downloads page. That's the Downloads tab up top. You should see this nice banner at the top of the page that says, if you want to try out 2.2, make sure you download the Preview 2 installer. If you click on that link, that'll bring you to this page and you're going to want to install the SDK. For your platform and architecture of choice. Then after you've done that, if you also want to deploy 2.2 applications to an IS-based environment, you're probably also going to want to go over here and install the runtime and hosting bundle. Once you've installed the SDK, you should be able to verify that things are all set up and working by going to the command prompt and typing .NET-version. You should see a 2.2 version of the SDK for Preview 2. Actually, if I run .NET-info, you can see that I've got lots of SDKs installed. Like I said, these things are all side by side and they work great together. They uninstall cleanly. Now, if you're using Visual Studio, you're going to want to go to visualstudio.com slash preview and install the preview channel of Visual Studio to use these bits. If you already have the preview channel, just make sure you update so that you're on 15.9 Preview 2. Okay. So let's create our first application. So I'm going to clear the command prompt here a little bit and let's do .NET-new. I'm going to create a new web app and let's put it in a web app one directory. What this will do, this will create me a new ASP.NET Core 2.2 application and just put it on my desktop. That will work on Windows Mac or Linux or whatever platform you happen to be working on. If you're in Visual Studio, you can just open up Visual Studio, file a new project and if you go to create an ASP.NET Core ASP.NET Core web application, click okay. In the new ASP.NET Core web app dialogue, you should see that ASP.NET Core 2.2 is now available for you to use. Go ahead and pick the default web application template and you're good to go. So that's how you can create your first application. Now on the project templates for this release, we've made a bunch of tweaks in particular for the default templates. If we look at the layout, you can see that we are now using, let's see, we can find it. There it is, Bootstrap 4. So our templates are now Bootstrap 4 based, so you get a nice fresh UI. In fact, we took this opportunity to go through the template content, simplify things a bit and give it a fresher look. So if I run this application, you can see what the new template looks like. We've basically tried to remove all the extra code and content that you don't really need. So there's less stuff for you to delete when you're trying to get up and going with your application and this is what it looks like. So that's the new template. It's based on Bootstrap 4, a lot more minimalistic. We hope you like it. Let us know what you think on GitHub. Other things that we've also done, if you're working with spa frameworks like Angular or React, if you go to create a Angular application, I'll do that one real quick as well, we've updated all the client-side frameworks as well. So the Angular application is now based on, let's see, if we go into the client app folder, packages.json, you can see now it's based on Angular 6. I believe Angular 6.1 has also recently come out. These frameworks move pretty fast. As much as possible, we will continue to update these templates to use the latest versions of the client-side frameworks. But for now, you can go ahead and use ASP.NET Core with Angular 6. So that's how you can get started. Here are the new features that are included with the 2.2 release. We've already seen the support for Bootstrap 4. That includes Bootstrap 4 support in the templates, but also in our scaffolders and in our default UI. Now, if you're still using Bootstrap 3, you're not quite ready to move to Bootstrap 4. The scaffolders and the default UI still support Bootstrap 3 as well. So you can still scaffold Bootstrap 3 content. You can still use the Bootstrap 3 version of the default UI. Web API improvements is the big theme for this release. For 2.2, we really want to make API and service development easier and better. We'll talk more in detail about that in just a second. Other new features, we've added support for HTTP.2 into Kestrel. We've added an in-process hosting model for IAS to have much better performance and reliability. We've integrated a health checks framework into ASP.NET Core in this release so that you can make sure that your APIs and apps are live and ready for traffic. We've revised routing significantly in this release into a new routing system that we call endpoint routing, which has much better performance and also takes a lot of the concerns that are today handled in MVC and makes them available much lower in the stack. So for example, if you want to generate a link from a middleware, you can now do that in 2.2. And finally, we've added a Java client for ASP.NET Core, SignalR. Now APIs are everywhere. Regardless of what type of application you are building, you're probably interacting with some sort of backend API or service. And that API or service may in turn be interacting with other APIs that may be hosted in your local data center or they may be hosted in the cloud. In 2.2, we want to make API development much better. So what are we doing in this release? Well, we're trying to make API and service development make APIs and services easier to create, make them easier to test and to debug, easier to document with standard specs like open API specs, easier to consume, including things like client code generation, easier to secure, easier to monitor, and then all of the performance features, related features that we've done in this release of course also apply to APIs so that your APIs get faster and more efficient. Now I'd like to show you what I mean. What I'm going to do now is I'm going to walk you through a development flow of building an API, testing it, and consuming it from a client application. And as I go along the way, I'm going to try and highlight the improvements that we were making in 2.2 preview two. And then I'll also try and point out areas where we're still applying to make additional investments in this release. So let's go do that. All right, so let's go back to Visual Studio and let's create a new project. And what I want to create here is I want to create an API that's going to be an API for managing data about pets. It's going to be a pets API. So let's call this pets API. Do I ever have a pets API project? Let's see. Looks good. All right, and then let's go ahead and use the API template for ASP.NET Core 2.2. Awesome. Okay, so what does this template give me by default? Honestly, not much. I get this very simple values controller, a very simple API that just, well, it returns a set of static strings or an individual string. And then the post, put, and delete actions, well, they don't do anything at all. But at least they're there. This API does at least use the new API controller conventions that we introduced in 2.1. If I run this application, what will it do? Well, it build, and then when it runs, well, it just uses the browser to browse to one of the API endpoints. It browsers to slash values and just returns the JSON. So that's okay. I mean, but with a browser, it's not the best tool for doing API testing and debugging. I mean, it really can only do get requests by default unless you wanna write some code. Maybe we can do better. So what we're doing in 2.2 is we're introducing a new tool that we call the HTTP REPL. And it's a .NET Core global tool that you can install a machine that gives you a command line interactive REPL for interacting with API endpoints. All right, so how do I get this tool? So you install it from the command line. It's a .NET Core global tool. So .NET tool install. And we're gonna install it globally, so dash D each install it globally. And the version that you're gonna wanna get right now, now this tool is currently not available with the preview two release that we just shipped. It's not currently on NuGet quite yet. It will be in the next few weeks. So if you wanna get it today, you should be installing it from our CI dev feed on my get. So the version you're gonna want right now is 2.2 dash, just pick the latest preview release dash star. And then you're gonna need to add an additional NuGet source in order to acquire this tool. Now I'm not gonna hand type that on the fly. I've got it copied over here. Let's go ahead and grab that. So there's the my get feed that you're gonna wanna use. Let's make this a little bigger. So .NET Core API and then the JSON file for the feed. And then the package ID for the tool is .NET dash HTTP REPL, okay? When you run that, that will then install the tool on your machine so you can then execute it. I've already installed it and I can verify that by doing .NET tool list dash G to see all the global tools that I have in the machine. And you can see I've already got the HTTP REPL installed. All right, cool. So now I should be able to do .NET HTTP REPL. And that will then pop me into this interactive REPL for interacting with API endpoints. Now right now it says it's disconnected. It's not connected to anything. So what would we do? So we can use this REPL to talk to either ASP.NET Core APIs or really any API that you want. So for example, I could point it at the GitHub API. So let's point it at api.github.com. All right, cool. So now it says it's connected. And if I run the help text just to see what this thing can do, you can see that from the REPL I can issue any HTTP request for any HTTP method. I can set headers. I can, whoa, it looks like it has information, it knows how to deal with Swagger documents. So if you have an API that has a open API spec or a Swagger document, the tool can light up additional functionality. For example, it allows you to traverse or navigate the URI space of your API using file system like commands like LS or Durr and CD. So that's pretty cool. And then there's also a capability to run scripts. Like if you want to set up a bunch of REPL commands that you just run as a batch, you can run them all together by just creating a file. All right, so let's try this out. So I'm just gonna clear the screen. Let's try just sending a GET request to the GitHub API and I get a nice colorized response from GitHub. GitHub is a great API. They are hypermedia based, so the response is giving me a whole bunch of links that I can use to then traverse to other resources that are available through the API. I don't know. For example, look, here's the emojis URL. So if I, let's see, what is it? github.com slash emojis. So if I do a GET to emojis, that should give you, whoa, yeah, it gives me a list of a link to every single emoji that GitHub supports. And there are apparently quite a few of those. And we're at the Z. So if I grab one of these links and pop it in the browser, supposedly, if GitHub's doing their thing, then I should be able to see an emoji. Yeah, so there's the ZZZ emoji. Okay, so that's pretty cool. Likewise, I can point this to my web API for ASP.core. Let's try that. So I'm just gonna grab the base URL for my ASP.core API. So set base, let's set the base to there. Good, and then I should be able to issue a GET request. And, well, currently at the root, we don't have anything that's due to API slash, was it values, is there API? Yeah, okay, so I can use the REPL to test API. Now this API is not particularly feature rich. So let's replace it with an actual pets API that we can use. So let's go back to Visual Studio. And I'm just gonna go ahead and delete this values controller. And let's create now a pet model that we can use to scaffold out our API. So right click, let's add a models folder. All right, and let's just add a class here. And we'll add a model for our pets. So let's call this pet.cs. And let's just add a bunch of properties on here. Let's give a pet an ID. Let's give it an owner. Let's give it a name. Let's give it like a type, like what kind of pet is it? Is it a dog, cat? And let's give it also an age. All right, so there's our pet model, looks great. Let's create an API. And we're gonna use scaffolding to help us do that. So I'm gonna add a controller and I'm gonna pick this API controller with actions using entity framework core. So what that will do is that will inspect my model and then generate an API for me using entity framework core to manage the data. So I'm gonna pick my pet model. I don't currently have a data contact, so I'm just gonna go ahead and create one. And then pets controller for the controller name sounds great. So go ahead, Visual Studio, create for me my pets API without me having to write a whole bunch of code. And so the scaffolder runs, it's inspecting the model type and let's see if that's gonna work. All right, cool. And so this is saying that the app settings that JSON file got updated, that's just because it added a connection string for the database. And now I've got a much more feature rich API. It's got actions for getting all my pets, getting individual pets and then put, post and delete. And these are our action methods that actually have code in them. Like it's using a database context to save data and manipulate data. So that looks good. All right, now one more thing. I wanna switch the launch URL for this application to no longer be API slash values. In fact, let's just put it at the root. So, and I wanna use my HB REPL to now test this API. How can I do that? So I'm gonna wire it up in Visual Studio and the way I'm gonna do that is by going to browse with in the dropdown by the little run button. And that will allow me to select which browser I'd like to use for testing my API. So instead of using the like a normal browser like edge, I'm gonna use the HB REPL. So how did I do that? I just clicked add and then you specify the path to the HB REPL executable. You can see that down below it's in your user profile under the dot.net tools folder. And so that's how I set that up. So let's browse to our API using the HB REPL. All right, cool. So now I should be able to do a get to like API slash pets and this is probably gonna crash because I haven't done anything with migrations because this app actually now has a database. So let's quickly run migrations. Let me run to the package manager console and let's do add migration. And I'd like to call my first migration initial and I like to put my migrations in the data migrations folder. I like to keep everything under the data folder. So what that will do is that will generate some code for setting up the tables in the database. And it looks like that worked. You can see the migration code is over here. Now we just need to apply that migration. So let's update the database with the migration and that will allow entity framework core to then run that code to generate a whole bunch of SQL for setting up the tables for my pets API. I'll just give it a second and there goes a whole bunch of SQL. Okay, so now it should be all set up and I should be able to reissue that get request. One of the things I really like about the REPL is you just arrow up and re-execute and okay. Now we've got an empty array of pets. We don't have any pets yet. Okay, so how do I add some pets? Well, I could do it also from the REPL right now but the REPL can become much more feature rich if we actually enable swagger for my API. Like give it an actual spec, an open API spec so that the tool can figure out well what's the URI space for this API? What types does it expect? The HP REPL can help me with those things if it has that information. So what I'm gonna do now is go ahead and enable swagger generation for my pets API. So let's go back to the project. I'm gonna use a community project called Swashbuckle to enable swagger documentation. So let's manage NuGet packages and I'm gonna add swashbuckle.asp.core and let's browse for it on NuGet.org, there it is. And let's go ahead and install that. If you haven't used Swashbuckle before, it's a great open source project that does swagger generation for asp.core applications. This is the GitHub repo and it's got actually some really nice documentation on the readme for how you set it up. So now that the package is added, let's see what do I gotta do? Well I gotta add the swagger gen services. So let me go back to my API and let's go ahead into the startup and go to configure services and add the swagger gen services. Let's change from my API to pets API and just add the missing using statement. Great, okay, what else do I gotta do? Okay, I'm gonna make sure my API follows the right programming model convention so that it indicates what its HP methods are and so forth. I'm already doing that because I scaffolded my code, the scaffolded code from asp.core already follows those conventions. Now I just need to add the endpoint for exposing the swagger document and also the swagger UI. Okay, so I add some middleware to my middleware pipeline. Let's use some swagger and then lastly let's use the swagger UI. All right, cool. And again, let's change this name to pets API. All right, awesome. So now if I should already be rerunning, well actually one of the nice feature of the REPL is that once I've got swagger generation set up, I should be able to just type UI and it will bring me directly to the swagger endpoint for the API. Let's see if that works. And there it is, okay. So now I can see my, using the browser, I can see all the endpoints from my API. If I wanna see the actual raw swagger content, that's this JSON file that's linked from that main UI page. And this is nice so I can do things here now. Like if I actually wanna issue a post, this swagger UI will help me do that. So let's try out doing a post. It gives me, it knows the type information for the post action so we can do things like say, like the owner of this, let's add a new pet. So the owner of this new pet will be me. Let's call it spot. Let's say it's gonna be a puppy and let's give it an age of one and then set the content type to just normal JSON and execute that. And voila, okay, so we got a 201 response and we've created our new resource. Now down here below, you can see that the swagger UI is showing me all of the responses that are supported by this endpoint that are advertised in the swagger document. And currently it says, well it returns, well actually it says that it turns 200s instead of 201s, it was interesting. So it's not quite right and I'm sure there's probably some error responses that it returns that aren't listed here. So for example, if I go back and try and add another puppy, but instead of its age being one, I said its age is ABC, which is gonna be invalid and execute that. Yeah, like I expected, I get a 400 response and the response body, oh, this is nice. This is a new feature in preview two of 2.2. We now return problem details responses by default for APIs and we even include a nice trace ID so that you can correlate that error response to other activities in your application. But that's not advertised anywhere in this swagger document either. Why is that? Well, those are things that Swashbuckle wasn't able to determine just by inspecting the application. So we have to do a little more work to add some attributes to make it aware of those things. And we can do that. We can go back to the pets controller and we could go to the post action and use the appropriate attributes. I happen to know that it's something like, I think it's produces, response type, and then you specify the status code and what type it returns. We could do that manually. That would be pretty tedious and there would be no good way to enforce this across all of my API. So how can I do that? Well, one of the things we've shipped in with 2.2 is we've added an API analyzer that will look at all of your API actions and determine by convention what types of responses they should, they will generally return and it will give you code fix ups so that you can add the appropriate metadata. So let's add that analyzer. So I'm going to go to manage new packages and let's do Microsoft. This is the analyzer package, Microsoft Ace Minute Core, NBC API analyzers, and let's go ahead and add that to our app. And that should help us out with cleaning up our swagger documentation, all right? Okay, cool. So now if I look in the error window, you see that I'm getting all of these warnings now from the analyzer letting me know that I have action methods that are returning responses that aren't documented anywhere on the controller, none of the appropriate attributes are there. So let's click on one of those. Let's go to this one for example and we can right click and let's do a fix up. So if we use the analyzer fix up, boom. So it adds all of the appropriate attributes so that the swagger document is cleaned up. So the analyzer helps me enforce that my API is appropriately documented. But even so, it's still kind of tedious to go one by one to each action and add all these attributes. Is there a better way? And the answer is yes. In 2.2, we've added some API conventions where we can determine this metadata by convention. So if your action looks a particular way, we will go ahead and apply the appropriate attributes for you. Now to apply this particular convention, what you do is you add API, I'm saying it was API convention and type, I think is what it's called. I'm gonna apply the conventions globally across my assembly. You could also apply them per controller or per action. So let's see, assembly was an API convention type, yeah. So I'm gonna use the, we provide you a default set of conventions that you specify using this default API conventions type. And those conventions match the code that's produced by the API scaffolders. So if I now, I think I can get a type of in here. There we go, perfect. Okay, and now if I go look at my error list, suddenly all the analyzer warnings have disappeared and that's because by convention, the runtime is now saying, oh, well all these actions match this pattern. So it provides you the appropriate, effectively adds the appropriate attributes. Now if I go back to my swagger document and take a look at it, let's see if we now have a better swagger experience. Okay, so let's look at like so post. Let's see, so yeah, so now post correctly says it returns a 201 or a 400 if you have a bad request. If I look at get, you might specify an ID that doesn't exist. So this should return a 404 and yep, now that's advertised. So those are all being applied for me and being enforced by the analyzer. If I deviate from these conventions, the analyzer will let me know. That's super nice. Now if you don't like the default conventions that we give you, you can of course use your own. They're pretty easy to implement. These conventions are just implemented as a static type where the methods on the type basically define a pattern that should be matched and the appropriate metadata should be applied. So for example, for a get, a get action, if you have a method, an action method that starts with get, this is a prefix match. If you have a method starts with get, then it's saying apply these additional metadata attributes. If it also has an ID parameter or at least a parameter named, has suffix with ID and is of any type. In that case, it'll match and it'll apply the appropriate attributes. So if you define your own API convention type, the convention, the analyzer will pick up that convention and help you apply them as well, similar to giving you warnings and such over your code. So that's how you can have better documentation for your API. And so now I should be able to go back to my HP REPL. Let's see, let's, am I okay? Yeah, so let's clear this and let's see if we can get some more information. Yeah, so now when I do LS and CD, I can see the API surface area, like the UI space, I can see the API, let's see what's here. There's a pets endpoint, that's super nice. And I can even see which HP methods are supported at each resource. I can see routes that take route parameters, like I know there's one that takes an ID. So let's see if we can get our puppy. Okay, our puppy is there. I could get like an individual puppy, like get one, that's the individual one. Let's add some more puppies now. Or some more pets. They don't have to be puppies. So let's post a new pet. I need to specify the content type of what I'm gonna post. So I use dash H to specify wanna add a header. And a super nice feature here is we get tab completion over the headers. So that's great. So just tab complete to content type. And then even for the media type itself, I can tab complete and say, yeah, this thing accepts JSON data. So let's issue a post. When I issue a post, it pops up whatever editor I have configured and gives me a little JSON sample that I can now use to post a new pet. So let's again, make this pet be mine. Let's call it Fluffy, what kind of type? This would be, let's say it's a tarantula and what age? I hear that surprisingly, tarantulas live a long time. They can live to be over 20 years old. So a 20 year old tarantula and there we go. So now if I do another get, I should have two pets and I do. Let's add one more. And I can just go in up arrow and reissue a post request. What pet should I add here? This pet, my mom actually when she was younger, she owned a pet duck. So this will be my mom's pet. And I think, I believe his name was George. He was a big white duck. And I don't know how old was George, don't know, say five. And so now we have a bunch of pets, okay? So there we, let's do a get. So now we can see all the pets in our API. So that's super nice. That's using the HP Rebel to test and develop once you've enabled a good swagger experience using the API analyzer and the API conventions. All right, so great. Our API looks like it's working. Let's now create a client library that we can use to consume this API. So let's go back to the project. Let's add a new project to the solution. That's gonna be just a normal.NET standard class library. So .NET standard. Let's call it pets client. Looks good. All right, and we can get rid of this class. That's the class one SCS. And what I want it to do here is I wanna create some code that people can use to consume my API. So make it easier for them to consume my API. And I'd like to generate it based on the swagger definition. So what I'm gonna do, let's add a new item to the pets client class library project. It's just gonna be a JSON file. And let's call it pets swagger.json. Okay, so just a normal JSON file. And let me go back to my API and let's go grab the swagger document for it and just copy in here. Great. Okay, now I want to generate code based off of that swagger document. And I like to do it as part of my build. Like every time I build this client library, I'd like to get the client code. And to do that, I'm gonna use a really nice community project called Enswag. So let's manage our NuGet packages. And the package I want, I believe is enswag.msbuild. Enswag is another great community project. There we go. Let's install this. It's open source. It's on GitHub. Here's the project URL. And the nice thing about Enswag is it supports both open API spec generation or swagger generation as well as code generation based on that specification. And it can generate .NET code, C-sharp code. It can generate tight script code. It can even generate the API code if you'd like. Like if you want to have a spec that someone gives you and they say like, please go implement this API. You can do that with Enswag. All right, so I'm gonna wire up Enswag as part of the build of my project. So let's edit the csproj file. I'm gonna, I've already got the target set up here in my snippet manager, also known as notepad. So I'm just gonna copy that in. And so all this does is to find a new target that's gonna happen before build. And it's gonna run the Enswag command line tool to generate some C-sharp client code from the swagger document. And I pointed it at the petswagger.json file, specified the namespace. I specified a couple of additional parameters like I'd like to be able to inject the HB client that it uses. So I've set that to true. And then I've also specified what the output file name should be. Okay, so let's save that. And now if I just build my API client library, hopefully I'll get some client code. Let's see if that works. Builds exceeded and voila, we have a new petsclient.cs file with some generated code that I can use to consume the API. Now that whole experience of acquiring the swagger or open API spec for an API, pointing your build for a library to that document and having it generate client code for you, we wanna make that experience a lot more seamless in 2.2. So in preview three, the next preview, we're actually gonna be providing some MS build infrastructure so that you can just add a package. And then in MS build, say, I would like to generate a client for that project over there, kind of like a project reference. Or I'd like to generate a client for that API over there, like using a URL and have that just work. And we're planning to be working with the existing community projects like Enswag and Autorest so that you can use the code generator of your choice. So that's coming, something to look forward to in preview three. Now it looks like I'm missing newtonsoft.json, so let's go ahead and add that. So our generated code compiles. We should be good. Yeah, okay, great. So now we've got our client library. All right, so now let's build an application with this. Like, I mean, I work on ASP.net, so I'd like to build a web application. I have a .net class library. I don't really feel like writing JavaScript right now. So for our client application, let's create a Blazor application. Now if you're not familiar with Blazor, Blazor is a relatively new experimental project for running .net code in the browser. And it's running the browser via WebAssembly. I've got Blazor, the Blazor extension installed in Visual Studio here, so I'm gonna add a new project to my solution. That's gonna be a Blazor app, so let's call this one Pet's app. It's gonna have some UI. And Blazor apps can run any .net standard library, so they should be able to use our Pet's client. Okay, so the Blazor's not part of 2.2, it's just an experimental project that we've been working on. Okay, so let's create a new Blazor app. I'm gonna add it to my solution. Very cool. All right, and now let's just add a reference from my Blazor app to the client library that I just created previously. Generated from Swagger. All right, now I need to also, there's one workaround I am gonna have to do with the Blazor app currently. This is something that we will be fixing in the future in order to allow it to work with Moonsoft.json. It's just a temporary limitation, but I'm gonna turn off the Blazor linker. This will make the app a little bit larger, but it will make more things work. So we're gonna do that quick workaround. I also need to now host this Blazor application. Blazor applications are purely client-side. They're just a bunch of static files. So you can host them wherever you'd like. I wanna host this particular Blazor app in my ASP.NET Core app in the Pets API project. So to do that, I can just add a helper package for hosting Blazor apps in ASP.NET Core, and that one is blazor.server. Let's go ahead and install that. Okay, and once that's in, we need to add our reference from the hosting app to the Blazor application. Looks good. So let's add another reference to the Pets app from the Pets API project. All right, cool. So now I should be able to go into startup in my ASP.NET Core app and say app.useBlazor, and I'm just gonna point it at the app, the program class from the Blazor application so it knows what to host, and that's all you gotta do. All right, cool. All right, so now we should be able to use the Pets client from our Blazor app. So let's go into the startup class for the Blazor application, and I'm gonna add the Pets client as a service so that I can inject it to any of my pages or components. So I'm gonna say services.singleton, and I want to add the was a Pets client, I think the name of the class is generators.client, and I'm just gonna add that as a singleton service. The reason why this works is because the generated client code takes in its constructor and HB client, and Blazor applications make HB client available as a service as well, and it's already wired up with the right base URL and with the right message handler so that it works in the browser. So when we resolve the Pets client, it should just get the right HB client under the covers by default, which is great. All right, so that should be all we need to do there to make it available as a service, and now let's just add some code. So in my homepage for my Blazor app, I'm gonna write a little code here. Let's do an I enumerable, I'd like to do an I enumerable of Pets. I think I need to add a using statement here, so using Pets client, yeah, so I enumerable of Pets, I guess, yep, so it gets a intelligence there, so let's call this variable Pets, and then when this page loads, let's just go ahead and use the Pets client to grab all the Pets data. So let's do a protected override, and on an async is what we're gonna do, because we're gonna do an async call, so we should make sure we use the async version. So let's make this async, and then in here, let's just acquire all the Pets. Okay, so I need a Pets client now, how do I get that from this page? Well, it's just Razor, so we can use the normal at inject syntax, to which basically we'll create a property on this page of whatever type you want, I want a Pets client client, and let's call the name of the property Pets client. So now I should just be able to refer to this Pets client anywhere in this code, so let's take the Pets variable we created previously, and let's just populate it by doing Pets client, yep, getting IntelliSense dot, and what do we want? So the methods names that were generated by Nswag are based on the URI path segments for the various endpoints. I wanna just do a get, so API Pets get async is the one I want, and I don't have to pass anything because it already knows about the URI space, and that should be it, so now I should have all the Pets, now I just need to render some UI so I can see them. So let's add a little header here, here's my Pets, and let's add a little if clause. So if the Pets are ready, like if it's not null, then let's do an unordered list here, and then for reach, let's go to that, var pet in Pets, yep, getting IntelliSense, great, then what are we gonna do? We wanna do generate a list item, and we'll put the pet name, pet dot name. All right, if the Pets are still null, like we haven't actually successfully loaded them yet, then let's just display a little message that says finding Pets. Okay, and that should be it, do we have everything we need? All right, all the squigglies are gone, well let's run it and see if that works. All right, so we're building the application, and this will build the Blazor app, which refers to the Pets client, it then gets hosted in the ASPnet core application, which also has the web API, all right, so loading in the browser, cool, all right, so our Blazor application starting up, and if we look at the homepage, it says Pets finding Pets, and there they are, so there, so that was an end-to-end experience. So creating an API using scaffolding, adding documentation for that API using Swagger or an open API spec, testing the API using the HP REPL, consuming that API using a client library with code that we generated, and then using that from an application. All right, so to make APIs easier to create, we give you a scaffolding, and the scaffolders in 2.2 have been updated with the latest conventions. To make it easier to test, you can use the HP REPL, to make them easier to debug, we also, like I said, use problem details, responses with trace ID, so you can track them, correlate them with other activities in your system. Document them using Swagger, the API conventions will help you do that, as will the analyzer, so that you enforce those conventions consistently across your API. To consume them, we are going to enable a code generation experience in Preview 3 that's coming. For now, you can use the existing open source projects that are already available in the community. We are also applying to ship an authorization server-based web API security story in the next preview of 2.2, not much to share on that yet, but just want to let you know more is coming. As for monitoring, you can use health checks to make sure that your APIs are live and that they're ready to receive traffic. I'll show more about that in just a bit. And as for performance, all of the new performance-related features in this release, they of course apply to API. You can use HB2, you can use the new endpoint routing system, both which have significantly better performance, and then also IIS in PROC hosting. So now let's go take a look at some of those other new features. So HB2, that's also new in 2.2. It's available cross-platform in Kestrel. It supports ALPN, it supports header compression and also multiplex streams. Now, this is great because it means, HB2 basically means HTTP, but more efficient, like faster, better, better performance. It is a new protocol implementation for us, so there are some limitations that you should be aware of. We don't currently support server push and we don't currently support stream prioritization. Also, because this is a new protocol, similar to, if you remember Kestrel in its early days, we don't currently recommend using HB2 with Kestrel on the edge at this time. You need some more time to harden and to bake. But it is enabled by default in 2.2 when you're using HTTPS, so we encourage you to try it out. Now let me show you what the impact of HTTP, HB2 is. So I have a little test application that I wrote. Let's pull that up. This app is based on the, if you've seen the Golang, Gopher Tiles, HB2 test application, this is a very similar app. It basically is going to try to download a bunch of image tiles from the server as fast as it can to render an image. All right, so let's go. I have two different versions of this app. I have an HTTP11 version of the application using ASPnit Core 2.1. And then I have an HTTP2 version of the application using ASPnit Core 2.2. So let's start with the older one, the 2.1 version. So let's set a startup project and go ahead and get that running and see what that looks like. Now to make the difference a little bit easier to spot, I've added some artificial latency to each of the requests, about 100 milliseconds of latency for each image request. So if things look a little slow, it's not because the pipeline is slow, it's just because that's been, was artificially added. So as you can see with the HTTP11 version, the tiles come down, and they kind of look like they're streaming in slowly. And that's because with HTTP11, you're fundamentally limited by the number of connections that the browser will let you open. All right, let's now put that over here and let's try the 2.2 version. Let's set this as the startup project and go ahead and run that. All right, now let's pull that out side by side. All right, now let's control F5 so we can see what that looks like. So it actually loads really, really fast. How is that possible? Well, this is basically the stream multiplexing in HP2 that's allowing you to get much faster load time. So you can send multiple requests basically over the same connection. So much faster DOM complete time on this one than on the HTTP11 version. And we can refresh this a few times just to make sure we're not slow because it's cold or whatever. Ooh, looks like that one took a little longer. Let's give it a, there we go. So there's a much faster time. So hit a little hiccup on my machine. So hopefully you can see the difference there that you can get some really nice performance out of HP2. Let me stop the servers, all right? So that's HP2 support. And like I said, it's on by default as long as you're over HPS. It does require HPS. Also new, the new IMPROC hosting model for IAS. We had started work on this actually in an earlier release but we are now shipping it with 2.2. Currently, when you're host ASP.NET core applications in IAS, it uses an out of process hosting model. What that means is request comes in to IAS and then it forwards the request to a.NET Exe process where your application actually runs. Now that has some obvious overhead in terms of performance. It also causes some reliability issues. If anything goes wrong with starting up that.NET Exe process or if it crashes for whatever reason, your application then breaks and it's hard to figure out why. With the new in process model, your ASP.NET core app actually runs directly in the IAS worker process which gives you much better performance and much better reliability. If things go wrong, it's easier to figure out why. So that's the main motivation why we're doing this feature. And the performance is looking really, really good in our latest perf tests. Well, these are back in August. We're seeing like four times the performance throughput for like a benchmark where we're just turning adjacent payload using both the in process model and the out of process model. So looking great there. To see it in action is pretty easy. For this one, you really do need the latest version of Visual Studio, 15.9 preview two. So let's go back to VS and let's go back to the project that we created at the beginning of the session. This was just a normal razor pages application. And what we're gonna do is we're gonna go into the home page and we're just gonna print out the name of the current process. So let's add a header element here and say system.diagnostics process. Let's get the current process and print out the name. Nope, not the machine name. The process name. All right, great. So now, if we look at the CS Proj for this project, our templates now do specify in the CS Proj file that it should use the in process hosting model for ASMIC Core when running on IAS. So by default, all the new 2.2 products will have this. If we run this in Visual Studio, it seems currently that Visual Studio by default will ignore that. But let's see. Fortunately, we can use VS to change it. Yeah, so currently it's saying it's actually running out of process in the .NET Exe process. Okay, let's see if we can fix that because I want that perf, I want the better reliability. So if we go to our project properties and go to debug, at the bottom, you can see there's a new setting now for setting the hosting model. Currently it's specified as default. We can change that to say to be in process. So if we save this and then go back to the application and run the application. You can see now we are literally running directly in the IAS Express worker process, which is great. Better perf, better reliability, a lot easier to diagnose problems. All right, next let's talk about health checks. So new in ASP.NET Core 2.2, we've added support for health checks. You can add dedicated health endpoints to your application so that container orchestrators and load balancers can figure out if your apps or services are alive and ready to receive traffic. It supports health checks for both liveness, like is the app even running, and also health checks for readiness probes, like is the traffic running, but not quite ready yet to receive traffic. You can do both with the health check system. So let's take a look at that. All right, so I've got a little application here. Close one of these. All right, a little application that uses health checks. So ASP.NET Core health checks 2.2. And the health checks APIs are already included with the ASP.NET Core shared framework in 2.2. So like if we go looking through our dependencies, we can just search here actually for like health. And we can see that there's the ASP.NET Core diagnostics health checks package that's showing up in my dependency graph. So it's already there, you can just use it. Don't need to add anything, at least when you're running on .NET Core. And then to use health checks, first you add the health check services and then any checks that you want to do. So in this application, what I'm doing is I have a health check that says, this app is only healthy if a particular required configuration value is there. If it's not there, the app isn't healthy. And this is intended to mimic a case like, for example, where you want to have a health check that checks to see is my connection to the database good? Like is it set up and ready to go? You would do something very similar to that here. But to keep it simple, we're just going to check a config value and see if it's there or not. And then to add the health check endpoint down below in our request handling pipeline, we just say use health checks and specify the path where we'd like the endpoint to be. Okay, so now, let's see. I have already gone and deployed this application to Azure as an Azure App Service. I've actually deployed it into two separate Azure App Services. I have one that's running in, they're running in two different regions. One's running in central US and the other one is running in Western Europe. And both of these have health checks enabled. It's just literally the same application. So if I do slash health, where is this guy healthy? Oh, currently it's unhealthy. That probably means it's got, let's go fix that real quick. So that probably means the required config value is not there. Yep, so someone didn't deploy it correctly. And let's save that. Okay, that should now be updated. And if we wait for this to refresh, hopefully after the app has a chance to recycle, I should now say that it's healthy. Give me a second for our app service to restart the app. Okay, so health. Okay, yeah, so now it's healthy again. That's good. So we got one healthy app and then the one in Western Europe also has a health endpoint. We can click browse to that one and see that one's healthy too. Okay, good. And I've also set up Traffic Manager in Azure to route requests to those two different applications using the performance routing method. So what does that mean? Well, the performance routing method means that it will pick which app will give you the best experience based on like what's, what will give you the best latency. So it'll generally pick the one that's closest to you. Since I'm in the United States, it should generally give me the U.S. version of the application. Let's see if that's the case. So here's the Traffic Manager URI. This is a DNS based load balancing system. And if I rerun this one. Yeah, so it's routing me to Central U.S. So that looks good. But what if Central U.S. isn't working correctly? Like I said, I deploy the application to Central U.S. And that app is no longer healthy. So let's go back to the app and make it unhealthy again. So I'm gonna take that required config and imagine someone did it wrong and deployed a bad configuration for this app. Let's save. I should probably show how I configured this in Traffic Manager. So here's the two endpoints that I set up. And then if you look at the Traffic Manager configuration in the endpoint monitoring settings section, you can see that I've specified the path for the health check endpoints to be slash health. And then configured some values for like, how many times should that health endpoint remain unhealthy before it actually does a fall over logic? Okay, so hopefully, let's see if the, yes, okay, so now the U.S. app is not working correctly because it's not configured correctly. And if I try and hit this in Traffic Manager, let's see if Traffic Manager is actually updated to say that it's unhealthy. Yeah, so now it's saying that the U.S. endpoint is degraded, do you see that? And if I go grab, normally it gets cached a little bit so I find that it helps if I go to an in private window, go back to Traffic Manager, and now instead of bouncing me to the U.S., it's bouncing me to Western Europe. So that's health checks. You can use them to make your apps more reliable and easier to monitor. All right, endpoint routings next. So we are implementing a completely new routing system for ASP.NET Core 2.2 that we call endpoint routing. It is on by default in a 2.2 application as long as you've set the compatibility mode to be 2.2, which means it even replaces the existing routing system. And the nice thing about this new system is it has much better performance. It has about a 10 to 15% throughput, perf improvement, and it's also much more scalable. We've been testing this routing system using actually the open API spec for like all of Azure, like all of Azure's management plane, but you know, thousands of endpoints and it scales great, even to that many of endpoints. It's also really nice because it moves the routing concerns lower in the stack so that you can use them in more places, including outside of NBC. So for example, if you wanna generate a link from middleware to some endpoint, you can do that with the new endpoint routing system. It also includes a bunch of other minor improvements. It has a feature called parameter transformers, which lets you transform route values, like if you wanted your action names to be snake case, you can do that. We also added a new catchall syntax with two stars, star star, which will encode everything that gets captured except for the slashes so that you can more easily round trip your iPads that contain slashes. So new endpoint routing system, it's kind of laying the foundations right now for even additional work that we wanna do in the routing space. So you should expect to see even more improvements coming in future previews and future releases. All right, the last thing I wanna show you is the new ASP.NET Core Java client. We have a new Java client library that you can use to connect to ASP.NET Core SignalR hubs. It's available for Gradle and also for Maven, and it is starting in preview two and now also supports the Azure SignalR service. So if you wanna write an Android application that's written in Java using SignalR to add real-time capabilities and you want it to scale, you can use the Azure SignalR service to do that. We have a really nice Android sample using the Java client that you can take a look at and I'll show you that next. Okay, so I have Android Studio installed here with the SignalR Android sample already wired up. If we look at the build.gradle file, you can see here's the, there's the, let me highlight it again so you can actually see it, there's the SignalR library being added as a dependency. So column.microsoft.asp.net, colo and SignalR. This is the preview one version, we need update that to preview two but the code is basically the same. If we look at the main activity.java, you can see that it just looks like the normal SignalR client. You create a hub connection to a hub. Here I have a hub that's hosted on Azure and then down below it's listening, has a callback for receiving send events from the hub. So when someone sends like a chat message, it can then update the UI and then down below if the user clicks a button and sends its own message, it uses the hub connection to send that message to all the other connected clients. All right, so let's try it out. So I've got the Android emulator up here and running. Let's go ahead and fire up the application. And in parallel, let's go ahead and let's browse to the web version of the client. So I think that's that SignalR samples, hubs.html, great. So this is just a little web client that talks to the same hub and I'm gonna connect from the web client and you can see in the Android version it's recognized that another user has joined. And so from the Android app using the Java client we can say like hello.netster and send that and down below. So we got that message in real time in the web app and then from the web app we can say hi, Mr. Android. And broadcast that and we get the message from the Android client as well. So that's the new Java client and like I said it supports the Azure SignalR service and give it a try. All right, so those are the new features available with 2.2. Hope you enjoyed learning about them. What is the roadmap for the 2.2 release? Well we shipped preview two in September, shipped today. We expect to ship preview three about a month from now in October and then we hope to ship an RTW, a stable release of ASP.net Core 2.2 by year end of 2018. And I hope you enjoyed what you saw and that you'll take the time to go install the latest.net core SDK, 2.2 preview two and try out these new features. And it looks like we have a few minutes so I will do my best to try and answer a few questions. All right, so any plans to provide updated templates for Vue.js? If not, how easy is it for the community to create these templates? So we currently have templates for Angular, for React and React plus Redux. We have actually done Vue templates in the past. You know, these JavaScript frameworks that move very quickly, there's quite a bit of maintenance cost in keeping those templates up to date. So we've scaled back actually to just supporting Angular and React, at least for the ones in the box. In the future we actually plan to take even those templates and move them to be just shipped as template packages, as NuGet packages, instead of having them actually in the SDK. So we have the ability to be more agile and update them as client libraries version. We don't currently have plans to add a support for Vue or Aurelia or any of the other frameworks. If the community would like to build these templates, you absolutely can. Anyone can actually create a template pack as a NuGet package, ship it to NuGet.org and then you can install them by doing .NET Nu-I and just point at the package ID for the package. So if the community would like to maintain a Vue version, that would be totally great and people should absolutely do that. I'm sure the code for the version of the Vue template that we used to have is still kicking around. That would probably be a good starting point. Next question to you, can we experiment with .NET Core 2.2 in Visual Studio Code? Yes, absolutely you can. The main reason why we recommend using the latest preview version of Visual Studio is because there are features that light up with that preview release. Like for example, being able to use the new improv hosting model when you're building and debugging your applications, that support was added in the latest preview version of Visual Studio. Also, the scaffolding support so that you can scaffold both Bootstrap 3 or Bootstrap 4 versions of UI for AcePenet Core that was added in the latest preview release of Visual Studio. But you can still do development with any editor that you'd like. If you like Visual Studio Code, absolutely. You can .NET build, .NET run, .NET publish all those things, get IntelliSense, the runtime features and the framework features will of course continue to still work. So next question was about Swagger and the HP Rebel, that they seem to have overlapping concerns. Do we really need both? I think the answer there is absolutely yes. Like depending on how you like to work, some people like to have a GUI UI. They like to be able to point and click and see pixels on the screen when they're doing the development flow. Other people really like the productivity of a command line interface that's scriptable, that you can just up arrow and repeat interactions. The Swagger UI is also very generic. Like it's based on whatever you can learn from Swagger. With the HP Rebel, we think there's also opportunities for us to do things that are more .NET specific, to add value specific to .NET scenarios. For example, in the past we've looked at like exposing log information directly from the HP Rebel when you get like a 500 response from the server. We could do that for a .NET application. We can't necessarily do that generically from the Swagger UI. So that's why we think there's value, but it's early in that tool's life. So let us know what you think. Next question is, are there any options for managing secrets like connection strings, with passwords, etc., other than Key Vault? Well, I would certainly absolutely recommend using Key Vault for whatever secrets you're trying to manage. Key Vault has a great set of security features for making sure your secrets don't end up going where you don't want them to go and helping you manage that. So Key Vault is great. If you're not interested in using Key Vault for development scenarios, you can certainly use the User Secrets feature that we have in ASP.NET Core to make sure that you don't accidentally check secrets into your source code. It's not really like an encrypted secret store, it's just a way to have a layer of indirection so you don't accidentally put things like passwords or connections strings directly in code that end up on GitHub. If you're running on Azure App Service, you can use things like environment variables for storing secrets. Those are sandbox so that they only stay within that environment. But still, I would highly recommend using something like Key Vault if you have very sensitive data. That's pretty much it. We're getting to the end of time. Thank you everyone for watching this session. If you have additional questions or feedback about these features, please let us know by filing issues on GitHub.