[MUSIC] >> Hi everyone. I'm Daniel Roth. I'm a Product Manager
on the ASP.NET team. In this session, we're
going to go from web to native with.NET MAUI and Blazor. Now.NET MAUI isn't just for
Native Client developers. If you're a.NET web developer, you can use.NET MAUI and Blazor together to build
native client apps too. Blazor is integrated into.NET MAUI, so that you can get the best of both a native client app and
the web..NET MAUI loves Blazor. Now if you're a Native
Client developer, Blazor has a lot of
benefits for you too. Blazor is a web UI framework
based on.NET and C-Sharp so that you can build modern
full-stack web applications without having to use JavaScript. Blazor is based on purely open web standards and it works in every modern web browser. Blazor lets you build full stack web apps using
just your.NET skills, your.NET tools, and your.NET code, and you can do that and get a great rich interactive
web development experience. Blazor is part of ASP.NET Core, your complete web
framework for a.NET. With the addition of
Blazor to ASP.NET Core, you have everything you need to
build modern web applications. ASP.NET Core and Blazor are supported as part of the
modern.NET platform, including the recent.NET 6
long-term support release. Now how does Blazor work? How do you get Blazor on the web? Well, Blazor is a
component-based UI framework. Blazor components
are little pieces of WebUI that encapsulate
their rendering logic, any state that they need and any UI event handling
logic that they have. As the components render
Blazor then keeps track of what needs to be updated
in the user interface. Then it very precisely
and exactly updates the browser DOM with just the
changes that need to be done. Then you can take your Blazor
components and you can actually host them on the web in one
of two different ways. The first way we call Blazor server. In a Blazor server application, your components actually are
running from the server, but they handle all UI
interactions and UI updates over a real-time
connection with the browser. Blazor server apps load fast
and they can really simplify your app architecture because all your code is still running
from the server environment. But at the same time you still get that rich interactive
web UI experience that's characteristic of a
JavaScript based web application. Alternatively, you can host your blazer components client-side in the browser using
Blazor WebAssembly. In a Blazor WebAssembly app, you actually download
your Blazor components to the browser along with
a WebAssembly-based.NET runtime that executes your
components and all of your.NET code right there
directly in the browser. Blazor WebAssembly apps are true client-side
browser-based applications. They can be deployed as simple, low cost static websites, and they can even run offline like
a Progressive Web App or PWA. When you combine Blazor WebAssembly
with an ASP.NET Core back-end, you now have that full-stack.NET
web development experience. Blazor and ASP.NET Core have everything you need to build
modern web applications. But what if the web platform just
isn't enough for your scenario? What if you need access to full
native device capabilities? Well we've been working on
expanding Blazor beyond the web. Earlier this year we
shipped support for using Blazor to build native desktop and mobile applications
using a new component hosting model that we
call Blazor Hybrid. Now, what is Blazor Hybrid? Well Blazor Hybrid
apps are native client apps where you take your Blazor components and you
package them with the app, and they run natively on the device along with the
rest of your.NET code. They then render to an embedded WebUI control that is also included
with the application. Everything's local, everything's
running on a native.NET runtime. WebAssembly is not involved. The benefit of this setup is
that you can reuse and share your existing Blazor web
UI components within a native client app and still have full access to native
device capabilities. Of course, the best way to build
a Blazor Hybrid app is with.NET MAUI..NET MAUI has Blazor Hybrid
support built into the framework. You can take your
Blazor components and embed them in a.NET MAUI app. This means that you
can use.NET MAUI and Blazor together to target mobile, desktop, and web with one
WebUI-based implementation. You can also then take advantage
of.NET MAUI features like leverage native UI elements
alongside your Blazor WebUI, or also call into native device functionality
through normal.NET APIs. Let's take a look at
what it looks like to build a.NET MAUI Blazor app. We're going to head over
now to Visual Studio. Now of course to get started with.NET MAUI you're going
to need to have the.NET MAUI workload installed
in Visual Studio. I've already done
that. Because of that, you can see I get these templates. One of them right here, lo and behold is the.NET
MAUI Blazor app template. Now, this is just a normal.NET
MAUI app like the one above it. There's the normal.NET
MAUI app template. But it's already pre-set up to be
able to host Blazor components, right in the application. Let's go ahead and we would go
ahead and create one of these. I'm actually, I've
already got one created, so I'm going to close
this and just go to my app that I've already got
set up, already deployed. This is what the project looks like when you've gone
ahead and created it. We get a single MAUI app
project with Blazor setup. This project is set up now to, of course, target Windows, Mac, iOS, and Android, all four
platforms with one project. I've already got it
running right here. Here is it running on Windows. This is a native Windows desktop app based off of WinUI 3 and
also the Windows app SDK, but its hosting our Blazor
components right inside of it. Then alongside it, we've also got, here's Android. This is our.NET MAUI Blazor app
running on Android device as well. One project using WebUI to
target mobile and desktop. Now we can see that
this is really WebUI. If we hit F12, that should
bring up the browser DevTools. There they are, and these
are the browser DevTools for the little Web View control that's
sitting in each of these apps. In this case, the Windows
app is using WebView 2. If we look at the elements and we
just hover around a little bit, we can see all the HTML elements showing up in the browser DevTools. This is really a hybrid of WebUI and native UI all within
one application. Now how does this all work?
How's the project set up? Let's go take a look at the code. For this.NET MAUI app, the main page of the app is defined
in this MainPage.xaml page. That's what we have up here now. This XAML if you're a web
developer, don't freak out. There's very little XAML
actually in this app, all we have is a single.NET
MAUI native control, which is this BlazorWebView control. Now what this control does
is it sets up the WebView, appropriate WebView control for each of the platforms
you're going to run on. Then it also sets up hosting the
Blazor components in the app so they can then
talk to that WebView over a little local
interrupt channel. We got one now we control that's it. That's the one piece of XAML that
we're going to use in this app. Now, the initial page that gets loaded into that web you
control is this host page. Index.html that's over here
in the dub root folder. We can take a look
at that real quick. It's just a single static HTML page. At the bottom, you can see where the BlazerWebView JavaScript
framework file is being loaded. Then we have this div up
above which has an ID app. That's where we're going to load our root component
for this application. The root components are
configured here in XAML. We just have one in
this application. Here's the selector saying that I want to actually render to that div. Then here's the specific
Blazor component that we want to render into the app, and it's this main component. This is the syntax so you use in
XAML for specifying CLR type. Now where is main defined? Well over here in
main.razor, of course, Blazor components are all
defined in Razor files, which is a mixture
of HTML and C-Sharp. Let's go ahead and open that up. Here's main.razor. Now, this is the Blazor
router component. What the router component
does is it takes care of handling any
browser.NET navigations, intercepting them,
and then rendering the corresponding component
that has that route. Every Blazor app has this. If you had a Blazor web app, you'd have exactly this
same file living in your application as well. Then we have all of our
actual component pages, which are defined up here above. Here are the three
standard Blazor components that we put in every Blazor project, template, Counter,
FetchData, and Index. Those are the three components
that we're seeing here in the app. This homepage, that's just
piece of static HTML. We got the counter with the button that we can click and
the counter goes up. All done with HTML and C-Sharp. Then a little table generated from some randomly generated
weather forecast data. We can see the components for each of those up above
and the project, here's the index page, just some static HTML
with its route and then a Blazor component
for setting up that little survey prompt
alert there in the middle. We have the counter page. Here's a counter,
again, a route HTML. >> Then now we have a little
bit of UI event handling. We've got the onclick event
that we're hooking for this button so that
every time it runs, we run our C-Sharp code which
increments this field and the component renders
and that's how we're getting this counter experience. Then lastly, FetchData. Here's the FetchData component. This is using dependency
injection to get this weather forecast service that we're going to use to get
our weather forecast data. That could be calling an API. In this case, it's just
using a little bit of in-memory good logic to
generate the weather. Below, we have some HTML
to generate the table, we've got a normal C-Sharp
for each loop to just loop over every weather forecast
or render every table row. Then at the bottom we have the uninitialized component
lifecycle method, that's the first thing that runs for the component and that's
what actually retrieves the data from the weather forecast service so that the
component can then render. That's how we're getting
blazer inside of our dotted Maui
Native Client app for mobile and desktop. Super cool. That means we now have a
mixture of WebUI in native, so we should be able to start taking advantage of Native Client features. For example, we don't
just have to have WebUI, if we want to take advantage
of native UI elements, we can do that too. For example, maybe instead of
this HTML based left nav bar, maybe we want to actually use a native tab view control
from the underlying platform. We get that native look and feel for that particular part of the UI. You can use as much native
UI or a web UI as you want. Let's give that a try. Let's go into MainPage.XAML. Now, because this is native UI, we write this part in XAML. This is going to be a little bit
of XAML code. That's not too bad. Instead of a content page, let's switch this now to a
tabbed page. That looks good. Then I think we have to
change it in one workplace because this is amplifier, has a code behind file, which is a partial class which
derives from the same base type. We'll go ahead and fix that up to. Now, we've got a tabbed page. It's complaining
because it's saying, tab views need to have
content pages inside of them. Let's go ahead and add a
ContentPage right here. We'll wrap our blazer WebViewController and will just
format that. It looks nice. We're going to give each
page can have a title, so it shows up in the tab. We'll set the title of
this one to be home. Then what we want to do now
is instead of rendering the main component which
has the blaze or router, it is handling all the tabs, we just want to render
the specific page for this tab because I want to render like the
index component here. To do that, I'm going to set up
another namespace up above XMLNS, and I'm going to call it pages. This will be the
pages namespace where all of our blazer components
are being generated right now. Then let's just change local.py
domain to page's index. That easy. That's one
of our three tabs. Let's go ahead and copy this. We'll add two more tabs list. First one's going to
be for the counter, counter right here as well, for the counter component. Then the last one will be, we'll call this one whether. This will be our
fetch data component. We've got three tabs. I think that's all set up nicely. Let's go ahead and run this
will run on Windows first. We'll go ahead and run that. Now takes a minute or two for it to build and actually
redeploy the application. We'll just let that go, but what we should expect
is instead of having the purple gradient-based
bootstrap styled left navbar, hopefully we'll get
a Windows client app within native tab view using the look and feel of the whatever platform
you're running on because we're using
native UI controls, these controls should
look windows UI controls, whatever comes with
when you i3 by default, essentially out of the box. Looks that employs succeeded. Now, we're just waiting
for the app to pop up. There it is. Here's
our blazer Hybrid app. But now instead of
having that left nav, we've now got these
tabs up at the top. These are native when
you I3 elements, we can click on them and we
see our different pages. The counter of course still works, but we're now having a mixture
of native UI and WebUI. Let's do this for Android as well, because I want you to see that. Now, it looks a little different
on Android because you're going to get the Android look and feel. Android take a second as well
for it to build and run. This is really nice that if there's a particular control
that's specific to a platform or has a particular UI experience
that you just want to re-use, instead of having to try and recreate
that using web technologies, then you can just re-use
that native control. You have the flexibility to do that. There's the apps, restarting and
now we're running on Android. Second to startup and Miller's taking us just a
second and there it is. We got home counter and
whether of course this has a certain material design look and feel because we're using the
native controls from Android. We get native UI and WebUI. We can use both, thanks to doctor Valerie
Blazer together. We can of course, also leverage
native platform functionality. If we want to call
into the device on to get the geo-location or
the network connectivity, we can do that too. Let's go into index.razor and
let's add a button right here. This button, let's say it's
going to check the network. That's just an HTML button. Then what I want below is to have a code block with a
method that's like, check internet, that will handle actually calling into Mao APIs
to check the internet. Now, I'm going to
save a little typing, got a little snippets
set up down here that I'm just going to grab and use that so they don't
have to type this completely on the fly. There we go. This is the method
that I think we want. There it is, so CheckInternet. Now this method is using this
connectivity API from Maui. There it is, thought in Maui
networking connectivity, this is a cross-platform API
for checking the status of the network on any of the
platforms now we supports. We're also querying for the type of network connection that we currently
have again, using those APIs. Then down below,
we're going to create a native alert dialogue to show
whether we have network or not, and then what is the type of
network that we currently have? Then I think I need to
wire this method up. I want, whenever this
button is clicked, I want that CheckInternet
method to be called. Let's do on click right here. Just like we saw on
the Counter component. We want to call CheckInternet. I think that's it. I'm going to deploy this to Android because we're
using the emulator, we can actually change the status of the network without losing any
connection on the machine. There it goes. Who's pretty quick? Now, we have this check network
button and if I click that, it says yes, we do have internet. If the current type of internet that the emulator is emulating is Wi-Fi. This is a native pop-ups. Again, native UI mixed
with WebUI. That's great. Now, if we go into the
emulator settings, let's pull this down
going to Internet. Then instead of having Wi-Fi on, let's turn that off. Now, if we check the network
status has internet equals false, and of course the type
is unknown because we don't have any internet at all. That's how you can call into nave
native device functionality as, as well. Pretty cool. Now, we've seen how we can use our web development skills
to build native client apps. We've seen how we can leverage
native client functionality, native UI, native APIs. But what's really
cool about this setup is now we can actually share this web UI logic with
our web applications. If we started with a web app and want to turn it into
a native client app. We can go just grab the blazer
components from that web app and use them in.NET
Maui and vice-versa. I think we're done
with this project. Let's go ahead and close this. Now, I'm going to go over to this other product that I've
already got set up. This is the.NET podcasts sample app. This is a sample app that's publicly available on GitHub
that you can go look at. It implements a podcast client
in a number of different ways. One of the ways is it implements
it using a web application, using ASP.NET core and blazer. That's this podcast.server
and podcasts that client projects up here
in the solution explorer. This is the ASP.NET Core part
and then podcasts.client, this is actually a
blazer, WebAssembly app, so it's going to run
client-side in the browser. Let's go ahead and run this and see if we can see the
web version of this application. This homepage is all
server-rendered. This is ASP.NET core razor pages
that's rendering this page. But if we go into
the podcast player, everything here is implemented
using using blazer WebAssembly. We get this rich
interactive UI experience. We can search for podcasts and search for
amalgamates ones, of course. Here's my podcast,
we get a playback. Hopefully you can hear
that sounds great. Then we can say that sounded
awesome, let me pause it. Let's listen to that later
and we can put it on our list and later
lists and it shows up over here and listen later lists, but we can decide not to listen
to it later. We can remove it. We can change our settings so that the theme is light
mode or dark mode, or use a system theme. We've got a rich
interactive UI experience, all as a web application
implemented with Blazer components. Now, but let's say, we decided that, we really want a native client experience
for this dotted podcasts app. Maybe we want to be in the different
stores or maybe we want to actually leverage native
device capabilities that's tricky to do on
the web. No problem. Let's add a.NET Maui blazer
app to this solution. I'm going to right-click up here. I haven't existing project that
I've already set up for this or that add existing project. This is part of the sample
application on GitHub as well. You can play around with this.
I'm going to add this project. >> Now we have a.NET MAUI
project in our solution. Let's switch to that to be
the one we're going to run. We should now be able to run
on Windows or on Android. Let's start with Windows. I think we can close our
previous application that we were playing around
with, we no longer need that. Just take a second while it builds, and then it deploys the app. Now, I didn't point this out, but this.NET MAUI Blazor
app for our podcast app, if we look at MainPage.xaml, it has exactly the same
XAML as we saw before. It's just a single BlazorWeb control pointing to the main component
which will route to our pages, but all of the pages for this app, if we look at its dependencies, they're actually coming from
this Podcast.Pages project, which is this same project
down here below where all the pages for our Blazor
application lives. We're literally reusing
the same binary, the same code in both
the.NET MAUI app, and the Blazor app. There it is. Now we have a native
Windows desktop app for our.NET podcast application, exact same UI as we
saw in our web apps, and here's the web one, barely
you can tell them apart. There's windows, and now we
can also do Android as well, so let's switch over to Android. We'll get that running there too. We've got Windows, we've got web, and then if we just
give it a second, hopefully, this will start quick. We also should have mobile. Mobile, desktop, and web all with one
UI set of controls. I was worried it was trying to do
a full rebuild for some reason, but now it's deploying
to the emulator. Exciting. There it is. We now have all three form
factors, if you will, for apps handled by one
code base.NET podcasts on mobile,.NET podcasts on web, and,.NET podcasts on desktop
as well, mobile desktop, and web super-duper cool, so one set of web UI components. Now, what's really neat is that we didn't just reuse the
web UI components in this app, we also integrated with
native device functionality. If we go look at how this.NET
podcast app was implemented, like down here in MauiProgram.cs, we scroll down a bit where
that's configuring it services. You can see there are these various INativeAudioService
implementations that are being added for each of the four platforms
that MAUI supports, Android, Windows, iOS, and Mac. We've got native audio playback happening for each of these devices. We can actually take
a look at this if I pull in the other project, let me add, I think it's
in a separate library, but it's pretty quick defined. In this Lib folder, we have this shared MauiLib where all those implementations were done, and if we F12 on this, here's the actual
Android audio playback. If we hover over the media
player, we can see, yeah, this is calling into
Android APIs for doing the audio playback on
Android, super-duper cool. That's.NET MAUI, and
Blazor together, WebUI, and native on
the same application. Now, Blazor Hybrid isn't just
for.NET MAUI applications. Blazor Hybrid works in any
application that can run.NET code, and that you can then render
to some web view control. If you have a web view
control available and.NET, you can do Blazor Hybrid. This can be really useful if you want to take
an existing.NET app, and modernize it to
have a web-based UI. Maybe you want that UI to work in our cross-platform in
our.NET MAUI Application, or maybe you want it to
now function on the web. This app that you see
here is a legacy, a Point of Sale application
for a dry cleaning businesses, and the company that
built this completely redid the UI using Blazor, from SPOT by Explorer. That enabled them to take
their existing application, and move it to the web. We have introduced not
only Blazor Hybrid support for.NET MAUI but we also have
Blazor web view controls for WPF, and WinForms so that you can use Blazor to modernize your
existing Windows desktop apps. Let me show you that real quick. I'm going to go hop back
over to Visual Studio, and then let's open up this. Let's look at WPF first. Here's a Blazor Hybrid
WPF application. This is a WPF project. It comes up there it is, and
it has this main window. XAML, so it's still XAML, it's not MAUI XAML, it's WPF XAML but down here
below you can see that there is a BlazorWebView control that you can get from NuGet as a NuGet package. If we go ahead, and run this, we now have a WPF application which hopefully should
show our Blazor UI. There it is, so that's
WPF with Blazor. Then if we go over here, and we should be able to see Blazor WinForms as well so we
go over to this other project. Now we have a WinForms project. WinForms doesn't have XAML, but we have the Forms Designer. If we go look at the Designer, and see what this app has set up. Let's give it a second to load, then we can see that
it shouldn't have just have a single WinForms control, which looked a little wonky there. Not sure what's going on there,
but if we look at its properties, we can see that that
WinForms control is also a Blazor WebView control. We have a Blazor WebView
control hosted in WinForms. What's going on with
that? WinForm's gone a little crazy. That's okay. There's our WinForms app, so we've got WinForms app, and WPF also hosting
Blazor components too. Great way to modernize
existing apps. Let me go back to
slides for a second. Now that we're done, we're shipping Blazor Hybrid support for WPF, and WinForms, and.NET MAUI. We're of course shifting our
attention to shipping a bunch of new Blazor improvements in.Net 7, we've got loads of new
stuff that are already available with the latest.NET
7 previews like.NET 7, Preview 7, which
just went out today. Hot reload improvements, and proved ahead of time
compilation performance, expanded Web Crypto support, binding improvements, virtualization
improvements, and much more. We've also got still a lot
more to come in.NET 7, we're not done yet,.NET
7 ships later this year, and we've got a whole bunch
of new Blazor features that are coming as well. You should check out the latest
details in the aspnet core, and Blazor roadmap at
aka.ms/aspnet/roadmap. I hope you enjoyed learning
about.NET MAUI, and Blazor. There's tons of
resources that you can use on the web to
help you get started. Give it a try, and let
us know what you think.