Modern Web Dev with Blazor and .NET 6 with Jason Taylor

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] welcome to modern web dev with laser web assembly and asp.net core my name's jason taylor and i'm an ssw solution architect you can find me online at jasontaylor.dev now enough about me we're here to talk about blazer it's kind of a rapid fire introduction isn't it but that's okay let's talk about blazer i'm happy to say that now is the perfect time to get started with blazer blazer's been running production systems for over two years now so it's battle tested and what's more next month microsoft is releasing.net 6 the long term support release version of their hugely successful development platform so if you're like me you've probably been running on preview versions for a while and we're already up to rc2 and i gotta say it's pretty stable everything is working how i like it too so in this talk i want to get you started on the right foot with blazer i'm going to demonstrate tools components data access code generation forms validation component libraries and more you ready to get started let's do it so with ssw we have a really cool ssw rewards app and i just wanted to give you a heads up on this if you search ssw in the app store you can download it and install it now at the end of this presentation i'll share a qr code that you can scan and you'll be able to earn some points and uh win some prizes so what is blaze i hear you ask that's a very good question now i want to be clear this is not an introductory talk but there's something in it for everyone i'm going to share some things that i think are really important when i'm building a blazer application but i'm also going to show you a lot of resources so if you are getting started i'll help you get off on the way but let's start blazer is a free and open source web framework it allows you to build interactive web apps using c sharp html and c and css so you'll be using c sharp mostly instead of javascript with blazer developers use the same language frameworks and tools on both the front end and the back end and this will accelerate development simplify maintenance and reduce complexity let's take an example if you already know c sharp you already know date time handling you already know validation managing collections and so on you don't have to relearn that you get to re to leverage that knowledge across the entire app you're not going to need multiple skill sets and teams to build a modern web app you'll be able to easily share code between the front end and the back end since both are going to be written in c sharp and as i mentioned blaze is production ready it's time to go live it's properly supported and officially released by microsoft and many companies including ssw already have blazer in production all right just like that it's time for the first demo so this one doesn't really need an introduction so i'll just dive right in so let's see i've got an empty directory here but i'll go ahead and create a blazer demo folder and we'll jump into there now let's start by checking what version.net framework i'm running so if i go net version if i get bad command file name i don't have the net core cli installed but i'm running version 6.0.100 rc2 so let's see if that's the latest version if we want to do that we can go straight to dot dot net and in dot net we can go to download scrolling down a little bit all net downloads don't know f5 is the current version and we can go to net six so we can see i'm on rc2 and the latest version is twenty one five o five five seven or is it twenty one five five five seven so i'm on the very latest version but if you're not on the latest version then you can go ahead and download it um for your for your os you can grab the installer or otherwise pretty easy to get started so once you've got that up and running once you've installed the net 6sdk you can go net new and you can have a look at the blazer templates so we go list we can specify the keyword blazer just to filter the templates so we've got two templates available so the first one is the blazer server app and that's built for actually creating blazer applications that run on an asp net core server and communicate with the client using a signalr channel tonight we're going to be focused on blazer webassembly app and that's when we're going to be running c-sharp in the browser so blazer web assembly will run in the browser so i'd like to explore some of the options that are available with that template so if i go net new laser web assembly and we change that to help it won't create a new project it'll just give us the help that we're looking for now there are a lot of options available in this template but they're mostly related to authentication so standard out of box authentication with identity and identity server or identity and azure ad b2c um here we go so the main ones are the target framework so framework uh the target framework for the project hosted this is a good one if specified includes an asb net core host for blazer webassembly we'll be turning that on auth so you can select one of the authentication methods the default is none let's see scrolling down we've got pwa so if specified produces a progressive web application supporting installation offline use so that's definitely going to help you get up and running and finally if you do select an authentication method other than none you might want this option use localdb when you're running this from the command line by default it's going to use lite if you include this option it will use localdb might be preferable depending on your environment that you're programming in all right let's go ahead and create a new blazer webassembly out so we go.net new laser web assembly posted and that'll be fine so this will have three projects we'll have the client which will be the blazer web assembly front end we'll have the server which will be our asp.net core end and we'll have this shared project which will be shared types and logic between the client and the server let me go ahead and run that so if we want to launch this we'll launch it from the server project so we can just go dot net run and let's have a look at what we get in terms of the samples out of the box okay control click on that here we go so you can see we get an amazing hello world page and you can take a brief survey if you like and tell the team how blaze is working for you we get the classic counter example you can count to our hearts content as long as we stay on this page and we get the fetch data demo which is pretty cool it's a demonstration of fetching data from the server so in this case our asp.net core api and this is a random forecast so every time you come here you get some random results let's have a look at the source code too now if you want to work with um blazer on.net 6 you probably want to install visual studio 2022 let's see what the latest version is they updated it this morning [Music] so i'm pretty sure i'm on the latest uh yeah so version 17 preview six you can go ahead and grab that so as mentioned we've got three projects here we've got the client which is the front end or client side blazer web assembly app which is this one then we have the server which is the back end or server side asp.net core application and then we have the shared folder which is logic and types to be shared between the client and server let's dive a little bit deeper into because we know kind of what this is right it's it's it's almost just a class library and we know what this is this is an asp.net call back end with controllers and a few razor pages but in here we've got the blazer webassembly up so we'll dive in a little bit there we have the ww root folder for our static files it contains css files the favorite icon index.html main template for our site and a few things like that next up we've got our app component and this one is the root component of the blazer web assembly application we've got our shared folder which includes shared razer components and i just like to keep the components that are shared across the whole site rather than components that are specific to a feature we have the let's see we've got the pages folder uh which by convention typically just includes routable components we'll talk about that a little bit later on and uh something adam mentioned we have the imports.razer which is kind of our um our kind of using statements specific to this project it's specific to this project because it's at the root level of the project but we can create multiple imports files and if we wanted say imports that were just specific to this page's location it will apply to everything under pages which is kind of useful especially when you're building out features and they have a specific feature folder ah so let's see so um we'll have a quick look at those three components we have the index which is the home page it's quite simple generally a razor component has some directives at the top some markup and sometimes some code underneath the counter component has all three so we've got our directives our markup and our code behind and finally the fetch data component which is actually um specifies a new using statement we don't we wouldn't really typically want that though we'd go ahead and whack that straight in imports we're going to be referencing that those those files a lot so we can drop that out and then we're injecting a service that'll be supplied from dependency injection and there's our markup and down the bottom of course we've got uh our code behind and we've got an uninitialized um kind of page lifecycle event and in that page lifecycle event we're making a call to the backend to grab some weather forecasts loop through and display them so you can see that it's simple to get started and the sample code provides some basic examples but it's not enough to build a real app so in the following demos i'm going to upgrade this template i'll demonstrate state management api access data access file organization and more and i'll provide you with a sample repo so hopefully you have everything you need to build a real app so let's go to the next demo which is the counter upgrade so in this demo we'll explore techniques for managing component state and app state by upgrading the counter component let's have a quick look at the current implementation so let me just make sure i didn't make it mess anything up there i think we're good right so we'll control f5 this and see if we can get the new.net 6 hot reload experience working for us i found that it works best if we just um start without debugging so um we've got hello world here let's see if we can change that over there we go so there we go so the hot reload experience is quite nice um some of the times it doesn't quite work how you expect but it'll actually let you know um if something's if something's going to be kind of required um for an update uh let me see let me see if i can trigger it i'm sure it'll come up as we code so this is the counter component and if i go to the counter component i can click on this button and increment the counter that's amazing if i click on that and go back i've lost my current account which is greatly disappointing because i've lost all my progress so seven clicks have gone forever so in this demonstration let's start by adding some app state so that we can actually keep the value of the counter component while we're using the application so where will we start we're going to build a new component which is going to be a special one and we're going to call it appstate so we'll pop it here abstain dot raiser and with this component we're going to use something called cascading values and parameters and they provide a way to pass data from component to all descended components without having to use traditional component parameters so let me grab the code for that so we don't have to type it up by hand you can see i've got a cascading value and you can specify a property here but in this case i'm specifying this which is the actual app state instance so that's what's going to get passed down to descendant components you're probably wondering what are these descended components that we're talking about well let me show you we've got over here in let me see in app where we um kind of bootstrap our component we go ahead and wrap that up let me just grab that code okay so app state will become the root level component and everything else will be a descendant and so that means that the cascading value will be available to all components under app state and so if we wanted to access that cascading value we can go ahead and define a cascading parameter so this is a good example this is what i was talking about before it's saying hey hot reload can't automatically apply your changes um do you want to rebuild and apply your changes or continue editing and you can just check this box and for the entire session it will do that automatically for us so we won't have to kind of manage it hot reload will work its magic if it can otherwise it'll be net watch working behind the scenes helping us out i believe it's starting that watch okay so we've got our app state set up but let's have a look at what's in upstate let it go they just shared there we are so it's quite simple it's render fragment called child content which is basically everything that's wrapped um in app state so in this case it's the router and the main layout and then we have a backing field and a property um this is not an auto property because when the current account has changed we want to notify the app that it needs to re-render so we go ahead and call state has changed so with that in place let's uh let's wire up the toolbar to display the current account so in this template i think it's in main layout yeah we have this little toolbar at the moment there's just an about link to learn more about asp.net core but we'll go ahead and pop in a little span and we will display the current count as it is set in appstate.currentcount and it's complaining about that because it doesn't know about app state yet we have to define parameter so go ahead and add a code block and we say this is a cascading parameter and we'll set a property for it whoops my shortcuts aren't working which is terrible um that's okay i think i'll be able to manage uh we'll just make it private appstay state yeah all right there we go so we've got the cascading parameter so that should sort itself out uh it's complaining about you know the nullable implementation you know that's i'm not going to be using that for this demonstration so i'm just going to go ahead and get rid of them so i don't know squigglies practice just for the purposes of this demo all right um let me get rid of the right ones yeah that's good oh yeah the other thing that you saw in there right implicit usings so um by default you know with a lot of the new templates it comes enabled and um so so um it'll be the default experience but if you if you're working on an existing project upgrading to netsix you'll want to go ahead and enable it all right so we have the cascading parameter it's getting the value of app state that's being passed down to this one because the the main layout is a a descendant of app state now so if we go over here we can see the current count is zero if we increment this nothing's improved because we haven't actually wired up the counter component so let's get that done nice and quickly so we're going to go ahead and add another cascading parameter here it's obviously the same one this time no okay but abstain okay we won't need that anymore that's our local component state um it wasn't providing us with a great deal of value uh let's see uh yeah that's fine uh so we'll go appstate dot current count is what we'll display and here of course we can just increment it uh as normal because we defined it as a property let's have a look it's doing the the rebuild for me so i don't have to worry about it and now if i increment the counter it's incrementing in both places because it's using that uh app state and uh of course the state um has changed method is being called to tell those relevant components to re-render if we navigate away and come back all of our work is not lost and we can continue where we left off which is spectacular and it and and it's and it's a good experience but if we were to go and refresh the page which our users will often do they'll lose that value because that value is just being stored in browser memory um and and they're going to be as disappointed as i am as to having lost those 20 clicks um so let's go ahead and update this a little bit further just to store the value of the current count in session storage so we have two kinds of um storage that we could use i mean there's a lot of different storage but say if we're talking about html5 apis we've got session storage and local storage session storage just applies to this browser tab and local storage applies to the site that you're accessing so in this case i'll use session storage because if i open up two counters in two separate windows i'll be able to increment independently and get a lot more done on separate tasks that way so to get this started we're going to add some javascript and do a little bit of javascript interrupt and also show you a um a nice package that you could use too that that does a great job but it's good to explore interop a little bit so we'll create a javascript file in our static files here and we'll call it scripts and then we'll call it laserdemo.js okay i'm not going to type the code out by hand so we've got this little blazer object that we're initializing to be empty and then we're attaching some methods to it so we've got javascript object so we've got get session storage which takes a key and uses the session storage api to get the item given that key and then we've got another method set session storage which will take a key and some data and store that for us so that we can retrieve it later on so with the script in place we need to update app state to load uh and save the counter value from session storage so in order to do that with net methods we're going to be injecting typically we would inject the ijs runtime but a better approach is to actually inject sorry i should clarify a better approach when you're working only with blazer web assembly is to inject the ijs in process runtime because with blazerweb assembly we have direct access to javascript we're not the code isn't running on a server communicating over the network via signal ah we're right there running on the client so if we want to run this synchronously we can so let's go ahead and inject the ijs in process runtime okay um now if we do this sorry just call that js it's not going to quite work for us it because while ijs runtime is wired up for a dependency injection ijs in process runtime is actually acquired by downcasting from ijs runtime to ijs in process runtime and so if we want to wire it up with dependency injection we can do that we can go over to program.cs which is where we wire up our services for our blazer front end and you can see we've already got one service wired up out of the box uh it's the hdp client and it's specifying the base address for that client which makes our life easy if you're wondering where the base address comes from it comes from index.html and it's the base href so that's that's that's a very nice approach to take so we don't have to worry about that for any of our future services so if we want to make the ijs in process runtime available we can simply wire it up with dependency injection and we go ahead and use the service provider to get the ijs runtime and cast it to the ijs in process runtime and now we'll be able to inject it into our counter page so with that in place we can go ahead and update our uh sorry this is um not where i want to inject it i want to inject it into abstain so we're not going to be doing it there there we go okay now we can go ahead and update this page to load and save the state from session storage so if we want to load state from session storage you can use the on initialized method or event and we can do it quite simply like this so we're overriding uninitialized and we're calling js.invoke so synchronous and uh we're saying that we're expecting to get back a result of type string and then we try and cast that uh into an integer which is the current count i wonder if can i just can i just put it as an int and will that return no no that won't work i'm just thinking out loud there i've been working on this presentation for a little while still running through my head all right so we go ahead and get that from the [Music] session storage but i don't quite like this um i've been reviewing a lot of other blazer open source projects and i've been learning quite a lot from from those projects i recommend you do the same so one thing that you could do inside of say shared or somewhere else in your application create a js i think actually i've got a reference here that i can just use yes i will use this instead typing it out by hand so we'll go chaos interrupt const dot cs so then pop that in there and we'll implement it like this so you can see i've got basically this constants class so i don't have to use my magic strings to access the javascript functions that i'm trying to access so you can see i've got this function prefix blazer demo and that lines up here with this prefix and then i've got um the two methods so get session storage and set chests and session storage building on the function function prefix this one's private but the other ones are public so it makes it quite easy for me to use those so if i come back over here and replace this nasty magic string with js interrupt constants dot and here we want to get session storage we can replace this nasty string with name of current count that's a little bit better i like that approach better okay is it okay is everything okay blazer i think so okay good so on initialized we're going to load uh the current account from session storage that's nice and easy the other thing that we want to do is anytime that the current count changes we'll go ahead and save that to session storage and so a little bit of code here to do that and it's going to be this one but we'll go ahead and update it again so js interrupt constants wondering uh which project um i i saw this source code in and it's not quite exactly the same i customize it to my purposes um it was in ant blazer they have a lot of really solid code in there worth it worth checking out so set session storage and then we'll go name of current count there we go that looks pretty nice so if we load this component it will grab the current account from session storage and when we update the current account it will save it to session storage now this is a simple example you could also save an entire complex object because we're just using um serialization converting the object into a string and storing it in session storage so this is a decent approach so we'll go ahead and save those changes and let's see if it's working okay it is not working i know why i've run into this issue about three times but i'm never gonna learn so this blazer demo.js file is not being referenced so we've got to go and pop it in here so oops here save to the refresh that no we'll do this one time okay incrementing and here we go control f5 there we go so it's still there and if we want to have a deeper look we can go over to the application tab here have a look at session storage and there it is current count bang nice and easy right okay so i mentioned that there was a another project that you could use if you wanted to work with these storage mechanisms now i couldn't remember it was laser eyes storage i was talking to someone about it today and we reviewed the source code because i wanted to make sure that if i was using blazer web assembly and i wanted to use the js in process runtime instead of just the js runtime that it was going to be able to do that so yes this is the package and it's quite easy to wire up it looks like it has a lot of settings that you can configure and then when it comes time to use it let's see there we go away local storage so obviously we're injecting the ilocal storage service where your weight local storage set item async so that's the asynchronous method and if we look at the code behind that that will be using the ijs runtime and it says here if we're using blazer webassembly you might like to use the isync local storage service and then we can use the um synchronous method which i've heard is about four times faster than the asynchronous method just because of the overhead of the approach to support both blazer server and laser web assembly which are fundamentally quite different so there you go this would be this would be a good package to check out and um definitely worth reviewing the source code there to help improve your understanding of blazer okay uh so that's it uh using cascading values and parameters with js interop and session storage we can now retain the state of counter for the entire browser session and as promised you know if you want to get twice as much work done you can go ahead and duplicate this tab and let's let's oh a little disclaimer i'm not using windows 11 so i don't have these nice new features i understand from adam that i'm not a real developer um i i i i'm very sad but i'll i will work on that so let's see there we go so we're incrementing our current count here independently of our current account over there just because we chose session storage over local storage which can be nice you know sometimes when you're building out these features the user might say to you i want you to remember my filters for example and so you remember the filters for them but you use local storage and then they do this sort of thing where it's side by side and they go hey my filter's from the other tab is overriding the filters on this tab i don't want it to do that well that's when you switch to session storage all right let's move on to the next demo this is a good one fetch data upgrade it's time to update the fetch data component in this demo i'm going to add support for open api including swagger ui and then using the generated open api specification i'll generate strongly typed c-sharp clients for using blazer web assembly so let's start with a quick review of the fetch data component jumping in here fetch data okay so as before we've got our directors we've got our markup and we've got our code behind we don't need that anymore so the markup's pretty simple right this is this is razer and uh it says if the forecasts are null just display a loading message because we're probably still loading otherwise display this table and all of the forecast data that we have available simple for each loop now in the code we have this private kind of field available which is an array of weather forecasts when the application sorry when the component is initialized we make a request to the back end to get the weather forecast from this end point and we cast it to that type which matches this type we get a forecast back and that runs as expected we've seen that running but let's have another quick look fetch data random information coming from the server and if we do a quick refresh there you can see there's the request to weather forecast and here's an example of the data being sent through okay so it's hitting the back end api we have a look at the orcas controller we can see yes it has a a get method sorry i get action the route has been customized to just be the controller name so it'll be just this part of the controller name weather forecast and it will go ahead and generate some random weather data for us now this is a small component but really there's a lot of things that are wrong with this approach firstly we don't really have a way from the code here to understand the capabilities of the api we have to specify the route using a magic string that can break and we even have to specify the return type a lot of things can go wrong with this it's not really easy especially if you have two two separate teams you know one people one one set of team working on the front end one set of teams working on the back end it's gonna happen less with blazer right because we're all just writing c sharp um but we can certainly improve this with with a few small changes so let's go ahead now and uh implement open api and i'll do that using my favorite open api tool chain and swag so with end swag we're going to be installing some packages on the server project so from the commandline.net add package and swag.asp.net4 and then we're going to install nswag ms build so nswag asp.net core will provide us with the services and the middleware in order to display swagger ui and generate an open api specification at runtime based on asp.net cores api explorer it's really easy to use so should i install ms build there we go ms build that's good so we use the ms build project or package to automate the whole thing and by automate i mean when we build server is typically um if we've changed a controller or an action we'll need to regenerate the open api specification and later on the clients that we're going to create and so we'll automate it by using an ms build task to run and swag after blazerdemo.server is built so let's fire it up so that we've at least got an open api specification and so that we've got swagger ui so i'm going to program.cs we can start by saying uh let's see oh this is the new minimal template right so we don't have really anything in here startup scorn program.cs is gone our namespace is gone our methods are gone they've taken everything from us and left us with this comment so we know to add our services here and we've got this comment so we know to wire up our middleware here okay but don't go past here and don't go past here you've gone too far we need a comment stop adding services here all right so we want to wire up open api so we go builder dot services dot add open api document and i like to customize this a little bit and i just want to give it a title so go configure title equals laser demo api there we go so what did that do for us it just added the services necessary for us to work with ensured not much really so now we want to add some middleware we want to configure the http pipeline so we can do that first by saying app.use open api you know what let's just start there let's see what we get with that fortunately we've got everything kicking over nicely in the background so we don't have to worry about anything we just have to be patient and we come over here and nothing's changed here but if we go to usa swagger b1 swagger.json we can look at our open api specification and so you can see it's been generated automatically for us by nswag and if we scroll down it describes the operations the inputs and outputs for the operations and any specific types such as the weather forecast type so we can now use that open api specification to display something like swagger ui and to do that with n swag we can just say use swagger ui3 save that and i made a mistake do i okay there what's happening here uh it's all it's all gone down that's okay we'll get it back up again use swagger ui three no there's no mistake there that looks good we'll go ahead and refresh this so we've got that specification and it's worth noting that specification is being generated at runtime each time okay and so now if we go to forward slash swagger we also have swagger ui so it provided this really cool mechanism for our developers to explore our api so if we go into get weather forecast we're going to try it out execute and get the results back easy right it's not really about that though it's about what we can do with that specification and what i love to do with the specification is generate strongly typed clients whether it's for angular view or react or in this case blazer so let's have a look at how we can do that first thing i don't want to generate the specification at runtime i prefer that we generate it on build using that ms build task i really like to see the specification actually as part of my project as a file in my project so that i can see when it changes when i go to check-in changes um i can i can see that and also it's one less thing that i have to do on my azure devops pipeline so you know if i'm generating it manually i don't have to run it um because i check in those changes so let's see i want to store the specification in wwe root and uh yeah let's let's just get let's just get it done so to do this i'll use a tool called and swag studio and nswag studio is not really geared yet for net six and in a moment we'll see why so i've created a new configuration here because this is the answer studio is a nice big configuration editor so that we don't have to edit the json configuration by hand which certainly makes life easier i'll go ahead and save it straight away i'm going to put it in where did i put it today demos laser demo server because that's where we're running our end swag from so we could go ahead and call it n swag.json that's pretty typical but i like to call it config.n swag the reason is that with the swag extension i can double click that and it'll load up n swag studio which is kind of nice so there we go we've got our new configuration saved now you can see from the available runtimes it only supports up to net5 now that's going to be fine for our purposes but it just goes to show n swag has not yet been upgraded to support.net 6. so the preferred method is to use asp.net core via api explorer that will tell us everything we need to know about our api you can see we can we need to navigate to the project file path so i'll go ahead and do that which is this one and we have this option no build now remember i want to run nswag after the server project builds so i don't want n swag to then build a project again so we'll check that scrolling down i want to put an output file path now we know that the convention is swagger forward slash v1 ford swagger.json but i don't think that's a very good convention the reason is that it's not called swagger anymore it's not the swagger specifications open api specification so i'm kind of going my own way on this one and um we'll call it put it in an api folder i like that because it kind of matches the default route that i'll use for my apis forward slash api and then we'll create a folder to support the version b1 that's good and then we'll create a specification file instead of calling it swagger.json i'll just call it specification.json and that'll be fine one thing you'll note is that we have these hardcoded paths here if i save that and we actually have a look at the configuration file just over here oh yeah that's that's the only problem with with making it that after sometimes i will just do open it with visual studio code see it automatically opened it for me in nswag studio if we save that you can see where's my output file path it's usually down the bottom oh there it is it's relative okay so if someone else checks out the source code they're not gonna have a problem because they've um put it in a different location on on their drive okay so we have this um first part of the configuration built and the first part of the configuration is for our open api specification we can go ahead and test that out now by clicking generate outputs and it fails which is which is always fun it's within until you have some experience sometimes these things can be a little bit hard to debug fortunately i know exactly what is wrong here and here's the message we're looking for nswag requires the entry point type program to have either a build web host or create web host builder slash create host builder method so what does that mean it means that nswag currently does not support this new minimal program.cs it misses the methods that were available in program.cs so i've tried a few different approaches to work around this and to be honest my preferred approach is just while we're in this transitionary period because i'm on rc2 it's just to bring back startup and program.cs because the fact of the matter is that with net 6 the templates include this minimal approach but it's up to you to use your preferred approach you're not locked into this so if you want to do things a little bit differently in your project then you can go ahead and do that there is a bit of a problem though if all of the templates ship with this middle approach it's pretty much going to become the standard approach and people will forget about the old approach so it's a problem for now but later on not so much of an issue we'll see how it goes anyway we're going to revert this back so that we can have the really nice experience with nswag the open api generation automation and the c client generation so to do that we'll go ahead and move everything into our startup dot cs and inside of startup.cs i've got this i've got i've leveraged the nice um namespace without uh with without the extra level of um braces and it's pretty much the same the only thing that is different is that i've gone ahead and added new static files because our open api specification is actually going to be stored from stored in www root which is the static files for the blazer demo.server project everything else is the same so we just need to update program.cs now it will be just like that so this is the method that nswag was looking for that it couldn't find so if we save those changes and if everything kicks over nicely we'll be able to run n swag studio again and see the generated specification so that's great we've got nswag working with n6rc2 to generate an open api spec now i want this to happen automatically as i mentioned so we'll we'll update uh the laserdemo.server cs proj to run and swag after build so you can see here we've created a new task called and swag it's going to run after build only when the configuration is debugged so it's only going to happen during development it's not going to happen as part of our devops pipeline you can see here where is it the command will be run and swag sorry it'll the command will be run the net 5 version of nswag and the command will be run and use the current configuration which will be locked to development just because of the environment variables that are being set here now you notice that we haven't specified a configuration file such as config.nswag or nswag.json you don't need to n swag.json is is the convention and config dot n swag is a recognized convention as well so if we build this project now we should see and swag output and happen in an output here try that again build there we go so and swag come online tool for netcore5 it ran and look wwe root has appeared api v1 specification.json so that's now been generated automatically for us which is great okay so now that it's been generated automatically we don't want to generate it at runtime so to get rid of that we can just drop this app.use open api that brings us to a problem which is now that we're fighting against the current convention swagger forward slash v1 forward slash swagger.json we have to use configuration at least until my convention becomes the um sorry until my convention becomes the popular convention dot uh what is it document path and i've got i'm bored of typing that in now so we'll go equals there we go okay so we can see here that we're setting the document path to reference our specification which is matching up to this one so go ahead and save that everything is going to tick over nicely for us and if we come to swagger ui we just have to get rid of this there we go we can see that it's pointing to apis v1 specification.json and everything's working as expected otherwise we wouldn't even see this all right uh it's behaving normally and of course we can access that specification in the same way that we access the other one just to a different location oh if you're wondering why this looks so nice it's the jason viewer extension for for chromium browsers okay let's see now we're going to build the c-sharp strongly type client and to do that we'll update our configuration in and swag so c-sharp client we check this tab and we go to settings we have to specify a namespace the namespace we're using is laser demo i wonder i could change that namespace but we'll leave it for now blazer demo works um even blazerdemo.com we also want to bring in some additional usages why do we want to bring in usages well in the past when we would generate these clients say a typescript client we would actually generate the associated dtos so you saw in our specification we have this weather forecast object so we would generate a typescript version of that that version would live on the front end and of course the c sharp version the source of truth would live on the back end and we'd use n swag as a way to keep them in sync so we had a single source of truth and we weren't violating the dry principle by maintaining those two matching types independently which we typically fail to do anyway but we don't need to do that anymore remember our client and server are sharing the same code it's right here so we don't have to generate those types but we do need to reference the name space for the generator clients so we can just go ahead and put laserdemo.shared or anything else that we need we could also which is something that i've got to do next is have a play with global usings maybe we don't need to add any additional namespace usages and that has its own benefits but i'll save that for another day so we've got our namespace and our blazerdemo.shared we're going to generate our client classes which will be our client classes that will depend on the http client to make requests to our backend api i like to uncheck this option because the base url has been set in the http client we saw that before right so when we looked at um the client over here and we saw how in program.cs um http client was wired up with a base address so we don't want to have to specify for these generated clients they'll just use this what else have we got i like to generate interfaces where is that generate interfaces for client classes that's handy scrolling down uh wait did i pass it no here it is generate dto classes pretty happy to be able to uncheck that it's really nice to have that c sharp code in the shared project accessible on both the front end and the back end and now we just want to specify an output file path let's see we're outputting this to the client uh so there's our client project we're going to put it in a services folder and i like to call it laser demo api clients dot g dot cs so g for generated i don't know if that's a good convention it's just something i started doing recently so let's give it a try generate outputs cool there's our client right up front we have our i weather forecast client our interface and it has two methods get async or get async with a cancellation token nice and simple underneath that we have our implementation i'm not really wanting to dive into the details so let's just go ahead and save and continue we we use n swag on pretty much all of our projects and the clients that they generate are really great we haven't had any problems with them in production whether it was typescript clients or c-sharp clients one thing to note is it's powered by these liquid templates and if you do need to go ahead and modify your template it's really easy to do it's really easy to include it in your project and quite quite a nice experience overall so don't be afraid to dig in a little bit deeper but you know there's many extension points here as well if you wanted to specify base class that sort of thing you can do that anyway uh i think we're finished with n swag studio now so we'll go ahead and close that down and let's do a build on our project and see if we get that generated c sharp client nothing much happened there that's because i guess um you know it doesn't recognize that that anything's changed because all we did was change that configuration file so we'll do a rebuild here on server and it looks like it's got some complaints about nullable reference types but ensured ran successfully and over here we've got our services folder and our new blazer demo api clients so that's great we'll run into one problem here it's that n-swag the templates that are currently being generated use newtonsoft.json okay and so that's not in this project by default now the they are working on um i shouldn't say they i guess rico is working on system.txt.json but the support for that is experimental at the moment so let's stick with newtonsoft.json which we all know and love so if i jump over to wait a sec where am i yeah that's the right place i'll go to client and we'll go ahead and let net add package shift insert in soft.json that will sort out that error for us great let's do a build solid let's update patch data.razer okay uh where is it here it is especially.razer so first thing we want to do is inject you know what we're going to get rid of http client we won't need that anymore because we didn't want to use that at that low level anyway we'll inject our weather forecast client and we'll call it client save that what's the complaint about http oh yeah of course because i've made some breaking changes so there's our weather forecast client it's been injected uh over here um we have our call to the http client we'll just comment that one out for now and we'll make our own forecasts equals await dot get async ah and that's it right much simpler we have a strongly typed client we're able to kind of explore the methods that are available admittedly there's only two really one um one with the cancellation token overload but as any complicated app builds out you'll be able to go client dot and you'll be able to see all the different methods that are available and understand the api a little bit better easily understand the return types and build your app to suit we can get rid of that one last thing we're injecting this but it's not wired up so let's go back to program.cs and we'll go ahead and builder dot services dot add scoped i weather forecast and and that one there we go so anytime we add a new controller with actions to our api it's going to generate a new client and we'll come in here and we'll wire up that client after which it will be available for use so if we go now to our weather forecast fine well we should be ready to take it for a test drive so we'll control f5 that's the best experience don't worry about that fetch data and it works okay so we're still getting our data back from the server but now it's using that strongly type client which is a much nicer experience if we were to make some kind of breaking change um we're going to be able to detect that really easily as well that's one of the things that i love about this approach so if we remove an action or change in action in some way that makes our client we'll find out very quickly let's get abc let's do this little rebuild that's nice back over to our fetch data just wait patiently there we go it says hey there is no get async method so if we try to build that because this code is the c-sharp code it's just been generated of course it's not going to build any longer um so that's great we'd go ahead and explore it and figure out exactly what went wrong and fix it so that's nice breaking change is really easy to detect which is which is one of the best things about this experience so awesome um i'd like to give you a quick win you know when i'm when i'm building my client applications like this single page apps i always love to have a global loading bar and that loading bar typically reacts to any http requests and so i found a nice little package that we can use for that so let's put that in so if i go shift insert yep.net add package toolbelt.blazer.loadingbar you don't have to remember any of these resources because i'm going to share with you all of these resources and more towards the end of this presentation so go to program.cs and now we've got to wire up the services for the loading bar first things first this uses a kind of interceptor for the http client so i might just clean this up a little bit so it's easier for me to see enable enable intercept i think that's right yeah there we go using toolbar populated extension dependency injection we just pass in the service provider so we can do the wiring up for us and then we're going to say add the service for the loading bar so we'll say builder whoops builder.services.addloadingbar straightforward and then finally we need to um add the loading bar itself so we can just say builder.use loadingbar and we can specify a few different things there's a few methods there um but um such such as the color of the loading bar but but i find that the default color is pretty good for these demo purposes okay uh i think i think that's it oh yeah we do have we do have a problem though um this weather forecast sample it generates the data in in milliseconds like less than 100 milliseconds which is it's just not right um weather forecast data takes time to generate and it takes time to retrieve it from the server so i want to make this task a little bit more realistic so first we'll make it our synchronous am i doing that that's better and then we'll add in an appropriate delay so i'll start a four seconds order do it there we go that's gonna be much nicer that one's finished so we run this so now when we retrieve our weather forecast data i know we're going to be getting the freshest weather forecast every time because we can see that it's taking time to do that and we have this little lighting bar at the top just lets us know that the page is working on something so that's really nice so we're going to get that for all of our http requests which is good i like that approach um and later on you know we'll we can add some additional interceptors perhaps ones that handle globally i say globally for the for the client any common http errors that we might we might get out of those requests so we can add another sorry i want to be on program.cs we can add another interceptor to you know display a toast so say that request to the server failed please try again later that sort of thing so that's going to be nice all right on to the next demo so now we're going to do the to-do app now i know some of you are sick of seeing to-do up demonstrations but to be honest i don't know how you get things done if you don't have a great to-do app i'm always working on improving my to-do up and this one is exceptional in this demonstration we're going to talk about conventions for organizing components we'll talk about the current conventions and you mentioned i think people should be using we'll talk about separating your markup and your code by using code behind and we're going to talk about the ultimate approach to validation for blazer webassembly so client and server validation let's have a look so i've got to switch to a different project that's as far as we'll go with the with the section let me close that one down and we'll clean up a few windows we'll keep it simple right so here we are this one is the same it's just got the to do app demo because i didn't want to build it from scratch because it takes time to build a quality to do upright laser demo solution here we go so the focus is not so much on how i built the to-do app but more so on how i organized it the code behind and uh the ultimate validation experience and and one one more really cool thing which i'll save to the end okay so inside of blazer server we've got some controllers we've got to do list controllers to do items controllers inside of shared we have our entities to do item up to do lists of states and priorities all the bits and pieces i'll be sharing this repo with you of course so you'll be able to explore this at your leisure and uh in the client we have our to do up components now i want to start by just discussing the conventions that you get that are that are kind of proposed out of the box if you have a look at the microsoft documentation so we have this pages folder and there's shared folders and we use those two folders to organize our components the invention is that we'll put our router routable components inside of the pages folder such as index counter and fetch data and our shared components our non-routable user reusable components our building blocks inside of the shared folder and i've tried if you've worked on my development team you know i've tried many different ways to organize components and if you work to my development team you're probably annoyed with how much i've changed things around but happy to say that i've arrived at what i think is is the the best approach for me in terms of working productively on a feature so what i like to do is to create a feature folder and inside of that feature folder i'm going to have a routable component and it's going to be called index.raiser and it specifies the route to do which matches the feature folder so it's very easy for me to go to this directory and say okay this index.razer is going to be at the root of the site so its route is going to match its location on disk and i like that approach it provides me with a logical way to reason about where to find the files and the routes that would be i would expect to be associated with those files now instead of then going to shared and creating a to-do folder and putting all of my shared building block components inside of that folder in shared i keep them right here so this is no longer just routable components it's routable components and feature components these to do items to do list and to do state all contained within the one directory because look if i create a to-do folder over here i'm constantly jumping back and forth between the two to build out this feature in this approach i have everything in the one folder so it makes me it makes it easy for me to work on that feature now i also like to keep the c sharp code out and separate from the markup it's really easy to to to make that work if we have a look at let's say let's do the weather component here we've got uh the client being injected that using statement which we've got rid of in the other demo and we've got the code for for the component if we go ahead and create a weather weather.raiser.cs file um it'll mess it up a little bit but if we delete that we've just got a weather class and if we change that to a partial class that will now be the code behind for this uh razer component and it's a partial class because behind the scenes it's generating a class anyway so let's go ahead and grab this code and pop it in over here let's go ahead and grab these statements i'm in here and instead of using um the app inject directive we'll use the inject um [Music] oh yeah what is it true i was worried that okay that's looking good over here we've got just that one director for the route and we don't have any code behind so we just focused on our markup and a little bit of that razor syntax so i prefer that approach often times when i'll be developing on a component i'll actually put them side by side so then i can see my markup i can work on that and i can work on my code behind and that's quite nice of course there are other approaches and which approach you follow is entirely up to you that's the approach that i like to use and so you'll see within this to-do application we've got code behind for all of those files you'll notice that index.raiser doesn't have any code behind and that's because it's just there for the template the layout it's um organizing uh the different uh different components so you can see for this particular feature i have a to do state so that's a cascading value and to do this which have the cascading parameters so the state is shared centrally here for both the lists and the to-do items we should have a look at this demo we haven't we haven't looked at it yet so i might just start it up here so we jumped into server here we go okay so i've got this url and i'm going to paste this one in yeah here we go here is the amazing to-do app so it's not your regular to-do app okay we don't have a single list here if we want to work with multiple lists we can create a most important task list we can go ahead and start adding items to it it's an important task maybe drink a nice copy lollipops but i get the point there we go so we have a very nice experience for creating lists we can go ahead and create another one and say no we don't need that much work to do so we'll go ahead and delete it that's very nice we've got our default data and we can go ahead and mark things off and add new items and uh yeah pretty works pretty well so the purpose of this this feature um is to demonstrate all of those other things that we've been talking about so we've had a look at the organization of the components and we've also had a look at the code behind but now i want to show you something which i think is really amazing it's the validation experience when i go to create a new list if i hit create of course it says title must not be empty and that in itself is not amazing but one cool thing about it is it's coming from fluent validation and so if we look at shared and i have this to-do list validator i've got a simple little validator here that says the title must not be empty and i also have a little package installed on the client it's called blazer dot fluent validation which provides really nice um really really nice support for fluid validation in blazer because it's not available directly from full invalidation and if we have a look at this to do lists modal you can see the way it works is we're using the blazer edit form and we have this fluent validation validator so a lot of times you know you'll see the data annotations validated we're not using data annotations we're using fluent validation validator and um we've got this little little little property here to disable assembly scanning because if fluent validation validator doesn't find into any validators it will scan the assembly and swap startup but of course i you know i've wired those up um in this application so you can see here we've got this um add validators from assembly containing which comes from fluent validation and so ad actually more specifically it comes from fluent validation dependency injection extensions okay so not not the base um package so that that's pretty important so what it what it then does is just goes and grabs um any validators that are in the assembly that contains this file type or sorry this class it doesn't have to be the validate it can be anything at all um but i just put it as validator because it kind of makes sense so at the moment there's one validator but it'll find any that are contained within that assembly so we get that really nice experience if you haven't seen it before these inline validation rules that's supported by blazer as well and so you can kind of see this validation message has been specified um referring to um the the um actual property that is would would could be an error and so that's really nice i'm not saying that's the ultimate validation experience because it's simply not but look you've seen this fellow data and i want to show you something pretty amazing if i now go and create a new mit list and hit create i get this message and it says title must be unique and you must be wondering where that's coming from because in this validator we don't have that well typically when i'm building applications i have a validation experience on the front end and a validation experience on the back end now in the past i've had to write the front-end validation experience in javascript or typescript and i've had to write the back-end validation experience in c-sharp i use fluent validation on the back end and whatever whatever framework i happen to be using on the front end whether you know it's react or angular or view now it's blazer and i'd have to rewrite it and i have to try and keep them in sync which i eventually ultimately failed to do but they wouldn't always need to be in sync sometimes the backend validation would do more than the front end and so that's what i've done here i've added some additional validation on top of this to-do list validator and so if we go to the back end where did i hide that over here we have this validators folder and there's a new to-do list validator the difference between this to-do list validator it's not implementing abstract validator it is derived from to-do list validator the one that is in shared so when we create this to-do list validator it gets all of these rules from the shared folder and the additional rules that we just want to run on the back end in this case it's we want a unique title and to check that we're going to go ahead and check the database so now we have these validation rules that are shared on the front end and back end and also we have this amazing experience where we're able to extend those rules for running just on the back end and i really love this approach i'm super happy with this but there's one more thing how did we get this new um how did we retain this inline experience even though these errors are as a result of a 400 so if we go and have a look at the network tab and just run that again we've got the problem details response which we've all come to know and love really the validation problem details response and it's returning us this dictionary of type string with a key string and a value of string array so how do we get it into a validation message well it's this little component here and i learned about this from the microsoft docs the microsoft docs for blazer are excellent so definitely worth checking out so this is a custom validation component which is actually part of this project so it sits right there and i'm calling it a component but you're probably wondering why doesn't it end in dot razer um and i thought about that too well this is a component that actually doesn't have any markup um so that and it's and it's a non-routable component so we don't really need the dot raiser um but it is a component just like any other component you can see it's derived from component base um when we created our weather code behind we didn't derive from component based because it's code behind it it's a partial class but we can if we want to and that's a good way to have a look at whoops that's a good way to have a look at some of the things that that you get for free in component base such as these lifecycle events and anything else that's available and also you might want to consider deriving from this class and creating your own component base for your application because there's a lot of powerful things that you can do um across the board across the across the entire client app for your components to make your life easier such as implementing focus or automatically injecting ijs in process runtime or ijs runtime those sort of things um so worth worth thinking about but anyway back to this custom validation component so it has a property validation message store which holds all of the validation methods messages for an edit context what's an edit context well it's the context for this edit form we haven't specified it directly so we're using the default one we've got a cascading parameter because this edit form was also supplying a cascading value and the cascading value is the current edit context which is great so you know those cascading values and parameters are used throughout the blazer framework so it's worthwhile knowing so we have the override for uninitialized and we're basically doing a little bit of sanity check saying hey if you haven't supplied a current edit context then you're probably using this in the way that it's not intended so check all of these things and fix it up then we've got this message store which we're we're basically creating a new validation message store the type is specified on message store and we're passing in the current edit context which is what's required to create a new message store we're create clearing any validation errors sorry we're not clearing any validation errors we're wiring up the on validation requested event from the current edit context so that we can clear any messages before validation starts and we're also wiring up the on-field changed message so when a user changes say the title on the form it will go ahead and clear the message for them so they have that nice validation experience where we're not constantly pestering them with these red error messages that are no longer relevant so we've got some helper methods which will which are public successful we can call display errors and pass in a dictionary of errors such as this dictionary of errors that we get back from this failed request and you can see that we're simply wiring it up with the message store and then we're calling notify validation state changed so that this form knows to re-render and we've got this clear errors helper message so that we can clear the errors before we make a new attempt at submitting to the back end um and receiving a response hopefully everything's okay um once we get that second response through so what else do we need to look at i think that's it i think we've covered it really well so coming over to the to-do list code behind you want to see all of that in action we've got a reference to the custom validation component that's so that we can access display errors and clear errors and then when we go create new list first thing we do is clear the errors then we try to create the list this is where it's likely to fail if it fails here it's going to throw an api exception as per our generated um strongly type c sharp clients if it does throw an api exception it's probably going to have a response which is of type validation problem details so we'll try to grab that if it's not null then we can go ahead and display the errors which are contained within validationproblemdetails.errors and so that's how we get that super nice validation experience and for me that really is the ultimate validation experience as far as blaze is concerned i couldn't be happier with that approach all right what else we're going to cover in this demo one more thing one more last minute thing that i added um when i was when i was making the final preparation for this presentation so if we go to uh program.cs you can see here we're wiring up all of these clients as they're created we only have to do it once but typically i forget to do it and that gives me an error at run time and that's kind of annoying so let's do it a different way we delete that and we'll use a package called screw tool which is installed there it is there and it provides a nice assembly scanning mechanism for us to scan our assembly that contains the i weather client it'll find all the classes in that assembly and it will wire them up with the implemented interfaces with a scoped lifetime so essentially it's doing this automatically for us so that we don't have to do it anymore so next time we create a new controller that um client is going to be automatically available for us so we'll save that give it a quick test before we move on actually i wanted to run it through here oh it's already running enough killed it never mind okay waiting awesome quick refresh and look at that our clients are still wired up and still happening automatically for us which is great so we never have to touch that again and that's kind of a whole big chunk of our application that we don't have to touch again it's the it's the open api specification generation it's the strongly typed client generation it's the wiring up of those clients automatically we basically just write the code now um we put in the effort ahead of time so that we don't have to do that later okay that's it for this demo uh you probably think there's nothing left to upgrade but you're wrong it's one more thing we have to upgrade before we finish up tonight and that's the home page upgrade we need to add some awesome resources you know in the past these templates they had a home page that told us all about the template and they had links to all the greatest resources so that we could go and learn how to build an angular app or a react app or work with razer pages and i really missed that in this template with this template go back to the other project now with this template let's have a look at what we've got so is this my blazer demo i'm working directory yep we can shut that one down now we get only the hello world experience we do get a nice little survey though um that we can fill out to give some feedback to the blazer team so that's great and there is an about link here so that we can get some asp.net core resources but i want the original experience the one that we had in in net core 2.1 and earlier um so i'm going to bring that back so let's do that and of course i'm going to um retrofit it with my own resources that i'm going to recommend um and and another link that will give you every other resource that you might need with blazer so first thing we're going to do is put in a bunch of code that should be nice we'll close that down and then i need to put in some scripts you can look away for this one oh i add this script for bootstrap javascript and now i think we're good to go let's give it a try not quite we're close we're really close we just need some images because all home pages should have some great images there we go drag that across okay click ctrl f5 still broken but i do wrong got the images bringing in the right project let's see all that try one more time all the demos to fail it's funny that it would be this one static content come on yeah there we go so now we have the original experience so we can learn all about visual studio to learn all about azure and we can learn all about asp.net core i've put in my own resources here we've got the application it's using sample pages using blazer theming using bootstrap icons using open iconic open api using enzo validation using fluent validation and of course data access using ef core i promise you data access tonight but that's your homework you're going to have to review the code to have a look at that and if you're interested in building enterprise applications with blazer keep your eyes open because we'll soon be running a new clean architecture superfiles which will have enterprise applications with blazer for resources we've got building web apps with blazer so this is the blazer.net site this is where you can come to get started even if you're completely new to blazer i wouldn't recommend coming here because there is this blazer app building workshop and the blazer app building workshop actually will guide you through the entire process including going to blazer. getting started getting set up and building your first app so i think you should just follow this workshop um to get up to speed with blazer it's really great and you can probably see why if you look at the contributors on this we've got a lot of great people who have worked really hard on this workshop to build us a really nice experience and so yeah definitely definitely worth running through this so what else do we have on our new upgraded home page we've got blazer on asp.net core blog so if we want to stay up to date um that's not it so that's blazer on microsoft docs we need the we're going to have to update that now uh we need let's see over here laser poke that's supposed to be the blog yeah okay so the asp.net core or just the asp.net blog has not that one i should i shouldn't have searched here this is for development okay and if we go yeah oh yeah there we go click on blazer that's the resource that we want so we can see on the asp.net core blog the latest and greatest with blazer um and asp.net core in general so we can see the release notes say for the dot net six release candidate 2 custom deployment layout for bazel web assembly apps just goes on so there's a lot that's where you're going to learn about the latest stuff that's happening um i think that that's probably not right in the template so i'll go ahead and i'll update that soon so what else have we got we have uh this great book blazer webassembly by example it has a lot of great content i can't remember what my favorite parts of it were but let's see we've got uh i liked the js interop section i love the progressive web app sections um the kanban board was really cool i've got to build my own kanban board now um yeah that's a really good book worth checking out i think you can get it um through a trial or five dollars a month through packs so that's that's pretty cool um we've got blazer courses on microsoft learn so there's a couple there this one's interesting i haven't done this one yet blaze uh publisher blazer webassembly app and a.net api with azure static web apps that's pretty cool uh back over here this is an awesome resource carl franklin's blazer train you have to check that out it's just video after video of all topics plays a webassembly blazer server it's just going on and on and it's producing new content all the time um very cool content something i saw today yeah it's error boundary so i gotta check that out okay covered those courses okay some of the packages we use today laser eyes fluent validation tool belt um loading bar and and um so blazer eyes fluid validation is pretty cool we use that for our fluent validation experience there's some other laser eyes packages that you might want to check out and then we've got um the tool belt blazer loading bar there's a another package that we used in a project here which was the shortcut keys i think uh let me see 169 repositories well um let's search toolbelt oh there it is that's the one i'm looking for twoabout.blazer.hotkeys this is a really cool repo if you want to add some hotkeys you're kind of thinking ah we're going to add hotkeys to some kind of html element not at all it actually wires up the hotkeys um to the to the methods in the backend of your component so it's a really nice experience the next thing we want to do is kind of bring it up so that if you can press the question mark to bring up that really cool um little model that you saw um to show what all the hotkeys are for the current component there it is there so that's definitely definitely one to check out um with the with the these blazer component libraries there's so many and i think you might think we're just gonna bring in something like ant blazer um or devexpress and and we're going to be able to build blazer apps really easily and that's true they're going to go a long way to helping you be productive with blazer but something else important these component libraries a lot of the open source ones are amazing learning resources for learning how to work with blazer and the reason that they're amazing resources is because blazer is component driven right components are the building blocks of a blazer application and so no matter what you're building in blazer you need to get really good at building blazer components you need to get as good at building blazer components as the amp placer team or the devexpress team because they're the building blocks that's how you put together your application so you'll be able to build good blocks with a basic understanding but you'll be able to build amazing applications amazing components with a really strong understanding so i'd definitely encourage you to review open source projects even if you're thinking i'm going to build this component from scratch myself because i have specific needs have a look at what's happening under the hood with some of these open source libraries and then build it yourself you'll certainly learn a lot i know i have that's it for the resources let's jump back over to the summary so in this presentation we looked at modern web development with laser web assembly and asp.net core using vs 2022 we examine techniques for managing application and component state using cascading values parameters and session storage using open api and the end swag tool chain we added support for open api and strongly typed api clients we discussed conventions for organization of components and files and i shared my preferences using fluent validation and blazer i demonstrated the ultimate validation experience and finally i shared some amazing resources to help you get up and running with blazer in your next project that's it for this talk but as promised i have the qr code for you so if you downloaded the ssw rewards app and would like to earn some points and eventually earn some prizes scan this code now and you will be able to um grab some points of course this is on youtube so i don't need to wait too long here now if you've got some feedback i'd really appreciate it um i'll build that into the next version of this talk next time i present um hopefully it will be even more amazing than this version i hope you enjoyed it thanks for watching i'm jason hiller ah that was awesome jason thank you for doing that um you're a very well prepared speaker i love watching you um it is obviously sad you're not here in the chapel down here doing this but uh how is it doing it from home i love working from home hey look i have my i have my screen down here just just below my main screen then i've got my screen up there above my other screen i've got my lighting and uh yeah no it's it's nice i'm i'm always happy working from home but you know it has been two years now i would like to get to a user group i miss uh playing pool in the office and eating pizza and and having a few beers so we don't get that here i have to go and read books after this so let's talk about uh your enterprise projects uh how excited are you about uh dot net six and like you know some of the guys uh you know asked jacob he said 11 out of 10 uh some some of the other guys you know pretty excited oh actually even even mehmet was excited so that's good that's it where where are you on the scale of dot net six well i mean i've been using rc2 and earlier versions before it was available through public channels so i've actually been subscribing to the to the to the updates that are available through the github channel and and feeling the pain of trying this early release software so i'm very excited about it um and excited to get up and running with it quickly so that we could use it in our projects especially for the blazer projects getting that hot reload experience um is is really going to be welcome um it's going to help our productive productivity a lot okay um are you going to be going the minimal code route oh you know what um i i i will think about it a little bit longer there's a bit of discussion on on the minimal code route and um you know we're actually we're actually losing a couple of things with this approach um for example steve smith our dallas called out that you know we have really nice ways of supplying configuration per environment with the existing options and that's simply not available with the minimal code route so i think the community needs to spend some time working with this approach obviously the templates need to be updated because some things are using the minimal code approach some things are not so we need to get at least consistent there and i think wait to hear back from the community wait to get some experience using it and then i'll make my decision on that i certainly love these new using their namespace statements where i don't have that level of nesting it also makes me think you know the convention currently is we have our using statements followed by the namespace we need to reverse that now namespace goes at the top of the file followed by the using statement so we see the namespace where we are followed by the using statements the things that we need and then the actual class that we're working on so that's going to be really cool right okay and when you create a new project for a customer on.net six do you need that startup anymore or just oh well that depends if we're creating a project on.net 6rc2 yeah we need the startup because we're not going to do any development without wiring up our nice uh entourage open api um experience right and so we're going to need it for that for the time being at least until nswag upgrades to.net 6. they need to support the minimal templates um and then that's it i could switch to using something like swashbuckle but i prefer n-swag because it's the only tool chain that provides that complete end-to-end experience in one package right okay all right well i think uh you've got everybody on on this almost everyone on the ssw teams using and swag so uh yeah you've probably converted a few more tonight um what are the gotchas in converting a net 5 project to.net 6. well i don't think there really are any i think it's a you know i haven't i haven't done uh a specific upgrade oh actually no i have i've upgraded the clean architecture solution template um just just on a branch it's not released yet um i haven't really run into any major gotchas um you know what pretty much since i don't know net core 2.1 through all the way to five and six it's been pretty painless actually the team always puts together really great release notes um so they'll let you know immediately breaking changes so just be sure to read the release notes um for for for upgrading to.net six and um if there are any breaking changes check your project to see if they exist otherwise i think you'll just be updating the versions of packaging uh packages maybe enabling implicit usings um and maybe enabling nullable by default which is coming in with the new templates um but yeah no i think you'll find it's going to be quite straightforward right okay and even on a very large uh net five project enterprise project do you want me to say it depends because i will say it depends happy to say it i'm just wondering if there's any uh gotchas i know we've had some uh successful migrations but there's plenty more to go yeah but uh if there are some gotchas then we need some patterns for migrating yeah well look i think you know i've tackled the mains ones with the things that we'll be working with um we have our nice fluent validation experience we have a nice open ap experience with nswag so i'm pretty confident that that's going to cover it for the time being um and and obviously i'll i've already upgraded one project to net six so i don't think there's anything major um and just yeah be sure to check the notes um to see for any breaking changes that might impact you okay um when there are in the migration and there's changes to end points do you have any patterns for that uh problem um in the migration changes to endpoints so what is what do you mean like if you're doing a migration and you want some changes to the end points uh at the same time oh okay i see i see what you're saying yeah okay well that's not really relevant um to an upgrade from.net5 to.net 6. so my advice would be do one first and then do the other don't complicate your upgrade by changing the routing at the same time because then you're going to be trying to upgrade trying to fix any braking changes and also figure out what the hell you did to your routing and fixing up your client and that sort of thing so yeah one step at a time keep it simple okay all right uh are you still using uh t4 templates for things no not at all all right go on um nswag uh studio how i know it's popular with us but how how popular is it compared with the other ones well i don't know let's have a look at new uh the nuget packages okay so fire up new get and what i like is the statistics we can see newtonsoft.json is at the top is that the latest is that welcome to auto mapper there's auto mapper so it's there i like that tool too okay but we're here to see the two main packages right and swag and swashbuckle so let's start with ben swag pop that there and then we grab this one you get actually got it okay so swashbuckle has 25 million downloads let's go with this one 132 million downloads and swag has 15 million downloads so you'd say based on that swashbuckle is way more popular than an swag overall but like i said i've used both and i just prefer the end-to-end experience that nswag provides it's one tool that can generate my open api specification it can generate a wide range of typescript clients and c-sharp clients and one other thing it's got the it's got the ms build so i can automate it all um and it also has the tools like um swagger ui and um um redoc and api mundo all in that one tool chain that you can access to use with your projects so yeah i realized that swashbuckle is is much more popular partly because it's also built into some of the net templates now but i still prefer nswag i think it's the right tool for the job right and i guess another point is most of the devs on the team aren't into it so much compared to you because you set it up for them and it's just done once and then it's just part of the build that's it that's it yeah so we we have conversations from time to time about different approaches um but generally people are happy to stick with nswag especially when they see how how nicely it works end to end right have you come across uh refit no i haven't used refit it allows you to find a strongly typed client for your api uh but it doesn't do the generation for you i guess if you want oh yes control or something yeah i heard that i heard some talk about that recently at ssw no i haven't used it i haven't used okay to be honest all of my time goes into i guess three things preparing for presentations working or looking after my kids and and that's it so at the moment i've had my blinders on just focused 100 on blazer um so i haven't had an opportunity to look at anything else right okay well maybe uh you need to free up some time and stop building a to-do app you could start using trello or something no i have to improve my to-do app um you might not have noticed this i'm pretty hard on myself um but i don't have filters to hide the done items um so there's a lot more to be done there so okay right okay now do you like server-side blazer or client-side blazer i like client-side blazer um i think you know when when we first heard about blazer in 2017 the excitement was not around it was around blazer but it was blaze a web assembly right running that c sharp code in the browser that's what i'm excited about and really if i run c sharp code in the blazer that's a way for me to steal cpu and memory from my clients i can't do that if i run it on the server that has to be my cpu and memory that they're using so yeah blazer web assembly is my preference okay all right well that's good uh so tell us about the performance of this like uh this is kind of you know large it's an assembly it's uh i guess it's a bit larger than angular but probably much larger post well i guess it's close to what angular 2 was and we all live with that for a long time angular angular 2 definitely it's lighter than angular 1. yeah no it's much larger and i think um our good good friend developer jk said it best when people need to think about blazer web assembly a little bit differently it's an application that you're loading in the browser and of course applications have a little bit of a load time and so i think when you look at something like say this this blazer train app um by carl franklin um it has this nice little loading um well it's it's it's a tiny little text box but i think we need to build these nice little loading images um to show that hey this application it's a serious application and we want to we we want to let you know that it's loading it's got the loading indicator um and once it starts it's going to be highly performant and so yeah no i think we just think about these applications a little bit differently and just just give make sure that we give the user a nice experience when that application does load and of course there's things that we can do to improve the performance such as compression and those sorts of things so when are you going to fall back to angular or react for projects wow um i will fall back to angular react or view no wait a sec let's reorder that to re to view angular and then react i need for react at the end if it comes up in a client project and hopefully that client project is hey we want to move away from react to blazer um i'd like to help with that because yeah look i have limited time and so when i think about the web frameworks that i want to work with i have great experience with view react and angular but i want to spend most of my time doing blazer right now because that's what i'm interested in so i'm probably not going to fall back unless i was joining a development team and they had massive experience with angular and they wanted to build an angular well of course we're going to build it in angular because that's going to be the most productive approach for that development team yeah so i think i'd be recommending blazer i'm definitely feeling that almost every dev that's touched blazer just wants to keep going because they find it so productive and they go even if there's you know milliseconds uh in in performance difference customers won't notice it and i'm getting it so much cheaper to them and i'm having a nice experience developing it's like being in a messy kitchen with pots everywhere yeah and working in a in a nice kitchen it's clean big bench space you know nice and simple and you can get a lot more done you know so that's kind of it's kind of interesting because that triggers a thought for me you know when we're building in blazer we get our c sharp in the in wherever we want right in this shared folder and that's a that's a really interesting concept especially when you talk it um talk about it in terms of clean architecture and being independent of the ui well that shared project is independent of the ui but it's also used by the client so we can put in those types and those lot and that logic and those validators and those sorts of things that are going to be used by blazer but could just as easily be used elsewhere so if we wanted to to to build a mobile app um it could be using those shared projects as well okay so we have a less what i'm saying is we're we are less dependent on the ui because we don't have to rewrite things like validation and types in the front end which is something that we have to do with angular view and react if you had to develop the same large enterprise app in angular or react versus blazer was to say it's you know an angular react project would take several months of a few devs what time savings do you think you'd end up with on with blazer you want me to say it depends again don't you no it depends it depends on the skills of the development team so you know if we're talking about a development team that's highly skilled in angular and highly skilled in blazer um they're probably going to be faster i would say in blazer um because we get to leverage a lot of that code we get to we get to use c sharp um and and in the in the front end and in the back end um so there's a there's a great amount of code reuse there but if the team was highly skilled in angular and new to blazer it's going to be faster for them to build an angular app at least at first you know we need we need to think about the capabilities of the team and and whether they want to move to basil whether they have a plan to move to blazer um and whether there's someone on the team who can kind of guide that effort i have uh seen even good experiences with node devs and reactives moving to blazer you know yeah that's great yeah it reminds me a lot of when i hear about java developers who move to c sharp and never look back yeah that's right brandon rich is a good example that's it yeah yeah um uh callum just sent me a message and said ask jason uh how hard is it to build a file upload component in uh blazer because i got the very first version of blazer tried to do it was a lot of work i haven't looked at blazer since has improved all right not very hard we've done it for the recent project um but i would just suggest you check out one of the resources that i presented so if we go to blaze or train you can have carl franklin teach you how to build an upload component in blazer um so he'll run you through that very easily so it's not hard at all no it's a very nice experience okay oh that was fantastic thank you so much jason for tonight thank you for all your hard work and giving that to the community it is awesome i uh i really enjoyed i'm sure everyone else did and uh did you use pomodoros to prepare that talk no i used um i i had to use a little bit of procrastination and a little bit of a uh um impede and pending deadline right awesome well that does the job as well yeah so uh thank you very much and uh thank you to all the viewers out there uh it was a great night and i look forward to seeing you next month at the dot net user group cheers [Music] [Music] you
Info
Channel: SSW TV | Videos for developers, by developers
Views: 27,790
Rating: undefined out of 5
Keywords: ssw, software, industry, cutting edge, latest, developments, development, dev, design, functionality, microsoft, windows, computing, computer, advanced, expert, information, knowledge, dotnet, .net, angular, developers
Id: lRYrhj9lwQk
Channel Id: undefined
Length: 107min 27sec (6447 seconds)
Published: Mon Nov 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.