>> It's great to be
here. I'm Daniel Roth. I'm a Program Manager
on the ASP.NET team, and I'm super excited for.NET
6 to be finally shipped. It is loaded with
great new features and improvements for Blazor
app development. In this session, we're going
to look at a bunch of them. We're going to look at enterprise-grade
Blazor apps with.NET 6. Blazor is a web UI
framework for building client-side web applications
using.NET and C#. With Blazor, you can build rich interactive web UI components
using just open-web standards, HTML, CSS, and then.NET and
C# instead of JavaScript. With Blazor, you can take your Blazor components and due
to its flexible hosting model, you can host those components
on a server in the Cloud. You can host them on
WebAssembly in a browser. You can even host them
in Native Client mobile, and desktop apps using
a modern approach. With Blazor, you can take the same web UI components and reuse them across
mobile, desktop and web. Blazor is part of ASP.NET Core. Your modern web framework for.NET. ASP.NET Core has everything
that you need to build, rich, modern web UI and powerful
back end services. The addition of Blazor
to ASP.NET Core extends the reach of your web
applications to the client. There's no need to rewrite your
ASP.NET Core apps to use Blazor. Blazor's components can
be added directly to your existing MVC
views and Razor Pages. Who's using Blazor today? Well, in the keynote, we saw
that GE Digital is using Blazor. They wrote their FlightPulse app to put data and analytics
in the hands of more than 3,000 pilots to help them improve safety and
efficiency on every flight. The back-end configuration
for what data those pilots actually see
that was built using Blazor. SPOT by Xplor is a
leading provider of solutions for the dry
cleaning industry. They wrote a beautiful
new modern web UI for their existing Point
of Sales application. You know, the original
UI as you saw, beauty of course is in
the eye of beholder. Maybe many people
think that was also beautiful and nothing wrong
with a little battleship gray. But I think their new
UI looks pretty sweet. They built a new UI
using Blazor server. They were able to reuse their
existing.NET investments to provide a modern web
experience for their users. What about Microsoft? Does Microsoft use Blazor? Yes, we use Blazor for our both internal projects and also for external
product development. Microsoft INTRACT is our insider
trading compliance platform. It's used to identify
and notify insiders at Microsoft of their responsibilities when trading Microsoft securities. This app was built
using Blazor as well as ASP.NET Core and a bunch
of other.NET technologies. Then Dynamics 365 connected store. This is a new offering
for optimizing in store operations with
real-time observational data. They built their in-store
configuration app and set up App as a Blazor application.
Now Blazor and. NET 6 is loaded with lots
of great new features. Way more than we have time to
cover in just this session, but we'll cover as many
as we can for the rest there's lots of Blazor talks
at dot net conf this week, so be sure to check them all out. I'll point out a few at the end. But some stuff that I want
to highlight here,.NET Hot reload is supported for
Blazor applications and.NET 6. You can quickly make
changes to your app and apply them to the
running application. You can now persist
any state that you use when prerendering your
components from the server, from your AS.NET Core
app so that it can be reused when the app
loads on the client. You have a much better
story for error handling with Error Boundaries
and Blazor and.NET 6. We have a whole new
tool chain for dealing with WebAssembly and
Blazor WebAssembly apps. You can do ahead of time compilation
for much better runtime path. You can link in native dependencies into your Blazor
WebAssembly application. You can then also relink the
runtime to remove unused features. We'll be talking a lot
about these new WebAssembly features in Steve
Sanderson's talk tomorrow. The download size of Blazor WebAssembly apps
is much smaller in.NET 6. You can dynamically
render components. You can render components from your existing JavaScript
apps like your Angular app, or your React application in.NET 6, we added support for
custom event args. You can write JavaScript
initializers to initialize logic before and after your
Blazor application runs. You can define JavaScript
modules for each of your components that sit
alongside your component code. We did a bunch of work on
the component model as well. Child components can now infer their generic type parameters
from ancestor components. When you have more elaborate
hierarchy of components, you can put your generic type
constraints in Razor now, you can handle large binary data when you're doing
JavaScript interrupt. For Blazor server app developers, we remove the SignalR
message size limitations. We added support for required
component parameters. Handling query string parameters, influencing the HTML head. We have much better SVG support now. I mean, that is a lot. I'm really excited to show you
a bunch of these new features. All right, getting started
with Blazor, super easy. All you got to do is go
to Blazor dot NET and download and install
the dot NET SDK. Once you've got that, you
can then get going and start developing with your
Visual Studio of choice. Let's go take a look
at Blazor in.NET 6. Let's go ahead and pop
open Visual Studio 2022. I've got it installed here and
let's create a new project. I would like to create
a Blazor application. I'm going to create a Blazor
server app for this app. I actually recommend
that's a good place to start if you're building
your first Blazor app, Blazor server is really nice. That's a fine name
for our Blazor app. Oh yeah,.NET 6 LTS, long-term support, love that. Blazor is in the box with.NET
6. Let's create this. Here is our first
Blazor application. The first thing we want
to note is that this app, the project files, is
looking pretty simple here. We're using the new ASP.NET
Core minimal hosting models. We don't have a startup class. Instead, we have this simple program cs file that has all of
our startup related code, configuring services, setting up the middleware
pipeline and so forth. This is also using the
latest C Sharp features. We've got top-level statements here. We're using implicit usings. We've got namespace,
file scope namespaces, and we've also turned
on non-state checking in all of the ASP.NET Core
templates. Looks great. Let's go ahead and run it
and see what it looks like. When we run this
app, that looks like a standard Blazor app with the classic purple
gradient on the left. But one thing that is
different about this is if we go look at the sources
for this application, let's go digging into
the CSS Bootstrap. Here, notice right there, this is Bootstrap 5.1. We've updated all the
ASP.NET Core templates, including the Blazor templates to use the latest version of Bootstrap. Let's write some code. I'm going to snap this
over to the side, and I'm going to bring Visual
Studio over to the left. Let's give myself a
little bit more room. Where do we want to go?
Let's go to index dot razor. That's the Razor component
for the homepage. Let's give myself again, I think a little bit more room and
let's change some stuff. Instead of hello world,
hello, hello.NET conf 2021. Then we're going to hit the magic
Hot Reload button and boom, it shows up right there so fast, we're updating the
app as it's running. No need to restart it, no need to rebuild it. We can patch it live
while it's executing. Again, as we saw in the keynote, I've added that setting, so I can Hot Reload on FileSave. You'll see me saving instead
of hitting that button. That's why that's working. All right, what else can we do? Let's change this
component parameter. Let's change this.
Isn't this so cool? Then we will save that ready save. Almost immediately it shows up in
our little component right here. We can add components
to the homepage. Let's add a counter, and we'll save that.
Go to a counter. We can click the counter,
the count goes up. Well, we're at it. Let's add all of the components
that's in the template. Let's add a fetchdata
component right here. This fetchdata component will
render a Weather Forecast table. We'll go ahead and save that. They're just Hot Reloads
right onto the page. Great. Now, notice we
didn't lose the count. The count is still there. The app state was preserved. This was one of the great
things about Hot Reload. If you're like deepen a
form or a nested tree view, and you just want to tweak the UI. No need to recreate that app state. In order to make those changes, you can just change the UI
while you're right there. Let's go to our
counter component and let's make some changes to it. In our C Sharp code, instead
of increasing by one, let's increase by two,
and we'll save that. Now if I click on the counter, gets incrementing by twos. Let's even had a
component parameter. Let's do a parameter
attribute right here. Let me have a little white space, and then let's add a property
and we'll do increment amount, and then let's go to the end. We'll initialize this to one. Then instead of incrementing by two, now let's increment by that increment amount parameter
that we defined before. We can go ahead and save
that, that'll hot reload. Nothing really new yet
that's showing up in the UI but if we go to our
counter component now, we should be able to set the
increment amount to something else. Let's set it to not in 16, about 10. That looks good. We'll go
ahead and hot reload that. Now, when I click the count, we're incrementing by tens. We can hot reload HTML markup, we can hot reload components, we can hot reload the.NET C# code. That's.NET hot reload. We can also hot reload
changes to our CSS styles. Let's go play around with
the styling of this app. I'm going to go into the
wwwroot folder and pull out the root CSS file for
this application. There it is. I want to change
the color of this button. That would be this class
right here, Button Primary. Instead of this bluish
color, let's type red. As soon as I hit the d in
red, it's already updated. We've hot reloaded those CSS
style changes into the live dom. Notice, the app is not even saved, this is happening as we type, this is the power of
Visual Studio 2022. We can change this to
whatever we want, we could say green or purple, got to love purple
when you're.NET dev. I'm going to go back to the
blue because I like that. That's CSS hot reload for
your top-level CSS styles. We can also do the same thing with
our components-specific styles. I think we have some component-specific
styles for the layout. MainLayout.razor has a
MainLayout.razor.css, these are CSS styles that will
only apply to the layout. Let me give myself a
little bit more width here so we can see
more of the layout. You notice, there's this top row
that's of this grayish color, that's set by this style right here, this class, the background color
is this grayish color look. Now, when we type red,
doesn't immediately update. That's because
component-specific styles, they actually have to be
built as part of the app so they get sculpt to just
that one component. But if we save it, here we go, save the file and it updates, so you can still get that
rapid development experience. Just got to save the file when you're doing
component-specific styles, but still really cool. We'll save that again, switch
it back, and there we go. That's hot reload for.NET and CSS, it'll make your life hopefully
so much more productive. Cool. What do we want to do next? Let me go back to getting
myself more coding space. Let's talk about error
boundaries and error handling, particularly Blazor Rendering Code. In.NET 6, we have a much
better way of handling errors when something happens as
part of the component rendering. Let's say this weather
forecast component has a bug. Let's go find the FetchData.razor
down here, and on initialize, it's got this service
that it calls to get some random
weather forecast data. We're going to introduce a bug here, we're going to throw a new
invalid operation exception. Boom, that's bad. Now, I'm going to save that. Nothing happened yet, and this is important if you're using hot
reload for the first time, we did update the logic of the weather forecast components
so that when it's initialized, that it's to try to fetch the data, and there should be an
exception that got thrown, but the component has
already been initialized. We didn't do anything
to cause that code to re-execute so we
need to do something. We're going to just
refresh the page, that'll cause it to re-execute. That's something that I keep in
mind when introducing hot reload, what state is my app in? What code has been executed? If you're wondering, why I'm not seeing the results of my changes? Even in pre-rendering of this app, we had the exception
thrown when it tried to pre-render that
weather forecast data. Can we do better for
handling this error? We can, using the New Error
Boundaries component. If we go back to the homepage where we're rendering
that FetchData component, let's add an error boundary.
This is a component. What this thing does is you put
child content inside of it. If everything is good,
if there's no exception, it will render its child content. If there is an exception, then it will render
some Error Content in place of that child content. We can go ahead and hot
reload this and save that. Now, instead of my
fetch data component, I'm getting this red
box with a little icon. What is that? Well, that's the fault error content
for the error boundary. We can look in the Browser to
see what exactly is that thing. It turns out, it's just a div with this
blazor-error-boundary class. Where is all that fancy background
coloring and icon coming from? Well, in the default CSS styles that we provide in
the Blazor templates, we add some styling for
that particular class, that sets the background color, adds the icon using
some SVG and so forth. But of course, you can change this content to be
whatever you want. Let's go ahead and do that.
Let me go back to index.razor. For this, I got my snippets, I'm just going to copy this
one in so I don't have to type all this stuff out, we'll save a little
bit of time here. I'm going to write over this. Let's go back to the
apps so we can see it. Now, what's happening here is we
still have our child content, it's explicitly specified
now because we also want to explicitly specify
what the Error Content should be when there's an exception. If we go ahead and save that, now we're getting our
custom error content, we're getting a div with
a class of an alert, a Bootstrap alert, we've got our own texts in there
and a really sad kitten. That's an error boundary, it's a much better way to handle exceptions in your
Blazor rendering code. Let's go ahead and
clean this back up so that we get rid
of all the errors, we don't need those anymore. Let's go back to our weather
forecast service and remove the exception and hot
reload that all back in. Now, one thing I want
you to make sure you're noticing up at the top, in the Browser tab, watch it as I tab around
in the application, we're on the Counter page
and it updates to counter, we're on the FetchData page and
it updates the weather forecast. This Blazor app is influencing the HTML head to set the
title for each page. That's now supported and
in the box in.NET 6. Let me show you how that's done. If we go back to index.razor, there's this page title component
that you can add to your pages, and that will set the page title. It actually signals that it
wants to set the page title. Then there's another component that actually handles doing that,
which we'll see in a second. You don't just have to
only set the page title, you can actually set anything
you want in the head. In fact, there's a head
content component. In here, you can put meta tags
or whatever you want to do. It's not just limited to the title, but that's pretty common so we provided a specific
component for that. These components, they signal
they want to render to the head, then there's a head outlet component that actually deals with that. Where is the head outlet component? Well, it's over here and
this is Layout.cshtml. We've jumped out of Razor here. This isn't a Razor file, this is a Razor page or an MVC view, potentially. There
was a Blazor talk. Well, remember, Blazor
is part of ASP.net core, they're meant to be used together. Blazor server projects, out of the box, are set
up to do pre-rendering, we're pre-rendering the components
from your pages and views, and that's what's happening here. When we render from the
server of the head, we want to make sure that the title gets set as part
of that pre-rendering. We add the head outlet
component right there using the built-in
component tag helper. We also are careful
about how that component is ordered relative to the rest
of the app being rendered. You may have noticed that instead
of just a host.cshtml file, which you may have seen in the
past and earlier versions, we have both that host
CSHTML file and the layout. That's because we actually
want to render the app first, let all those page
title components run, let the head content
components run so that the head outlet
component can then do the right thing when
it renders the head. This is that inside out rendering
that's done in MVC applications. But this is a good example of using Blazor and MVC and
Razor pages altogether. That's influencing the HTML head. Next, I want to
actually do something with query string parameters. Imagine with this
weather forecast table, I want to have some buttons where
I can change the start date. I don't want to just
look for this week, I'm going to see next week
or maybe I even want to go backwards in time
or 10 weeks from now. Wouldn't it be nice if we can know
the weather 10 weeks from now? We're going to dream big
here and we're going to add some buttons to this
thing so we can do that. Now, let me go find the
FetchData component. Now, when we do this, let me give myself a
little bit more room, we're going to leverage the query string so that we can keep track of what
the current start date is. I'm just going to actually
grab a snippet here again from my notes. It's going to be a
little bit bigger one. But we'll walk through
it, don't worry. We're going to just replace this
code and put this in instead. Now, we've got a couple of buttons
at the bottom of our table that are going to call
previous week and next week whenever we
click those buttons. Then let's go look at the
implementation of those guys, those are just calling this
updates start date method, and that is taking in the number
of days that you want to shift. We have this start date, datetime field that's
keeping track of that state, it's part of the component state, and we're updating it
to be the new value. Now, what we want to do
then is we actually want to save the start date on the URI. That way, we can bookmark that particular start date
for the weather forecast, we can send that link to someone
and they can see the same data. In Blazor and.NET 6, we have new helper
methods that help you manipulate the URI and the
query string in particular. On navigation manager
which I think we have a red squiggle because
we don't actually have a navigation manager yet. Let's go ahead and inject that. Inject NavigationManager, and we'll call it an apply
named NavigationManager. This is basically using dependency injection to add
a property on to the page. Great. Now, we should have no
red squiggles, and we don't. This GetUriWithQueryStringParameter
helper method, it will generate a URI based on the current browser address and add any query string
parameters that you specify. Here, we're saying, we
want a parameter named whatever the name of the
start date property is, which we'll look at in a second, and then put the
value right in there. Then what we do is we use the navigation manager
to navigate to that URI. We're going to update
the browser address, that will cause the Blazor router to kick in and things to re-render. Now, when we re-render that page, we want to now capture that start date so that we can use
it in our component. That's what's happening
up here above. Instead of on initialized, we're now calling
OnParametersSetASync, and the reason we're doing
that is because we have this new start date
parameter that we want to supply from
the query string. That's what this new attribute does. This means, please
bind this parameter from the query string for me. Then once we've got that, if we got one, we'll
use it, otherwise, we'll just use DateTime.Now
and then will go and fetch the weather forecast
data for that start date. I think I have to restart this
app. Let's go ahead and rebuild. Made too many code changes to hot reloading that
one, which is fine. Yeah, we got our previous week. Next week. Do they work? Yeah, I go for it. I go backwards. Let's make this a little
bigger so we can see the address bar and there's our query string
parameter being added. If I duplicate this tab, so now we can see that we've got the same week of data that we're viewing in
our weather forecast data. That's the ability to manipulate the query string
in.NET 6 with Blazor. Cool. What do I do next? I think we definitely
want to look at rendering Blazor components from JavaScript. One thing we hear a lot about from customers is they love
the idea of Blazor. But now I've got a whole bunch
of JavaScript code already. Maybe I'm using Angular, maybe I'm using React. How can I use these
two things together? Well, with Blazor and.NET 6 we
now have a way for you to render Blazor components
directly from JavaScript. This enables you to
reuse Blazor components in existing JavaScript-based
applications. It's a fairly low level feature, but it enables so much cool stuff. Let me pop over here to
a different project. This is a sample that's
in the ASP.NET org, in the samples repo that you can
definitely go and take a look at. Let's pop this open. In this sample application, what we're doing is
we've actually got some custom MSBuild
logic for generating Angular and React JavaScript
components around a Blazor component. It's pretty cool and
this is just a sample. This is not something that's like shipped and supported as
part of the framework, but it shows you what
is now possible. We've got this counter
component here. It's a little bit
more elaborate than the default Blazor counter because
it's showing a few more things. But you'll notice it's got these
attributes at the top to say, please generate me an Angular
component for this thing, or please generate me
a React component. Then in our Blazor app, we register the counter
as both an Angular and React component because we
might want to use it in either, and then we're good to go. These other two libraries, that's just the sample code for
doing the code generation. I'm going to go ahead and run this. Let's get that started. Now that app is not
going to do anything because what we want to
use is an Angular app that makes use of those files
and we're just spinning up the Blazor server to make those files available to
our Angular application. When we publish, we would
put those things altogether. Let's now go to an Angular app. I'm going to open this up in
Visual Studio Code. There it is. This is an Angular app. When I built that
previous application, it generated some code for me, which is in this app folder. We have this counter component, a TypeScript file that was
generated for our Blazor counter. We also have this Blazor adapter, which has all this
infrastructure code that's used by that counter. The key piece is this
Blazor root components add. That's the new hook that
we have in Blazor for rendering Blazor components
from JavaScript. Let's start this angular app now. We're going to do npm start. This will do an angular thing
to get it up and running. What should happen
here if everything is working is we should
have an Angular app with Angular UI that then has Blazor
components inside of it. We're regenerating browser
application bundles, is the whole JavaScript toolchain, there's the Angular app. This is an Angular app now, but if I click this button, it adds our Blazor
counter onto the page. When I'm clicking, ''Click Me''
here we're actually executing, this is a Blazor WebAssembly
code base component. We're executing that as part
of our angular applications. Show you that's really happening. We can go into the network
and let's just refresh. We've got to clear our filters here. You can see there's Blazor, that WebAssembly JS
that's getting loaded. Down here at the bottom,
there's like.NET.js as well. We're able to render our Blazor
components from JavaScript. Super cool, I think this is going to enable a lot of users to be able to take advantage of Blazor
in a lot more situations. Well, I think we're
getting close to time, so let me hop back here to
slides for just a few more. Got to give a shout out to the new dominant WebAssembly build tools. These are really useful for Blazor WebAssembly apps to enable
ahead of time compilation, runtime relinking, support
for native dependencies. Definitely check out
Steve Sanderson's talk tomorrow to learn all about these. Then Blazor WebAssembly apps
and.NET 6 have gotten way smaller, I think in.NET 5 if you build like the smallest Blazor
WebAssembly app you could. It was about 1.7 megabytes. That's about as small
as you can get it if you removed all the extra stuff. In.NET 6, thanks to a whole
bunch of work on the.NET aisle linker and on that.NET
Web Assembly build tools. We can actually get a Blazor
WebAssembly app in just about a meg, it's about a 40 percent reduction. We have one of these published actually that you
can take a look at. This is that min Blazor that
anthonychu.com, Anthony, thank you for helping me set this
up on Azure Static Web Apps, a great host for Blazor
applications. This is a Blazor app. If we F2 and look at the
what this is downloading, lets clear the site
data network and we'll refresh this and look at that
down here at the bottom. This whole app is just slightly
over a meg, so much smaller. Your app loads faster and
users get a better experience. So much more in.NET 6 for Blazor that we won't have
time to cover today. But please make sure that
you go and check out the other Blazor talks, later today, Javier and I will be talking about next generation Blazor
components with.NET 6. Later after that, Elon
Lipton is going to show us using Blazor with.NET
Maui and a whole session. Then of course there's a code party. Hang out for the code party. On day 2 there will be talk by Steve Sanderson on the new
WebAssembly capabilities for.NET, for Blazor WebAssembly apps. Definitely don't want to miss that. Anthony will be there
with Simona talking about using Azure Static Web Apps to
host your Blazor applications, and then a whole bunch
of other great stuff. Definitely go and listen. Thank you for paying attention. With that, I think we will take a few questions
if there's some time. Let's take a look at the big board here. We've
got questions coming in. Make sure that you put
your questions up at hashtag dotnetconf
and we'll pop them into the board here.
What do you see, Jamie? >> Let's go with the, will the Static Web App pipeline
for GitHub and Azure DevOps also optimize Blazor WebAssembly
for.NET 6 applications? >> Yes. I know per fact that
Azure Static Web Apps has deployed the.NET Blazor
WebAssembly build tools, and that will then do
run-time relinking for you. Ahead-of-time compilation
is an opt-in feature. But if you turn that
on in your project, it will then just kick in. The tools are there in
Azure Static Web Apps. I'm less sure about Azure DevOps, but we can check up on that. >> Does that mean that
I can set these things up if I build it correctly, it doesn't matter what pipeline
I use to be optimized? Or do I need some pipelines
support? As Stacy asks. >> You'll need the SDK to
actually do the publish. If the.NET WebAssembly
build tools are present, they will then kick in. If you have both installed, you'll get the benefits of both. If you're in an
environment that only has the SDK and not the dominant
WebAssembly build tools. They're are called an optional
workload in the SDK in.NET 6. We have these sort of bolt-on
pieces now to the SDK, like Maui is also an
optional workload. You need to install that optional workload into your build environment
for it to kick it. >> That makes sense. As
long as my pre-setup step, whether it be a shell
script or batch file or PowerShell
installs that workload, it's theoretically
possible that any of those pipelines or third party
pipelines will be able to do. >> You can definitely
do it yourself. You can set up your own Docker
container that has that setup, whether it has a built-in. I know Azure Static
Web websites does. Azure, I'm not sure
if they've got it lit up yet, but hopefully soon. >> Got time for another one? >> Yeah, we have time
for another one. This is a long one. This one? >> What do you, those with Evan
one? That's what Evan got to say. Evan wants to know what
about pre-rendering for SEO, for search engine optimization? That's the big question when it
comes to these applications. Absolutely. You can pre-render
Blazor WebAssembly apps to. We don't typically do
that for you by default. The reason is it takes a little
bit more thought to realize, well, my component might be on the server or it might
be on the browser. I need to make sure that I
write my code appropriately. That I don't take a dependency in one environment versus the other, but you can turn it on
yourself like there's a pre-rendering mode on the
component TagHelper where you say, I would like to pre-render a Blazor WebAssembly
component right here, and then it will just work. I actually have a sample project on my GitHub account that shows
Blazor WebAssembly pre-rendering. You can take a look
at that and you can use the new like state persistence feature that we have in.NET 6 where any state you used in pre-rendering, you can persist it
into the page and then the Blazor WebAssembly
app can pick that up like your podcasts list can get put into the page and then you don't even need to request
it again once you're on the client because
you've already got it on the server once. Why do it twice? >> Amazing. >> Very cool. >> Those of us who don't know what's your GitHub handle so they can find. >> Danroth27. >> Danroth27. >> Danroth27. As we head out, I just want to make
another reminder that the way that you win these great prizes, the Xbox One, the drone is you do the challenges,
dotnetconf.net/challenges. >> Yes. We have tons of challenges. You can win $500, many drone and Xbox, and more.