 Hello, everyone. Welcome. My name is Daniel Roth. I'm a program manager on the ASP.NET team. In this session, we're going to talk about modern web app development with Blazor. It is a great time to be a software developer. No matter what type of application you're trying to build, you have loads of frameworks, libraries, tools, languages, runtimes to choose from for building your application. This is also true when building browser-based web applications. There are loads of libraries and frameworks and languages to use. Well, as long as that language is JavaScript. Unfortunately, JavaScript is the only thing you have available to you in the browser. You can compile to it, but it's the language you pretty much have to use. There really hasn't been any way to address this in the browser for a long period of time until recently. There is now a new open web standard called WebAssembly. That is a byte code for the web. WebAssembly is intended to be used as a compilation target. The idea is that you can take any code written in any language, and as long as you can compile it to WebAssembly, you can then run that code in any browser at native speeds. WebAssembly is fast and is available anywhere in any modern browser. Of course, we would like to make it possible so that you can take your .NET code and target it to WebAssembly, so you can run your .NET code in any browser. Now, why would you want to do this? Why would you want to run .NET in the browser? Why wouldn't you just continue to write JavaScript? Well, we think there are a number of advantages for using .NET for full stack web development. One is that .NET is stable, mature, and productive. It has a standardized set of APIs that are mature, they're not changing, it has a standardized build system so that you have a solid foundation to build on. .NET is also fast, scalable, and reliable. You can use .NET Core for your back-end services and get phenomenal performance. .NET also has modern innovative languages. C-Sharp, F-Sharp, and Razor are getting a constant stream of new and innovative features. Of course, the tooling in .NET has always been first-rate. You have Visual Studio, IntelliSense, and great debugging. Now, if you're a .NET developer, of course, you already know these things because you use .NET every day. But what this means is that by having .NET running in the browser, you can now leverage your existing skills and expertise. So we've been working on an experimental project to bring .NET to the browser so you can do full stack web development. We call this project Blazer. What is Blazer? Blazer is full stack web development for .NET via WebAssembly. It requires no plugins and there's no code transpilation. All you need is a browser. You don't need to install anything into it. We're not taking your .NET code and translating into JavaScript. You literally are running normal .NET standard libraries in the browser. It works on all modern browsers including desktop browsers and mobile. Where does the name come from? Well, browser plus Razor equals Blazer. Razor is the HTML and C-sharp templating engine that we use for Blazer component authoring in the Blazer framework. Where does the L come from? We don't know. Laser beams, blockchain, it just sounds better. So how can this possibly work? Well, the way Blazer works is first, the first piece you need is a WebAssembly based .NET runtime. For that, we're using Mono. Mono is the Microsoft supported cross-platform .NET runtime that we use for client application development for Android, iOS, Mac OS, watches. You can pretty much run Mono anywhere, which makes it a great fit for Blazer applications. So we have a WebAssembly implementation of a .NET runtime. We then take your .NET code and your Razor files. We compile them into normal .NET assemblies and download them into the browser along with all their dependencies and along with the WebAssembly .NET runtime. Then we take the WebAssembly, have a little bit of JavaScript that bootstraps it, executes it, points it at your .NET assemblies and says, run these. That's how you can get .NET running in the browser. So how can you get started with this? Well, first you're going to want to go to Blazer.NET, and then you're going to need the .NET Core SDK. So make sure you have that installed. If you're just operating on the command line, you can install the Blazer templates using the .NET Core SDK, just .NET new dash i and type in the name of the Blazer template pack. That will work then on Windows Mac and Linux. You can do cross-platform Blazer development. If you happen to be on Windows in Visual Studio, then you can install our Blazer Visual Studio extension, the Blazer Language Services, and that will give you the Blazer templates in Visual Studio along with the great tooling and editing experience. So let's go take a look at doing that. All right. So first to get started with Blazer, you're going to want to go to Blazer.NET, and that'll bring you to this website, click on Get Started, and it has all the instructions that I just went through with you on what you need to install to get Blazer open running. You need a .NET Core SDK. If you're using VS, install the Blazer Language Service extension. If you're on the command line, down below are the instructions for installing the Blazer templates on the command line, then you're ready to go to create your first Blazer app. All right. So I'm going to go ahead and do that. Let's go into Visual Studio. I've already installed the Blazer extension. You can see that in my extensions and updates. If we search for Blazer here, there it is installed. If you want to install the extension, you can just search for it here and you'll find it online. All right. So now let's create a new Blazer app. So file new project, let's call this Blazer app one. I'm going to create a web application. You create it through the ASP-NET Core web app dialog, and then I'm just going to create a default normal Blazer application. There are these other two templates and we'll talk a little bit more about those later. All right. So let's create one. All right. Cool. Now to see what this app does, I'm just going to go ahead and build and run it. Of course, we should let the NuGet packages restore first. Try it again. There it goes. This should bring me up my first.NET in the browser web application. All right. So let's see what we got here. So this application is using Bootstrap 4.4 styling and it just has a couple of tabs on the left-hand side. There's a homepage with just some content. There's a little link to a survey. If you'd like to give us some feedback on Blazer, we'd love to hear from you. Then there's this counter page which just has a button and you click the button and it increments a counter. Then on the fetch data page, there's a table rendered with some weather forecast data that's being fetched from the server. So this counter page, every time I click this button, it is actually executing.NET code. It's executing C-sharp to update the UI. There's no page refresh happening to go back to the server. So what does that look like to implement? If we go back to the application, look at the pages and you can see that the MyBlazer application is entirely made up of C-sharp and razor files. Each of the razor files defines a Blazer component. Let's look at the counter component and see what it's got. Well, up at the top, you see that this is a component that has a route. It is a routable component to browse to this route, I browse to slash counter. Then there's some normal markup and some razor syntax. It's rendering a label that's displaying the curtain count using razor syntax, and then a button that has an on-click handler that happens and every time the button is clicked. But this isn't a JavaScript click handler, this is written in C-sharp. So down below in this functions block, the functions block adds a bunch of members and methods to the generated class that comes out of this razor file as part of the build. A Blazer component is just a normal .NET class. So this method gets added to the class when it's built, and you can see we just have an increment count method that increments the current count int field. That's it. So every time I'm clicking this button, I'm actually calling that function. Now, so these are components. You can define components using razor files, and then when you want to use them, you use them using normal HTML element like syntax. So let's go look at the index page, the home page for this application. That was this page here. Currently it just has some static markup and then this survey link. If we look at how that was implemented, it's just static HTML. Again, it's a routable component, it has a route. But then there's this survey prompt component that's being used to render this little part of the page. So we're asking you to click on the survey link. So there's an example of a component. You just use it using normal element syntax. So for example, if I wanted to use the counter component, well the name of the element just matches the name of the type that gets generated from the razor file. So I should be able to add a counter component here by just typing counter, and there it is. You can see you get nice IntelliSense over your components. All right, so let's go ahead and complete that. And this should give me, actually I like the self-closing syntax. There we go. This should give me a counter component, a separate one rendered on the homepage. Let's refresh the application and see if that works. And there it is, yeah. So now we've got another counter component right on the homepage in addition to the one that's routable, the one that's off of the tab. All right, cool. So you can reuse components using normal HTML element-like syntax. Components can also take parameters. They can take data that they can use as part of their rendering logic. Like for example, this survey prompt component actually takes a parameter, this title parameter. We can do the same thing with our counter component. Let's update it to take a parameter as well. So I'm gonna go into counter, and I'm gonna add a parameter. We have a nice little snippet in VS that you can use, just type P-A-R-A for short for parameter, and tab that in, and there we go. So our parameter is just a property that is attributed with a parameter. And so I want, yeah, I want an int parameter, and I'm gonna call this one increment amount. And this is gonna be the amount that I would like to increment every single time I click the button. So by default, let's just make that one. That should be good. And then down below, let's use our parameter. Let's increment now by increment amount using normal C-sharp syntax. Okay, that looks good. Now, if I go back to the home page to where I had this counter component, let's set the parameter. So if I start typing increment, aha. So I get nice IntelliSense over my new parameter that I'd added to the component. So let's go ahead and add that, and let's make the home page counter increment by 10. So we go back, let's refresh, and we should see the counter component. And now when I click it, it increments by 10. Sweet. The other one should still continue to increment by one because I didn't set the increment amount parameter on that component. Great, so that's working great. All right, now let's take a look at this fetch data component. So this component is actually issuing an HTTP request to the backend to pull down some JSON data, deserializing that in the browser in order to then render this table using razor logic. Let me show you what that implementation looks like. So here's fetch data. Okay, at the top, again, we have a route. This is a routable component. And then what's this at inject thing? Well, at inject is the razor syntax that you use to inject services into razor, or in this case, a blazer component. The way the syntax works is the first token is basically the type of the service that you'd like to inject. And the second token is the name of the property, really, that you'd like to populate with that particular service. So here I'm actually injecting an HTTP client into the fetch data component. Blazer provides an HTTP client as a service as part of the runtime. And it's already preconfigured with the right base address to talk back to the hosting server. All right, cool. So I should now be able to use this HTTP property in the code. If we look down now at the rest of the fetch data component, there's a bunch of razor logic for just rendering out a table. That looks normal. Let's jump down here to the code. And if we look at the code, we have a method that will be called when the component is initialized. When the component is initialized, we use that HTTP client to issue a get request to the server. In this case, the JSON data is just a static file. Like we can see it actually in the www root folder under the sample data folder. There it is. So there's just the static JSON data in this case. We can improve on that in just a bit. But it retrieves that JSON data, deserializes it using a little JSON helper into a weather forecast array, which is then saved as a field on the component. The weather forecast type is inlined here in the component just for convenience. And then up above, we're just looping over that array using normal razor syntax to render out the table data. So that's how you can issue HTTP requests also from your component and also use dependency injection to inject services. When you configure your services, like where does that actually go? Well, Blazor apps have a startup class, kind of like ASP.NET Core apps. But remember, Blazor apps are running client side in the browser. They're not a server application. So my startup class has the standard two methods, configure services. That's where you would add any services that you want to add. Blazor adds the HB client automatically for you. In the configure method, this is where we're actually setting up the root component for our application. In this case, my root component is the app component. Where is that defined? Well, that's over here in app.cshtml. And if we look at that guy, all it has is a single component in it, which is a built-in component that's provided by Blazor called the router component. And the router component is what actually handles finding all of the routable components in your application and making sure that requests go to the right component to render. That's all it really does. Now, if we look back at that startup class once more, there's also an element selector that's saying, where do we want this Blazor component to actually be rendered? That the root of the Blazor app is actually just a static HTML file. If we go up again to our www root folder and go to the index.html file, this is just static HTML. But here you can see there's that app element that we're telling Blazor, replace that app element with the app component, with the rendered output of the app component. You can also see here the script tag that's setting up the bootstrapping JavaScript that will fire up the WebAssembly.net runtime and point it at your app. So that's where all of the Blazor stuff gets wired up. OK, so then what actually gets downloaded by this application? Let's f12 in the browser and take a look at the network traffic. All right, cool. So let's see, we have at the top, we have that static index HTML file, the rendered HTML. And then we have bootstrap styling and stuff that's being pulled down because this app uses a bootstrap. And then, oh, here's the different kind of bootstrapping. The JavaScript that Blazor uses to fire up the .net runtime. Now, where is the actual .net runtime? A little further down, and that is this guy here, monodotwasm. .wasm is the extension used for WebAssembly files that are executed in the browser. That is a full .net runtime implemented in WebAssembly. And then you can see right below it, there's my application, blazorapp1.dll, a normal DLL being downloaded into the browser, along with all of its dependencies that is then being executed using that .net runtime. So that's pretty cool. Now, how big is this application? If we go all the way to the bottom and look at the size, it is 1.8 megabytes compressed. So that's pretty small for having a full .net runtime. For a web app, it's admittedly a little bit big. Now, some folks might say, oh, but we could mitigate this using HTTP caching. We could cache the WebAssembly file and a lot of the .net base class library assemblies. And that's absolutely true. But we still think we can do better. We think we can get this size down even smaller. We're already doing what we call IL linking, where we go through the DLLs that are produced from your blazor application. And then we strip out all of the unused IL as best we can right now, some work that still needs to be done to make that even smarter. And we think we can do that. Like, we could probably strip out more code, reduce the size of the WebAssembly runtime itself. And we hope to get this down under a mag is where we'd like to shoot for. ASP.NET Core 2.2 also has support for a broadly compression. So that would help reduce this size even more. All right, great. So that's how the blazor app actually runs and gets executed. All right, cool. So what about debugging though? So you have this .NET runtime running in the browser, but how do you debug your code? I mean, you can't just use the normal Chrome DevTools for example, or whatever DevTools you like, because you're not running JavaScript. So how do you do that? Well, we do actually have some early work that we've done on enabling debugging for blazor applications directly in the browser. And I'll show you how that works. So first of all, if you go look at the console of the in the browser, you'll see that it advertises this hotkey for doing debugging of your blazor application, Shift Alt D. So let's give that a try and see if that works for us. Okay, so this opens up another tab. And what it's gonna try to do is it's try, well, it obviously didn't work, so let's find out why, or understand why. This separate tab is actually gonna try and take the Chrome DevTools and point it at a blazor debugging server, which then is pointed at the actual application that you want to debug. That debugging server will talk to the browser using the standard debugging protocol for that would normally be used for JavaScript, but augmented with .NET specific information. Now in order to enable that hop, you actually have to open Chrome in remote debugging mode. So that's what this error is telling me to do. So I'm just gonna copy the command that it's telling me to execute. I'm gonna close all the browser instances and let's run Chrome now with remote debugging enabled. Let's get it up and run it. Okay, let's do Shift Alt D again. And hopefully this time, we should have some luck. Okay, so I got the Chrome debugging tools up. Let's put them over to the side. Oh no, so I got this reconnect bug again. That's gonna work. Okay, hold on a second. Hold on a second, let's see if we can fix this. Now the bugging support for this setup is admittedly pretty flaky right now. Like right now it's mostly proof of concept to show that it can be made to work, but there'll be edges. Let me see if I can just get this to clear out by going into the local storage and clearing out some stuff. So whether the local storage, everything there, okay, local storage dot, see if we can, was it clear? Yeah, clear. Okay, great. So then let's try it one more time. I'm gonna try it once more. Let's see if we can get this to work. All right, let's put it over here and let's put the app over here. All right, and now we want to, let's see if we can see our sources. All right, cool. So now, do you see over here in the sources, I can now see blazorapp1.dll. Whoa, what is that? And if I expand that, I can now see all of the razor files for my application. So I'm gonna, let's look at counter and yep, I can see the C-sharp code, the razor code for the counter. I'm gonna set a breakpoint on the counter component. Let's click it and voila. We hit breakpoint debugging in the browser of .NET code. Now this is really, really early like you've already seen. There's lots of edge cases. We still need to do a whole bunch of work to enable, be able to see locals and make the stepping really work well. But at least we have a proof of concept to show that this is absolutely possible. In the future, we wanna make it so that you can just F5 in Visual Studio and have this already set up so you can already go ahead and debug without having to do any additional jumps. We'd even like to make it so that you can do script source debugging of your C-sharp code directly from VS while the app is running in the browser. And we think we believe that is possible as well. So that's a early look at proof of concept debugging. All right, let's close this down. All right, cool. What about publishing? When you publish this application, what you end up with is just a bunch of static files. Remember, this is a completely client-side solution. Those static files can then be hosted on any server that supports static file hosting. That could be hosted as an Azure static site. You could host it on GitHub pages. I believe we even have a Blazor app that's already set up that way. BlazorDemo.github.io. This is an slightly earlier version of Blazor. I think it's still in Bootstrap 3. But this is a Blazor app hosted just as static files on GitHub pages. So you can host it wherever you want. You don't need to have .NET on the server. But if you do have .NET on server, we can enable a lot more experiences. So just like you can host Blazor anywhere, you could also host it in an ASP.NET Core web application. So let's take a look at what that looks like. So let's do File New Project now. Let's leave this simple app. So let's call this one Hosted Blazor app. Then instead of picking the default Blazor template, now let's now pick this Blazor ASP.NET Core hosted template so that we can host our Blazor app in ASP.NET Core and use .NET now on both sides of the wire. All right, cool. So what do we got here? So now we have a solution with three projects. So let's take a look at what these are. So there's a client project, a server project, and a shared project. So the client project is just a normal Blazor app like we just saw a few minutes ago. That's going to have our Blazor components, that's going to have all the normal Blazor stuff. The .server project, that is an ASP.NET Core project, and we're going to use it to host the output of our Blazor client project. .shared is just a normal .NET standard class library, and it's referenced by both the Blazor client and the server so that we can have code that is shared on both sides of the wire. So let's take a look at what that looks like. So the Blazor client looks just like it did before. In fact, let's run this app so we can see that it's functionally the same. While that's going on the building, we'll expand here, we see we have our counter component, our fetch data component, all the normal stuff. Let's let it go ahead and run. Cool. All right. Here it's loading. Okay. So we have our counter, we have our fetch data component as well. Now in this case though, fetch data instead of going and just pulling down a static file, it's actually calling an API that's hosted in our ASP.NET Core application, in the .server application. So let's see that there. So in .server now, we can see we have a controllers folder and it actually has an API controller that's just returning some random weather forecast data that's at least dynamic. All right. So that's nice. Now how do you set this up so that you host Blazor in ASP.NET Core? Well, it's pretty easy. First thing you need to do is you just have a project reference. So the server project references the Blazor client project that it wants to host. So you set up a normal project reference. Then second, in your startup class for the server side in ASP.NET Core, you add a piece of middleware, this use Blazor call. Then you point at a type for the Blazor app that you want to host. Now this will set up your application, so we'll work both during development. It will also work when you publish the server application. It will build the Blazor app, collect all the stuff that it needs in order to run, and then make that available to the server application so that it can be served up as static files. So that's nice. Now the .NET standard class library, it has code now that's shared between both projects. If we look in there, we see we have this weather forecast type. That's the same weather forecast type we saw before that was sort of inlined in the fetch data component. Now it's in a .NET standard class library so it can be shared. If we look back at the controller, we can see that the controller is returning that weather forecast type, the same one and then on the client when it does the fetch call using the HP client. Now this type is no longer defined in line, it's just being reused from that .NET standard class library. Blazor supports running pretty much any .NET standard class library that's out there with some limitations based on the limitations of the browser. So like there's obviously things that you can't do from a browser that .NET standard library might try to do. Like you can't go off and just randomly touch the file system. In those cases Blazor will throw a not supported exception to let you know that you're doing something that's not going to work in the browser. All right, great. So that's a full stack now, .NET web development with Blazor. Now it's interesting to look at this fetch data component because I kind of glossed over something earlier. There's this HP client that's being injected to make the HP call to the server. But wait a minute, how does that work? Like this is a managed .NET type, how does it actually do a network call to the server? Well, the way that works is through JavaScript interop. Web assembly code can call into any JavaScript function through JavaScript interop, and we surface that capability in Blazor. In fact, that's actually how Blazor fundamentally works. When you have your Blazor components, and the Blazor runtime executes their rendering logic, the components actually render into a rendering tree, an in-memory representation of the browser DOM. Then Blazor keeps track of what was previously rendered and what was newly rendered and does a diff. Then it goes, once it's calculated that diff, it then applies that diff to the actual browser DOM using JavaScript interop. That's how it actually makes those calls. That's how it's able to do DOM manipulation. You can't actually manipulate the DOM directly from WebAssembly code but you can absolutely do it through JavaScript interop. This HB client in code is working in a very similar way. Remember, this HB client comes as a service in a Blazor application and under the covers, we've actually swapped out the underlying message handler that it's using to add some JavaScript interop code so that it uses the browser fetch API to actually make the network call. So that's how that's working. That's JavaScript interop in action. Now, you can use JavaScript interop yourself as well. For example, you might want to do this to call arbitrary browser APIs. Maybe you want to access local storage, maybe you want to use the Canvas API, maybe you'd like to use the Payment API. There's lots of native capability of the browser that you'd like to be able to use. You can use JavaScript interop to do that. You might also have existing JavaScript libraries that you'd like to continue to leverage. You can use JavaScript interop to call those libraries from .NET code. We can look at how to do that. In fact, we have a template that we provide you, a Blazor class library template, that you can add JavaScript interop code too, and then you can build it and package it up as a NuGet package and share it with other people. Effectively shrink wrapping a JavaScript call in a .NET library that people can then use to call that JavaScript as if it were just normal.NET. So let's see how we do that. So unfortunately, the template isn't actually exposed from within Visual Studio, but we can use it from the command line. So I'm going to jump to the command line here. Let's just go into command prompt. All right. Then let's do .NET Nu to see all the templates that I have installed currently. Let's expand to make it a little bigger. You can see that I have a Blazor host in a net Blazor library template. I have all the Blazor templates that are available here from the .NET Core SDK. Now, these don't get installed with the Visual Studio extension. You do need to install these separately. The way you do that is you just say .NET Nu-I and then you put the package ID for the Blazor template pack, which is ASP.NET Core.Blazor.Templates. That will give you these templates available from the command line, including this nice Blazor library template, Blazor Lib. So let's create one of those. So I'm going to do .NET Nu, Blazor Lib, and let's put it in, I don't know, Blazor Lib 1, it's probably okay. All right, great. So now we've created the project, we can jump back to Visual Studio now. So let's add that project to our solution. All right, let's do, let's go to my actual code. This is hosted Blazor App 1, and there's Blazor Lib 1. There it is. Let's add that one. All right, cool. So what is in this Blazor class library? Well, first of all, it has this example JavaScript interop class, which shows you how to do C sharp to .NET interop. So what it is, it's just a static class that has, in this case, it's a prompt method, and here it's going to call into the JavaScript prompt function. The way you do that is you get a handle first on the JavaScript runtime using jsRentime.current. Then you can call invokeAsync, and you pass in a path to the JavaScript function that you want to call. This path is relative to the window object. You can then pass in any .NET, any parameters that you want to use for calling that JavaScript function, and the introp API will take care of marshalling those parameters over to the JavaScript side. You can then specify the return type of what you'd like back. In this case, you just get the string back from the result of the prompt. So this has a little bit of JavaScript that goes along with it. Let's see where that is in the content. Yes, so example.js introp.js. Great. So here's just a little bit of JavaScript. We've set up an example.js function with the show prompt function, and all it does is call prompt, and you can type in a prompt and then it returns a string. So now we have a .NET API that we can use to call the prompt prompt function that we can use from anywhere. In fact, the Blazor class library template will take care of bundling up all of the static assets that are used by the library and embed them as embedded resources into the library so that you can then reference that library very conveniently. Okay, so let's reference it. So let's go to my client and let's add a reference to the BlazorLib library. There we go. All right, and now let's add some code. Let's call the prompt function. So let's see the homepage looks like a good place, and what do we want to do in here? Let's add a button and let's call it prompt, and let's add a handler on here on click. Then in here, I'd like to call a .NET method that will use JavaScript Interop to call prompt. So let's add a functions block. Okay, and then now JavaScript functions there are async. I hope you saw that it was task of string that it returned. So we need an async function. So let's do async task and let's do, let's just call this method prompt as well. Prompt, and then okay, so now we probably need a using statement for BlazorLib. BlazorLib1, is that there? Yeah, completed, and now we should be able to call it. So example, JSInterop, perfect, and let's call the prompt function. So this is that static function, that static method that we'll call the JavaScript function. What is this? Let's take some methods. So hello from .NET, and let's await this and get it back. So let's actually have a little message here. Let's do a string message, and let's populate that message with the results from calling the prompt function. Okay, great, and so now let's do at prompt, should give me the method. Yeah, okay, so I got intelligence there from completing my .NET method name, and let's render out the message that we also got back. So I don't know, through paragraph and message. Okay, cool. So let's go back to the app, home page and let's refresh. We should have a button now that says prompt, everything builds correctly. There it is. Okay, if I click prompt, well, we just called into JavaScript says, hello from .NET calling the JavaScript, and here we'll say hello from JavaScript back to .NET returns the string and it renders it to the screen. So that's how you can call any JavaScript function you want from a Blazor app, and likewise from JavaScript, you can call back into .NET. There's a pattern for doing that as well, for like doing event handling and those types of things. Now, the only thing better than doing a JavaScript introp though, is having someone else do JavaScript introp for you. So there are all sorts of people in the Blazor community that have been already building Blazor class libraries, that shrink-wrap existing JavaScript APIs with .NET APIs, so you can just use them. So for example, if I go back to the counter page, right now if I count up to 11, and then I refresh the browser, it'd be nice if that actually stayed at 11, but it doesn't because it's just held in memory, it's not actually stored anywhere. Now, if you do a lot of browser development, you would think, oh, well, I can solve that. I can just store the current count in local storage, and I could use some JavaScript to do that. But wouldn't it be nice if I could do that in .NET? So we're going to do that, and we're going to do that using a community package. On the Blazor.NET site, if we go to slash, actually let's just go to there, and then we'll click on community. There are all sorts of libraries that folks in the community have been building that give you a bunch of pre-built Blazor components, and JavaScript introp libraries that you can use, as well as a whole bunch of sample apps that if you want to take a look at those. So let's use one of these. I'm going to use the Blazor extension storage library. So let's do it in my app. Let's add to my client app a new package. Now let's use these Blazor extensions. I think there's a whole bunch of them. Yeah, there's a whole bunch of them here. You can do logging, storage, there's a SignalR client, there's one for the Canvas API, and this is just from one org. There are a bunch of other ones as well. I'm going to grab this storage library. This will handle both session storage and local storage, and let's just install that into my Blazor client. Apparently, we encountered the yes, lint parsing error someplace. Does that work? I hope that worked. I'm not sure what happened there. All right, let's see if we can still use it. Okay. Now to use this, but I've read the docs for this library, and the way you use it, you need to actually add it to your services. Let's do services.addStorage, I think is what it is. Yeah. There's the namespace Blazor extension storage. That's the service I just added. So it did something. So hopefully that this all worked just fine. Now let's see if we can use the storage API from the counter page. So what are we going to do here? Well, first of all, by adding the local storage support as a service, I now can inject support for local storage here. Let's add a using statement just to make this easier. Blazor.extensions.storage is the namespace used by this library, and then I want a local storage service, and let's just call it local storage for the property name. Great. Now every time I click that button, here's what I'm going to do. I'm just going to save that to local storage. So let's do local storage, you accessing that property.setItem, I think is the name of the API. Yeah, that looks right. Okay. So setItem, and then what are we going to do? We got to give it a key, let's call it counter, and then the value I'm going to put in is the current count. All right. Great. Now this is, I believe an async call, but that should be fine. Like it would just let it fire, and if it doesn't complete, it's okay. All right. But when the component reloads though, we want to be able to rehydrate to that state out of local storage. So I'm going to now add an onInit method, onInitAsync, because we're going to read something out asynchronously, a little formatting goof there. Okay. Let's make this guy async, and in here, let's also access local storage, but let's read out of it. So read local storage that was probably getItem. Yeah. GetItem, and we're going to return a string. We're going to, sorry, not a string, an int out of local storage, and the key again is counter. Yes, I know, I should probably have that string someplace common, and then we'll just populate currentCount with the value that we get out of local storage. Okay. Great. So I didn't have to write any JavaScript interrupt code myself, but just let someone else in the community do that for me, because they do a great job. Okay. Let's go back to the app, and see if it's still working. Okay. So let's say five. Is it building? All right. Cool. So it's loading. Now we can click up the counter up to 11, and hopefully if I did this right, refresh, it should say still 11. It is. Awesome. Okay. Now, if we actually go into the browser, the browser dev tools and into the console, and let's look at local storage, we can see that there is in fact a value counter, and it's got some stuff in it. So that's cool. All right. So that's how you can consume community libraries for doing JavaScript interrupts, so you don't have to write all that stuff yourself. All right. What else can we do with a Blazor class library? Well, you can also share component implementation. So in fact, this Blazor class library has a component implementation in it. There's this component 1.cshtml that's in this library, and it's just a bunch of static content, but that's fine. But it also has some particular styling that goes along with it. There's a background image that it uses. Can we use this component from our application? Hopefully, yes. Now there is one little ugly thing that we do have to do. This is just a temporary thing right now with the way Blazor works. In order to get the tooling to work, we do have to say add tag helper star from, I think Blazor live one. That's just a little thing that you currently have to do when consuming components from a Blazor component class library. In the future, that won't be necessary, but for right now, it is. All right, now let's see if we can use that component 1 from our home page. Let's add it right in here. So can we see component 1? It's now showing up. So we've got component 1 in our application. So let's complete that. Let's just close it and save. Let's go back to the browser, to the home page, and see if we can see component 1 now showing up. And it is. And you can tell that it's also picking up the background image and the custom styling from the Blazor class library because it's got this stripey background and this dotted red line on the outline. That's all done with CSS. The background's done with an image. So now you can build your own components, put them in libraries, package them up in NuGet packages, and share them with the community. A bunch of those also are available on that Blazor community page. So if you're looking for some existing component libraries, you can find them there. All right, cool. So that's components. Now I think let's look at a slightly more involved application. So which one do I do this? So let's go ahead, let's go back to Visual Studio, and let's close this project. We have a sample application that we've published on the ASP.NET org. I think it's also linked from here. Is it available here? I don't remember. Slide finder? No, it's not published on this site. But I think it's on the getting started instructions at the very end. If you want to see this particular flight finder sample, I think it's at the end of build your first app. You go all the way down the bottom after doing all this stuff, you can find a link to this flight finder sample that I'm going to show you now. So let's go ahead and open up Flight Finder. There it is. This is a slightly more involved application. But if we look at the solution structure, it looks like the ASP.NET core hosted product that we saw previously. It's got a client, it's got a server, it's got a shared library between them. If we look at the shared libraries, it's got all sorts of model types that are being shared between the client and the server. Let's run it so we know actually what it does. This app basically, you can think of it as a mini travel site where you're searching for flights. We can say where do we want to, we can go from some point A to point B. Here we're going from Seattle, from London to Seattle. You can select your departure time and arrival time. And I don't even know if validation is set up to check for those things. But if we search, it just returns some random flight data that is not based on anything in real life. It's just randomly generated. But then for each of these flight results that come back, you can add them to a short list that appears on the right-hand side. So there's three basic high-level components here. There's this search component. There's the flight search results component. And then there's the short list on the right-hand side. And we can see that if we look at the Blazor client app for this application. And let's look at this main.cshtml component, the main component. You can see that, yeah, there's the search component. There's the search results wrapped in this grayout zone. We'll talk about that in a second. And then there's the short list component that's rendered on the right-hand side. All right, so that's cool. Now, there is something interesting up here at the top, this at-inject app state. What is that? Well, Blazor itself is very unopinionated about how you manage the application state for your application. There are loads of people who have lots of opinions on how you should do this, Iobservables, or Iproperty, NotifyChain, all sorts of patterns that you could use to manage state in your app. But the community seems to have centered on a particular approach, which is to use a state container so that all of the app state is managed in one place. Now, if you're using existing JavaScript frameworks, they have, in fact, built frameworks for implementing state containers like Redux and so forth that you can then use in your app. In this application, it's using a little mini state container that the app just implements itself. This app state class is just managing all of the state of the class and making sure everyone that needs to know about state changes knows about it. But there are also community projects now available for managing state. If we go back to that community page, then we just let's just search for state. Like, there are people who have done .NET ports of Redux that you can try out of Flux. You can try that one out. I think there was one of Mobix that we saw recently. And we keep finding more about them every day and every week. So you could absolutely use one of those. This application just is fairly simple, so it uses a fairly simple state management solution. So that's what that's doing. That app state is not a blazer runtime thing. It's an app-specific way of managing the state of the application. Cool. OK. Well, what else is interesting in this application? It has some real web APIs on the back end that are used to serve up the data. Here's where the airport list comes from. It's just a hard-coded list of airports. And here's the Acemit Core flight search controller that's used to generate all the random data that you're seeing. So it is full stack web development again with .NET. Now, one thing I wanted to show you here that's kind of interesting is a higher level component that this app uses. And that's this behavior that you see when I click the Search button. Well, the Search button is going to do a web API request at the back end. And that could take a little while. And while it's doing that, you'd rather not just keep displaying the previous search results, because then you don't know. Like, are those the new search results or the old ones? So instead, what it does when you click the Search button, you can see it sort of grays out that search results section so that you can't interact with that part of the UI until the search results have actually been returned. Now, how is that implemented? Well, that's done with this gray out zone component. Remember, seeing that in main, this gray out zone is around the search results component. Now, how is that going to implement it? What does it do? Well, let's look at its implementation. So it has a div. And the div has a class that is conditional based on a parameter. So there's a isGradeOut Boolean parameter that this component takes. If it's true, then it sets the gray out class. Otherwise, no class. Inside of that div, there's another div, which is this cover div. And so what happens is if the isGradeOut parameter is set to true, then there's some CSS that will basically expand this cover based on the size of the parent component and put an overlay over the UI that's sort of translucent gray so that you can't interact with it. Now, this component, interesting enough, was implemented in such a way that it could surround any arbitrary content. You can see it's doing this atChildContent thing here. What is that? Well, components can capture their child content and then use that as part of their rendering. So down below, we have a second parameter, which is this childContent parameter. And it's of type renderFragment. And that renderFragment captures the child content of the component. Remember the main component? It was wrapping the search results. So it will capture this stuff. And then you can, in your component authoring, decide where you would like to render the child content. So that's how that works. It's sort of a higher level component where components can have child content that they capture and use as part of their rendering. And you should absolutely play around with this app. It does a lot of other interesting things. It's available on GitHub. All right. Let's now go back here. So that is a little bit of Blazor. So we've seen a lot of things. Blazor as a UI framework already has quite a few features, even though it is experimental. It has a fairly rich component model. It supports routing, client-side routing. It has a notion of layouts. We didn't really look at that in detail, fairly straightforward. It supports dependency injection, JavaScript interop. When you change the code, you can just refresh the browser because it will auto-build in the background on the fly. We have some very early support for debugging in the browser. We support publishing. We do app-size trimming to reduce the size of your application by trimming unused IL. We also, we didn't show this, but this is supported by the runtime. We support falling back to an Asm.js-based runtime in the event that the browser doesn't actually support WebAssembly so that you could potentially work in older browsers. It'll be a little larger, a little slower, but it can still be functional. And then lastly, you saw that we have rich intelligence in our tooling and editing experience. OK, next I want to talk a little bit about hosting models for Blazor. So the apps that we looked at were all Blazor-running client-side in the browser, and they actually are running directly in the browser UI thread. You download the runtime, the Blazor app. You have a little JavaScript that fires off Blazor. Events are happening in JavaScript that are Blazors in handling and giving to components, and they're rendering, and the DOM's getting updated. All that's actually happening directly on the UI thread today, but Blazor was architected in such a way that all of that work could actually happen in a separate process. So for example, maybe you'd like to actually move all that Blazor logic into a web worker and have only, then through messaging, handle all of the DOM diff updates to the UI and all the UI events coming from the user. And Blazor was architected in order to support that. This isn't something that we have available today, but it was built with this pattern in mind. When we were looking at this, they were like, well, that actually enables a bunch of interesting scenarios where you can use the Blazor UI framework for scenarios other than just client-side browser development. For example, maybe you'd like to use Blazor with Electron. Electron is a cross-platform desktop app framework, which is basically a browser shell that's been wrapped in a process that you can use to build desktop applications that run on Windows Mac and Linux. So we did a prototype where we took Blazor, and instead of running it on a web assembly-based .NET runtime, we just run it on normal .NET Core. And then we communicate with Electron over an IPC channel so that we can handle the UI events from the browser and then push back the DOM diffs to update the DOM in the browser. So let's take a quick look at that today and what that looks like. This is just prototype-proof of concept, but it's fun to play with. All right, so let's go here. OK, so on GitHub, GitHub, Steve Sanderson's repo Blazor Electron experiments.sample. I think this one is actually on the community page. So we search for Electron here. Yeah, so the Electron sample you can find in the sample section on the community page. If we just do .NET Run here, what this is going to do is it's going to fire off a .NET Core process, which is then going to fire up Electron. And it will set up an IPC channel with Electron so that it can handle all of the UI interactions. But there's no web assembly involved here. You're actually running on normal .NET Core. But it looks exactly the same. So instead of writing my Electron app with a bunch of JavaScript, I can actually now write it in .NET. And this application will run cross-platform on Windows, Mac, and Linux. So that's kind of interesting, an opportunity to write cross-platform desktop applications using web technologies and .NET. So that's OK, kind of an interesting model. What else could we do? Well, we started thinking about this, and we were like, huh, well, Blazor supports out-of-process rendering. What if we took that channel and stretched it out over the entire network? In that way, you could actually take the Blazor UI model, the UI framework, and run it on the server. And then you set up a signal R connection to the browser, two-way real-time connection with the browser, and have a little bit of JavaScript running in the browser so that you can send any UI events to the server, have your components run, do the DOM diffing, and then send the DOM diff back down to the browser. And we call this model server-side Blazor. And the nice thing about this is, well, OK, well, web assembly, again, isn't even in the picture here. There's no issues with, like, how do we do debugging? How do we get the runtime to be performant, figuring out how to run a .NET runtime at web assembly? In this case, the runtime is a known quantity. It's just .NET Core. So debugging works. All your normal libraries work. And we have a template that tries out this experience that we'd like to share with you. So let's go back to VS again. Let's do File New Project. Instead, this time, let's recall this, server-side Blazor 1. OK, now I'm going to pick this third template, server-side in ASP.NET Core. And this template is set up to actually run Blazor on the server with a signalar connection set up to the client. So we have two projects in this template. There's .server. That's the ASP.NET Core project. And .app, that's the normal Blazor project. If we run this, it has some different behaviors. But the programming model is fundamentally the same. So the app will look the same as it has a chance to build. There it goes. OK, whoa. Now, I want you to notice that as I refresh, like this app reloads super fast. Like the client-side apps, it takes a little while to download the WebAssembly .NET runtime and get it running, whereas this server-side version runs really, really quick. And that's because we're downloading very, very little. We're not downloading a .NET runtime. We're just downloading a little bit of JavaScript. We can look at the network. That's Control-F5, just to see what actually got downloaded. The download size now, instead of being 1.8 megs, is under 100 kilobytes. OK, and there's very little coming down. There's no .dll's. There's no .wasm. That's all being handled on the server. So super fast startup time. Other things that are interesting, because it's running on the server, normal .NET stuff just works. You can reference normal .NET libraries. You don't have all the limitations of the browser. You can also debug things. So let's go to our counter component. Let's just set a breakpoint on the counter component, F5. So now we're going to be running the .NET code that's running on the server under the debugger. There's no .NET code actually running client-side, in this case, although we wrote our whole app with C-Sharp and .NET. And now, if I click on the counter and click Click, I hit my breakpoint on the server. The experience, let's remove the breakpoint and just make sure we see the experience. It's still the same. There's no refresh happening here. You still get that rich interactive feel of a single-page app-like model, but it's all implemented on the server and handling all the UI interactions over a real-time channel. So we think this is an interesting model. And because it's less experimental, we're actually planning to ship this with .NET Core 3.0. Now, as we do that, we're planning to still continuing to preserve the client-side model. The component model will stay the same, whether you're running on the server or on the client, so that we can continue to make progress on .NET in the browser. Because at the end of the day is really the goal here. We're using server-side Blazor as a path to get to .NET on the browser. We can continue to make progress on the UI framework while the WebAssembly.NET runtime matures. So let me show you how you can take this server-side app and you can actually flip it to be a client-side app without really changing any code. So let's go back to the app. I'm going to stop the debugger. And now let's go and just going to make a couple changes. So in the startup class for the server-side Blazor application, instead of saying use Blazor, it's currently saying use server-side Blazor. And that's the call that actually will set up the SignalR Hub and the channel and all the infrastructure needed to run the Blazor components on the server. There's also a call in the configure services method to add the services needed for server-side Blazor, which unifies the service provider with the one used by the Blazor app. Okay, but what if we just change this back to use Blazor? All right, and then we have to do one other thing. Let's go back to the app. The app has a slightly different index HTML file. Instead of using Blazor.WebAssembly.js, it's using Blazor.Server.js. That's this little JavaScript that's handling the, applying the DOM diffs and sending the UI events back. Well, let's switch this back to WebAssembly. Okay, now what happens if we refresh the application? Okay, now I see that loading thing again. So, it's loading slower, it's downloading more stuff. If we have 12 on the browser and look at what was downloaded, we can see just by tweaking one little thing on the server, we're back to downloading a WebAssembly.NET runtime and all the DLLs. So we're keeping the component model the same while enabling a new scenario where you can do server-side hosting of your applications. So like I said, because this is much less experimental, there's not a.NET runtime that we still need to build and mature, we think we can just go ahead and make this available to you in.NET Core 3.0, which we hope to have a, as we do that integration with ASP.NET Core, to make sure that it's clear that this is really separate from the.NET in the browser effort, we've decided to rename this feature and call it Razer Components. So server-side Blazor is, we're gonna be calling Razer Components and it will ship with ASP.NET Core 3.0. We expect to get a preview of that out probably like early next year. Right, well, what else is new? Well, we're not stopping, we still continue to work on Blazor. Blazor 0.6 is the next release that we're working on. We have new features that are coming in that release. Templated Components is one where you can write components that like a grid or a list view that you can specify templates for, so how they render. And then we're also updating the server-side Blazor support so that you can integrate with the Azure SignalR service. See if I can do demo, templated components really, really fast. To do that, I'm gonna hop over to preview version of Visual Studio. I have a little application here that just renders a list of pets. So I have a pet component that I'm rendering a list of pets with. Let's see what that pet component looks like. It's right here. So it takes in as a parameter an inumerable of pet and then it renders the pet name for each pet. And if we look at how that's called, nothing, yeah, in the pages index.cshtml, you can see here's where the dummy data is being set up and then we're calling the pets list component and passing in the pets. But I'd like to be able to change how these things are rendered. Well, because let's actually update the pets list to have now a template that we can use. And it looks very similar to how we captured child content before, except instead of just render fragment, we're gonna capture a regna fragment of pet because it's gonna be a parameterized template. Let's call this pets template. And then now instead of just rendering at pet and just the name, we're gonna render the whole pets template right here in that list item. Then when we consume the component, now we can define a template as a child element of our pets list. So let's do that if we can really quick. And I think I have a, and say for the sake of time, I've got the template already authored down here. It looks like this. So all this is, I think it's pets template as I, what I changed it to in the, why I just type it, there we go. So you can see that this lights up. So this is now a child element of pets list. And you can have multiple of these. And we're specifying the markup that we'd like to use to render each pet. I can have a parameter, it's the context parameter that I can name. It's called pet and it's of tight pet as we iterate through each pet in the component. So let's go and refresh now and see if we get a slightly better view with my new fancy template that I just added. You can do it. All right, we're reloading. It's rebuilt, reloading. Ah, I messed up something. What did I mess up? Let's see. So close to out of time pets template. What do I do right here? It looks like it's so close. I don't know. Well, we'll have to debug that. I apologize, but we're pretty much out of time. So lots still to do to get to take Blazor to not be an experimental project, lots of runtime work. So not ready for production quite yet, but we hope you found it exciting. Blazor 0.6 will ship this month. And we'll have ongoing Blazor releases monthly. And then in early 2019, we hope to have a preview of the Razor components work. Here's some additional resources. Go and check out the Blazor.net site to download the bits. You can find the code on GitHub. Lots of stuff from the community that you should definitely check out and feel free to chat with us on Gitter. And that's Blazor. Thank you for watching today and I hope you enjoyed it.