 Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and today's episode is part two of an hour long's worth of Sam Bazoo and Ed Charbonneau talking about Blazer. As I explained previously, they were here taking a bunch of episodes with me. They wanted to do an episode on Blazer. I unfortunately had a conflict I couldn't get out of and Dimitri wasn't available. So we left them alone in the studio and they talked for an hour on Blazer. Really good stuff. But we decided an hour's too much, so we cut the episode in half and hopefully the cutting job isn't a little too choppy because we're just going to pick up where they left off now. Let's do File New Project. We'll do ASP.NET Core web application again. This time we'll do the full stack version. Now it's important while this spins up, we'll kind of outline. When I say full stack, we're not doing server-side rendering. So we're still using that client-side. We're going to ship everything to the browser, let it run on WebAssembly. We're not doing ahead-of-time compilation of the views and sending any HTML down the wire other than the bootstrapping index page. That's it. So it's something that we just need to clarify so people don't expect that those razor views are being compiled on the server and HTML is being sent down the wire. So we're going to go back to the server for data, like essentially API endpoints. So if we look at this, it's exactly what you said. We have our client app, which is the same exact thing that we saw before. Now we have a server project and the server project has a Web API controller and this is going to supply that weather data that we saw coming from a static file before. So this is a Web API endpoint with a get action on it and it's just going to randomize some weather data for us. Yeah, and you can hook this up to any data source you want. It could be cloud service and Azure Function Node.js, all the above. Our SQL server sitting under my desk. Cognitive services, you could do some cool machine learning stuff there. So this is just Web API and I can do cloud operations like create, read, update, delete. Absolutely. Okay. And then notice we have a shared library now. All right. So if we're on the client and we're going to iterate over a list of weather forecasts, so this is the same view that we saw before. An array of weather forecasts is coming in from this get JSON async and the server sending a list of weather forecasts, then the weather forecasts can live in a shared location where both projects can access that class type. All right. So how would you share? Is that like a .NET standard library? Absolutely. Okay. So this is a .NET standard library. It's being referenced if I go into my dependencies under projects. There you go. You can see shared. Yeah. And it is actually using the .NET standard library as well. So you can reuse this from Xamarin if you wanted to. Yes. You could share it not only across Blazor projects, but any .NET standard project. And that also opens up this to a whole ecosystem of things that already exist. So think about that for a minute. We'll actually have a demo at the very end here where I've gone in and tried some of these things and seen what works. Like existing Nougat packages? Absolutely. Okay. Nougat .NET standard packages that are on Nougat. Within reason, they work within Blazor. Now, if they have some kind of direct access to the system, they're looking at your system temperature registry or things that belong on maybe windows, they're not going to happen. What you can do though is load in things that are business logic and stuff like that. And I'll show you a use case for that where it's been successful for me. Okay. So this is the other project. And we've got the same type of structure. But inside of fetch data, we're actually going out to an endpoint now and pulling that data in through an API. We have a shared logic folder. These are all very good things to help us be productive. Sure. So in this solution, you could host the server in IIS or anything that you'll host an ASP.NET application in. And then the client could just be served up from anything you want. It's all our client side. Absolutely. In this scenario though, the client application is actually being served by .NET Core. But you could split those out if you wanted to. Okay. All right. So let's look at another project. I'm going to open this one. This is, I didn't want to do too much live coding here. So I know I will fat finger something and we'll have some demo fails. So I kind of pre-created it here. Let's do, pull it off my start page here. I want to show the concept of having external component libraries. So there's currently no file new project experience for creating a component library from within Visual Studio. There is tooling however. We can drop down to the command line. We can type in .NET new Blazor Lib. So that .NET new Blazor Lib will spin up a project that is a boilerplate for creating component libraries. Okay. So let me back up. You said CLI. All of this Blazor stuff, I can do it through CLI as well? Yes. So there's a new get, or sorry, there is a, well technically it's a new get package. So you can go into your command line .NET new dash I will install and then you point to that package and it will install those command lines. And if this is in .NET Core, I can do this on Mac or Linux, right? Yep. Okay. Again, Blazor .NET and look at getting started, you'll find those CLI commands. Okay. People don't have to try to memorize them as we say them here on the show. That's the best place to find them, Blazor .NET. So we have our client application and we have another library called My Components. And I have a component in here called My Component, really cleverly named component here. And I've put that component on my index page. So on my index page I have my component. So you're referencing your component project from inside the Blazor project, obviously. And then you're able to just render that. And does the component have other new dependencies that you're pulling in? Right now it's just dependent on the Blazor libraries. So if we look in .NET standard, you see we have our Blazor libraries here. Right. It's dependent on browser and build. If we come into our dependencies on the client application, you can see I have a dependency on My Components. And then that dependency is registered in the view imports file. So here it's being registered as a tag helper. So this is another familiar concept from our .NET core, ASP.NET core mindset. So I'm registering any components that exist in the My Components library I'm referencing. And that allows me to drop it on my index page. So let's take a look at what this component does. So the code looks almost identical to just rendering a component that's inside of your client project. But you're just pulling this in. Yep. So I have this big box with a dash line. Most of this is actually boilerplate. I've modified it slightly so we have a cool demo for the show. I've just kind of wired up what already exists in that template just to give it a little more flair. Sure. So I'm going to click on this box and now I'm going to prompt. And I can type anything in here. I'll say hello vs toolbox and hit OK. And now that data is represented and it's bound inside of that dotted box there. So let's see how that works. So again, My Component. Look at My Component.cshtml. It's a simple div. It's a binding to the handle click function handler or click handler. It's got a regular CSS class on it with My Component. And then I have a value called message. So I'm going to create a placeholder for it. String message equals clicker to change. That's the default value. And then whenever I click handle click, I'm going to set the message. And this is going to do it asynchronously. It's going to make a call to JavaScript. And it's going to display a JavaScript prompt in the browser. Got you. So I'm making a call to JavaScript from my C sharp code. And then when that comes back, we're just going to notify Blazor that the state of the view has changed and it needs to do an update to the Shadow DOM. Now if I dive in to My Component, you'll see this content folder. This is put here by the template. And inside of that are resources that belong to the component, including this example JavaScript interrupt. So this is a JavaScript module. And it's being loaded into the global namespace of the window here. So on window, we have our scope of example js function and a function called show prompt. Right. And then that prompt takes an argument of a message so we can set that prompt to whatever we want. And then it returns the value that was put into the prompt. So how is the name show prompt different from what you were calling from the JavaScript? I thought you just said prompt in your component. So there's a nice little wrapper, a piece of syntactic sugar around that. If I open up example js interrupt. I see. So there's a little C sharp extension method in here. And it's called example js interrupt. Sorry, it's not an extension method, just a static method. It's asynchronous, so it uses a task. It returns a task of string. And it takes in the prompt message and returns a string value as a task. So here's where it's calling that scope and then that function in JavaScript. Okay, so at this point you're kind of mixing and matching JavaScript and .NET on the client side. So if you have existing JavaScript assets and functions you can call them from .NET. Yes, so if you have existing JavaScript libraries that you love and they're too big to maybe translate over or you want to have a moment where you're migrating to... You're in between. Yeah, okay. So you can do some migration there. Or WebAssembly may not target certain things yet. So for example we can't pull up a prompt natively in C sharp through WebAssembly so we need to reach out to JavaScript to say, hey we need a prompt and we're able to do that. So we have that flexibility and this is how it's done. Okay, that's very interesting. And at the same time we got little experience with developing component libraries. Right. And you can see there's no at page directive on this one. It's just HTML, a little bit of C sharp and razor. Right. And it's very easy to understand what's happening inside of the system. Right. So let's do the server side example now. No, this is where it's going to make it confusing for me, aren't you? But let's see, this is interesting. So we've been talking a lot about WebAssembly. We're going to get away from that for a moment. We're going to actually do all this in the browser or sorry in the server. Okay. We're going to create a Blazor application that is running on the server and all of the data is going to be handled through a WebSocket. So the application on the client is just going to be a very thin client. It's just an HTML page that spins up a SignalR listener. Connection back to the hub on the server. Yeah, so there's a hub on the server that's all part of the application framework. So we don't really have to concern ourselves with all of that. It looks exactly like the previous few examples. Let's run this guy. While that spins up, I'm going to fire up yet another application. This is Fiddler by Progress under the Teller brand, something that you and I know and love. Most web developers cannot live without Fiddler. And Fiddler is a free tool that you can download and use. And it's very helpful for working with HTTP connections and things like that. Because I want to show you when we're running this, WebSockets kind of perform a little different than your normal requests do. So the server has sent down the application through the SignalR pipeline. We have this active connection back to the server. And we can do updates like this and pull in data from our application. And we can do all this using that SignalR hub. At this point, this is not running purely client-side. There's actually almost nothing running client-side in this scenario. So let's actually open this guy up. Let's pull up the network tab. And again, we'll do a reload. Notice all the DLLs aren't coming down this time. No, they're not. Because they're staying on the server. They're running on the server. And we have a small JavaScript file that's handling all of this for us and just sending back changes through that SignalR pipeline. So how does the server know about the DOM if you had to do anything? So that's in the diffs that it's sending back. And it's a binary package it's sending to Blazor to make those changes. So for example, if I navigate here, let's clear this window out. And let me come down. Let's go to fetch data. Notice the data loaded. So the data is in here. And we didn't make any kind of communication back and forth. Let's do the counter component. I'm clicking. There's no communication back and forth. You might on the surface think that you're not communicating with the server. Let's pull up Fiddler. And hopefully this works for me. Let's try to put this side by side. And we'll do a click. And I'm going to demo fail. So let's try clearing our, is Fiddler responding? Fiddler just, oh, there we go. Something was, some kind of lag here. So let me try again. And for some reason Fiddler doesn't want to behave with this demo. So we'll have a little demo fail. Normally what we'd have, we'd be able to open this up and Fiddler would actually show the socket traffic. So DevTools does not capture repsockets traffic. Fiddler can. It may. I just don't know where to look if it's there. It may be a little bit of my inexperience with the WebSocket traffic in the tooling here. It does normally show up in Fiddler though. So every time I click this, we're actually, actually we've frozen up there. When we click this, we're actually sending some traffic through the socket up to the server. Again, this is what happens when you work with experimental bits. Things don't always happen. The way you expect them to. We get the point. So this is running server side, almost nothing on the client side, and you are piping content through a WebSocket channel or a tunnel essentially. Yeah, absolutely. So one other very big difference that you'll notice. Remember before when we did our dependency injection on that Fetch data, something's a little bit different here. So since we're on the server, we don't need to send an HTTP request. So we can just new up a service, forecast service. This could be maybe a layer over the top of any framework or something like that. But we don't have to send a web request because we're on the server with the data and the application and all of that. And we can just say get the forecast asynchronously and do it that way. So our dependency injection actually looks different as well. So we're not injecting an HTTP client. We're just injecting the service, which is a C-sharp class that we've written. Yeah, so this is interesting. You're hosting the data on the server and you're also running the app right next to it so you can get the data just as quickly without making HTTP. We have our weather forecast service in here and it's just creating a task, an asynchronous task to return that array. And like I said, that could be your database there. Okay. So no HTTP call. So that's an interesting mode of operation. Let's do one last demo where we show a project that I've created and used some existing .NET assemblies from NuGet. So let's... Oops, I've got to stop this guy from running first and then we'll see if I can grab it off my start page and I've lost it here. So let's do open project. And the project is called blaze down. I figured I'd go with the theme. Browser plus razor is blazer. Markdown plus blazer is blaze down. So let's do a little bit of blaze down. So this is a markdown editor completely written in blazer. So I'm going to run this up and it's a client-side application. It's running on the browser only. There's no server code in here. So we're going to get the application. The browser loads it up. We have markdown here on the left and we have the rendered markdown here on the right. So this is a very cheap markdown editor that we can just come in here and live edit and then those changes persist on the other side. We can use some of our markdown syntax to change things like headings and do code highlighting, for example. All of those things are working here right in the browser and being rendered as HTML on the other side. You might expect a lot of code behind this, right? I'm parsing markdown into HTML in real time. And are you doing this yourself or do you bring in some libraries? I'm not the smartest guy in the room ever, Sam. So I'm actually using something someone else created. So there's an existing library called markdig. So there's a dependency in this application. And if I look under dependencies and under new get, we've got something missing here. It's actually in a component. Sorry, I've moved it out to a component. So our dependency is in that component itself. So I have a markdown component, new get, and there's markdig. So this is off the shelf. I haven't modified it in any way, shape, or form, pulled it into my project and just started using it right away. I don't know anything about making an markdown parser. And I didn't need to. Somebody already did the hard work for me. I can just pull that into my component. I can open up my component. The component takes and runs a function called build HTML from markdown. And I pass in this content value, which is whatever you're typing into that text box. That runs this function called build HTML from markdown and returns an HTML using this method here called to HTML and sends that back as a string. And that string is loaded as raw HTML into the component, displaying it in the browser. And all of this is now running client-side entirely? This entire thing is running client-side. So markdig is running on the browser using the DLLs that come out of new get. Those are actually running right here in the browser. I can do things like pull in, I can use that HTTP client to pull in markdown files from another resource, maybe GitHub, something like that. I don't know if people saw that, I'll clear this out. I can do import and it'll go back and pull in that original file that I was using before. And then I can also do something cool here. I can say download is markdown. I click that button and I'm prompted with a markdown file. So at this point you were on the client-side and you downloaded a file from the client-side that was generated client-side as well, right? The markdown file, is that like an output of the markdig? So that's what we're going to get to now. I'm glad you brought that up, Sam. I have a download component here. There's another component. There's another component and this is called download button. So this component has an onclick event. That's when you click the actual button itself. It has a property called payload and a property called file name. So if we look at our index page here, you'll see the actual component being used, download button here. And I'm setting the value to that same content value. Binding, all these things are just being bound to content value. The markdown editor itself, the output, and the button are all binding to the same set of data. And then I set the file name to whatever I'd like that to be. And then when somebody clicks the button, let's look inside of our button. So we go to download button on clicked event fires. And I'm using a JavaScript interrupt. So the JavaScript interrupt is necessary in this scenario because of browser incompatibilities. So I initially wrote this with no JavaScript whatsoever. And you're able to do this in Chrome through a special type of URL that you can just set a prompt and click a button and that URI translates into a file download. That's not possible on Edge. Edge has a special API that is custom for Edge called MSSaveBlob. So I've wrote an interrupt that wraps MSSaveBlob. There's basically a simple browser check. So if I go in here, there's a function in here called is HTML download allowed? And there's also one to say is MSSaveBlob allowed? So we check to see is MSSaveBlob a function that exists in the browser? If it's not, that means we're probably not on IE for Edge. And then it fails over to the next mode, which is this HTML download that is more universal. And then finally, if no browser support is there, we'll just throw a console message and you won't see that download come across. So that gets invoked when we click that button. But this project is a good example of how I can use existing .NET technologies, go into NuGet, pull in some packages, write very little code. Almost everything that exists in Blazdown you just saw on the screen. Just a couple properties here and there and a couple function calls. And I'm able to make something really cool like this. Indeed. So that's Blazor in a nutshell right now. 0.5.1 is the current release. It just came out a couple weeks ago. It may be updated by when the recording comes out on Visual Studio Toolbox. But just check Blazor.NET for updates and see how that turns out. And you're wearing an interesting shirt that says goodbye to JavaScript. But it sounds like we're not really saying goodbye to JavaScript. You can do JavaScript and .NET in or up. But just like JavaScript runs natively in the browser on the client side, now you've got C-Sharp running natively on the client side as well. Yeah. My shirt does say goodbye JavaScript hello C-Sharp in Blazor. But I don't wish any bad will towards JavaScript. Of course. There's still some great frameworks out there that a lot of people are using. This is just another option for .NET developers and people that may want to use .NET using web technologies and creating browser-based applications to use. So it sounds like if you are a .NET developer and you want to stay on top of modern web but you don't want to write a whole lot of JavaScript, this is a way for you to write C-Sharp straight up in the browser and run it natively. What about performance? I mean we are running native performance in the browser. Not yet. So again, this is only like six months old. Sure. The performance, I mean if you look at Blazor down it's pretty performant. It does a good job. You're not supposed to be using this framework for building production applications because of the state that it's in as an experiment. The performance isn't going to be as good as JavaScript at the moment. Okay. But it'll get there over time. At least I feel like that's the direction it's headed in and I think Daniel Roth and his team have a pretty good outlook on what's happening. Yeah. And it sounds like this is not just a Microsoft or a Google or an Apple thing. As long as WebAssembly gets better at executing those bytecodes we'll get more and more performance out of it. Yeah. Nothing about WebAssembly is Microsoft. It's the W3C standard. It's a standard technology that browsers are implementing all the other evergreen browsers have it. Other technologies are looking at targeting it. There's Go Compilers, Rust Compilers, C++. So this is just another flavor of WebAssembly and a really cool framework built on top of it. Sure thing. So it sounds very exciting. What's next? Let's just keep an eye out on what the ASP.NET team is doing and Blazor is open source now. Okay. Part of the GitHub repo. Yeah. So Blazor is open source. Again, blazor.net or look for it on GitHub. Further down the pipeline we'll see some more experimentation. There's actually a project out there of using Electron with Blazor and using that same SignalR type server side experience but it's using the Electron shell instead. It's yet another avenue for this cool technology to take off. And the experiments just keep producing really interesting things. So keep an eye on it. Yeah. Clearly you're pumped and I think if you're a C sharp developer and you want to see where your code can go, definitely keep, I mean it behooves you to kind of keep an eye out on Blazor and where this is heading. Very much. Yeah. Well thank you so much for sharing all this knowledge and all the cool stuff that the ASP.NET team and Steve Sanderson and Dan Roth and those guys are building. This is very exciting. So we'll see what comes out of this and how this evolves. Yeah, hats off to them. It's really cool stuff and I've just been watching and enjoying all the things they're making and trying to help with issues on GitHub and if you get a chance to try this out, get the bits, click on the survey button that comes with the example application, fill out the survey, get in touch with them on GitHub, let them know what your needs are so they know where to steer the framework and how to make it better. Yeah, I mean just like anything else in ASP.NET, it's open source and sounds like the community. This is the perfect time for us to play around and make sure we are doing this together. Yeah. All right, very exciting, very cool stuff. So this was all about Blazor on VS Toolbox. Hopefully all of you guys enjoyed it. Keep an eye out on how this evolves. Very exciting times ahead and thank you so much for being with us on this VS Toolbox show. Thank you and bye for now. So I hope you enjoyed that look at Blazor. It's a revolutionary technology. It's still experimental but it's got some potential to really change web development. Hope you enjoyed learning about it and we will see you next time on Visual Studio Toolbox.