Wednesday 23 October 2024

Blazor Tips and Tricks

>> On today's Visual Studio Toolbox, Ed Charbeneau is going to show us how to set our Blazors to run. [MUSIC] >> Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me today is Ed Charbeneau. Hey, Ed. >> Thanks for having me, Robert. >> Welcome back. >> It's great to be back. >> Ed's a Developer Evangelist with Progress software, and a regular guest on the show, but it's been about a year since you were last on, right? >> It has been. I've been working hard on Blazor for that entire time. >> So a year ago, you and Sam Basu did an episode on Blazor, I believe it was one of our long ones. >> It was. >> Well-received. >> An hour show cut into bite-size pieces. >> Back when we used to do hour-long shows. So it was an introduction to Blazor. Today, we're going to take a look a year later, and you're going to catch us up to speed on some of the most frequently asked questions that you hear, some tips and tricks that people doing Blazor would need to know. >> Yeah. >> But before we dive into that, let's do a brief refresher of what is Blazor. >> Yeah. So like you said, we took a look at Blazor a year ago, it was a very early beta back then. It's now rolled into the official ASP.NET Core pipeline. So Blazor is a brand new front-end development framework, so a SPA framework that uses C#, Full Stack. So we can actually write client-side application code with C# and not have to rely on JavaScript like we normally do with jQuery, React, or Angular, we now have Blazor to take place of all of that, and we have.NET end-to-end. >> Cool. >> So we saw it early last year, a lot of things have happened since then, and every time I present on Blazor, I get asked these questions that are really great questions, but just at a glance, you don't quite catch when you're talking about Blazor so I thought I'd bring some of those questions up with you today. >> Yeah, cool. Let's do it. >> All right. So I'll hit one of the ones that is the most popular question I get, and that is, does identity work with Blazor? Now, people usually frame that question, does authentication work with Blazor? Authentication is actually a browser behavior, so that's usually happening on the client, but what they usually mean is, does Microsoft Identity work with Blazor? Actually, now it does. So with server-side Blazor shipping in ASP.NET Core 3.0, Microsoft Identity will be available with the application. If you click "File New Project" just like you do with an ASP.NET MVC application or Razor Pages application, you get the dialogue in the File New Project, where you can click to change your authentication type. You get that same experience with Blazor. What you get out of the box is actually what we have running here. Just like in an MVC application, you have your login and your register links at the top of the page. So we can click "Log In" and we get prompted with the identity log in experience, and I don't have an account, so we can click "Register" and create a brand new account. Just like with MVC or Razor Pages, we can create an account here, and what I want to show if I can get a correct password through this system here, I don't remember what their requirements are. Now, we get an error screen or what looks like an error screen, but it's actually something very helpful, and MVC does this as well. It says data operation failed processing requests, it's because we haven't created a database yet. >> Okay. >> This is a brand new File New Project experience, but what's nice is we get a button on the error page that says, "Apply Migrations", we click it, will actually create the database for us, Microsoft identity database. It will apply the migration to our database, create all the tables we need, and then it will bring us back into the application, sees us try refreshing the page so we can come back, hit "Continue", and now, we're actually logged in. It says, "Hello Ed Charbonneau@progress.com." So we have identity working, it's backed by SQL and.NET Framework and this comes out of the box with a few button clicks during the File New Project experience. >> So this is a generic identity provider. Can you hook it up to Active Directory? >> You can hook it. >> Or Azure Active Directory? >> You can hook it up to Azure and that steps you through as well in the File New Project experience. >> Okay. >> One other notable thing that's really interesting about the way identity works in Blazor right now is another question that I get asked a lot, and that is, do Blazor components work with MVC, and can you mix MVC, Razor Pages, and Blazor in the same project? So if we go under "Areas" and "Identity", and we look at our "Pages" in here, our logout or login pages, these are actually Razor Pages. So we have Razor Pages that exist in our Blazor application, and they're able to work side-by-side. Now, another thing is people ask, can I use Razor components or Blazor, the component framework inside of an MVC or Razor Pages application. That ties into the same idea. If we go into our host cshtml file. So.cshtml is a Razor Pages or Razor MVC view, inside of here, this is the bootstrapper for a server-side Blazor project, but this is a Razor page. If we look right here, this is where the application starts up, and we have inside of our app tag an HTML helper that says, "Html.RenderComponentAsync." This RenderComponentAsync method is something that we can call and bring Razor or Blazor components into MVC in Razor Pages views. >> Cool. >> So that's another frequently asked question. Two things tie together in my opinion, talk about using all of ASP.NET in a Blazor application, and that is possible. >> Cool. >> So the next thing that I wanted to show is people asked frequently because they see Blazor component. You can refer to these as Razor components. Razor components is something that is the component model of Blazor. So Blazor components, Razor components, interchangeable. >> Okay. >> But when they look at one of these, it's all written in C#, and your markup and your code is all in the same file. So one of the questions I get right away is, can I separate those two things because I don't want my markup and I don't want my C# code intermingled? So I've got an example here where I've already started taking these two things and decoupling them. So we'll finish this up here. What I want to do is I have a fetch data component, and I have the code section down here. What I want to do is remove this code section. So the first thing I want to do is create a C# file, and I want to name this file the same as my component, but with the extension.razor.cs. >> Okay. >> So what that does is it matches up with our component filename. So our component is FetchData.razor, our code behind is going to be FetchData.razor.cs, that allows to the nest in Visual Studio. So when we name them like that, that semantic allows that nesting to happen. So we get this nice tree effect where we can collapse that code behind down if we'd want to. So I'm going to click on "FetchData.razor.cs, and this is the same code that is inside of that code block. I went ahead and moved it out to keep this nice and short. >> Okay. >> So in FetchData.razor, we can now take out this code block because we have that inner code behind file. >> Okay. >> So to marry those two things back up together, we simply come back up to the top here. We just call inherit, so we have an inherits directive. Then we point to that code behind file. So this is called fetch database. The component name is fetch data, so this is the base of that component. So we'll save that. I can also remove this dependency injection from it because that now happens in the code bar. So now I have tied those two things together, and all of our little red squiggles have gone away, and we separated those two pieces of logic. So our markup is in one file, logics on the other. >> So you named that fetch database? >> Yeah. So the filename itself is fetchdata.razor.cs. >> Okay. >> To provide that nesting. But we can't call it fetch data, because it will collide with the component names space. >> Right. >> So we can't have two fetch data classes. >> Okay. >> So we got to give it some things. >> It's a partial class, it's an entirely separate class. >> Excellent question or observation. Partial classes aren't supported yet. >> Okay. >> But it is something that may come in the next release of the preview. >> Okay. So fetch database was just a naming convention that you use. >> It's a naming convention that I use, and it's pretty common in the community right now, is to name that as your base of the component itself. >> Okay. >> Partials may be coming soon. >> It's okay. >> So this may change a little bit over time, but this is one way that you can separate those out today. Also we need to inherit from component based on that. So that gives us all the lifecycle methods, and everything that is part of the component. >> Right. >> So another notable piece is the inject parameter here. So we're injecting through property injection when we do the code behind versus when we're on the markup side, we use an inject directive instead. >> Okay. >> So that's one piece that people look for when they start refactoring this out, is they don't know how to inject that properly. So the inject attribute on the back end side, and it's inject directive on the front end side. >>Okay. >> So that's one of the pieces that people ask a lot about. >> You then you would expect ultimately that that would just be an available refactoring inside the Visual Studio editors so you don't have to do it yourself. That might be a nice feature request. >> Would be a good feature request. There's a lot of tooling changes that will come with all of this new blazer stuff. >> Right. >> I've talked with Daniel Roth and his team. They're very optimistic about what they can do with the razor engine itself. There was a lot of tooling that can come in the future. >> Cool. All right. >> All right. So we can look at some more frequently asked questions. Another one is we get this application out of the box. We need to rerun that, we've done some code changes here, we'll pick this back up and run it. We have this counter component that comes out of the box. The count starts at zero if we click on the counter. This is all file new project experience. So anybody that runs blazers probably seen this counter component before. If we go back home, and then we visit the counter page again, our state is gone. >> Right. >> So don't share a state if I created more counters. They don't share that count. So we can have multiple counters on the page, they would all have their own independent counts. So how do we manage state if that's something that we do on? So there's actually two ways to handle state in, well there's multiple ways to handle state in blazer. I'm going to show you two of them. There's actually some components that are designed for this, so we'll look at a component approach and then we'll look at using dependency injection and do some application state. So one thing I've added to this project, and under my shared folder, I have a component that I wrote, very simple one, is called counter state provider. So this is a provider component that I can plug into my application, and anything that is a child of it will receive the values that I assign to this component. So it uses a special blazer component, this is something built into the system called a cascading value component. Inside of that cascading value component, I can provide child content. That's essentially what this component is for anyway. On value, I'm going to keep this as simple as possible and I'm just going to assign this. So this component's value will be just assigned to the cascading value. Any child component can subscribe to this value now. So what we'll do is we'll take this, and we'll put our current count for a counter component in that object. So what I need to do to implement this, is I'll go into my main layout and now I can surround any piece of HTML in my application that I want to be able to receive the data from. So we'll go right around the main component of our application, and we'll call in our counter state provider. We'll wrap that around the body of the application. >> So this is now at the application level? >> This is at the root of our pages. >> Okay. >> So anything, any of the pages that we load will be inside of the body. >> Okay. Got it. >> So now anything that's in the body which includes our counter component, will be able to receive that. So how did we receive that inside of our component? So there is a special parameter that we set up. I'm going to use a shortcut here, and we're going to use the cascading parameter attribute on a property. We'll set this up and call this current count, or actually, we need to bring in the component namespace , because this is going to resolve to a counter state provider, and then we can name it, and we'll name this, let's keep this simple and just call it state. So this state will be assigned the value of this that it brings in from the counter state provider. So now, we can consume it, we can get rid of this current count equal zero. When we increment our count, we'll use the state instead. So we'll say state.currentcount, that's coming from the state provider. >>Okay. >> Up in this section, we'll do the same thing; state.currentcount. So that should tie it all together. Now, when we run our application, we won't lose that state as we go from page to page. We can also take advantage of that. So now we have our Current count. We can go to our "Home" page, go back and still have a four. Make this a little bit cooler. On our Index page, we can consume that same StateProvider. So then we have shared state across the application. So we'll do the same CascadingParameter. It's going to be a CounterStateProvider. We'll call it State. Then in my Hello world section here, I can just write out Current Count at State, CurrentCount just like that. Now, this will appear in our Home page. So now, we're getting the count off the counter even though they're not on the same page together. So our Current count is zero. We click this up. We go back and our "Home" page changes. >> Very cool. >> So that's one way that we can share state across the application. This is using a piece of markup, the StateProvider uses the cascading value component. So this is markup-driven. We can also do this through code. So we don't have to have this markup piece that drives the State management. So in my application, I've added a very simple poco object, plain old-class objects, called CounterState. I have a CurrentCount on that as well. This is something we can just inject in our application through dependency injection. So if I go into "Startup.cs", I'm going to scroll down to where all of my dependencies are registered. In services, I'll just uncomment this line that I've added earlier. Services.AddScoped of type CounterState. So now, I have this object, this CounterState that is available to my application through dependency injection. So if we go back to our "Counter" component, instead of using a cascading parameter, we'll come up to the top of the page and we'll use the inject directive. We can inject to that dependency injection that CounterState through dependency injection. So we'll call it CounterState. I think I'm missing a namespace here. This is on data. Data CounterState. We'll simply call that State again. So since we named it the same, we actually don't need any code changes here. I can remove this. Now, our data is resolved through dependency injection instead. So it has the same idea but it's application level. Then in our "Startup.cs", we'll go back here for a moment. We used AddScoped to add that to the application. We have several ways to add things to our container. We can use AddSingleton, AddScoped. The reason I chose AddScoped versus AddSingleton, so on Serverside Blazor, you're sharing that application state with the entire user base if you use AddSingleton. So that will be a single instance per application not per user. So it's a very important thing to know. You don't want to share certain things with everyone. Whereas, our weather forecasts service, something is pulling a weather data, we can share with all users because it's going to be the same. So those are some of the most frequently asked questions that I get when I present on Blazor. People ask about state management, they ask about identity, and they ask about code separation. Those are the real heavy hitters that I get all the time. So hopefully that clears things up for you. >> Yeah. That's awesome. So if someone who is starting out with Blazor, what are briefly some tips and tricks on how to get up to speed on it, how to get used to it, how to understand what it is and how to use it? >> So my biggest advice would be first of all you go to Blazor.NET and you walk through the Getting Started materials. The.NET Docs team, they've done a fantastic job there. Second of all, Blazor is a lot different from MVC, where in MVC applications, we're rendering strings. Blazor has something called a render tree that it builds. It's not a string, it's a representation of the DOM, the Document Object Model that is held in memory and it does diffs against it to see what's changed. So it's a big difference from HTML Helpers and Razor Views that just render out strings all the time. The reason for that is those string rendering mechanisms, the client-side code is done in JavaScript. So it goes back and it finds pieces of the DOM, manipulates it, edits it, deletes it, those sort of things. In Blazor, we work with the render tree. The developers do. Then the framework takes to render tree and applies the changes for us. That's what allows C# to be able to work on the client-side. >> Cool. Your impression of how far along this is. Is it preview? Can you put stuff into production with it? >> In September, we will see a GA release. >> Okay. >> So it's coming soon. For server-side Blazor, we'll have the global availability soon. Client-side Blazor will come sometime next year. We haven't got a solid date just quite yet. I've heard quarter one, quarter two. So that is coming soon. >> It requires.NET core? >> Yes. >> Is that true? >> Blazor requires.NET core. >> Okay. >> It's currently on set for.NET Core 3.0. Client-side will likely come with.NET 5. >> Okay. Cool. Thanks for that. >> Thank you very much. >> All right. >> Hopefully, everybody found something useful out of this. Getting started with this stuff is a little tricky. It's a brand new preview. So I figured that most people are new to the concepts because the entire framework is new. Something I've been working on very closely for the last year because of my job with progress, we build UI components for everything. So we jumped on the bandwagon early and created a suite of Telerik UI Components for Blazor. It's been my main focus. >> We will have links to that in the show notes along with the places people can go to learn more. So I hope you found that useful and we will see you next time on Visual Studio Toolbox.

No comments:

Post a Comment

Building Bots Part 1

it's about time we did a toolbox episode on BOTS hi welcome to visual studio toolbox I'm your host Robert green and jo...