Uploading Files to Blazor - The Blazor File Upload Mini Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this is the uploading files with blazer mini course in this video we're going to upload a file to the server using Blazer server we'll look at how to use the multi-select option how to filter the files by type how to limit the file size and more this video is part of a mini course around uploading files I would encourage you to click on the playlist Link in the description and use it to go through the course in order now if you don't know me my name is Tim Corey and it's my goal to make learning c-sharp easier I have hundreds of videos here on YouTube with more coming out each week I have a podcast answering questions developers have and I provide training courses designed to give you the real world training and experience needed to succeed in today's Marketplace you can find all the resources I have to offer at impcorey.com okay let's jump into visual studio and we're going to start by creating a new project now we've already said we're going to choose Blazer server as our project type because it's the the option we decide to choose now you could choose MVC you could choose API you could choose Razer Pages you could choose Blazer webassembly and all of them will allow file uploads although each has their own quirks about how to do it we're going to choose Blazer server in this course so I'm going to choose the full template note that if you search for a Blazer you're going to find that there's more than one template in fact there's now a blank template which of course is going to wait and the filler's not going to work I mean there we go so it's going to have the Blazer server app also the Blazer server empty app the difference here is if you don't want all of the um the pre-set up stuff all the things that you know the weather uh page the counter page and the other demo stuff you can choose the empty app just note that will also remove the bootstrap 5 styling and all the icons and other things as well so because this is a demo application I want to show you something really quick and easy and not have to do a whole lot of setup I am going to choose the Blazer server app not the empty template but just know if you're going to start a brand new project it might be simpler to start here so we're going to choose this because this is what we're going to do for a demo not for production so we're going to we're going to call this um up upload files app or upload files yeah app and we'll call this upload files uh sln droplet file solution I'll hit next and we're going to use.net7 for this and no authentication we could get into authentication because authentication will be important when you're allowing people to upload files you really don't want to allow Anonymous file uploading if for no other reason than the fact that you can't reassociate the file with a user but there's also some security implications around you know Bots doing it for you and so many other things so we really want to be authenticated but in this demo we're not going to set up authentication and the reason why is because to do so would mean a whole lot of extra work that wouldn't be around actually file uploading it would be around securing authenticating users and verification and and all the rest we'd still probably cut some Corners because it's a demo environment and we don't want to do everything like two-factor authentication and so on that's a whole nother series but for this we're going to do is we're going to stick with no authentication but in the future I'm going to show you we are actually going to simulate a logged in user and that way you can see what would look like so we're going to leave all these the same default and hit create so this will create for us a a simple Blazer server project that will kind of just work in fact let's just verify that because it's always good to verify that your application is working before you start making modifications so that's one of those little Pro tips there that um hopefully won't bite you as it has bitten so many others so here's our our working application we've got the counter page woohoo fetch data you know it's all there it's a simple Blazer server application it works but we're going to do is we're going to focus in on just modifying the index page so we're going to go to the index page and we're going to rip this thing apart all right so we're going to get rid of the survey prompt and the welcome and we're going to say this is the upload demo all right we'll actually change index to upload demo as well or upload demo app there we go and now this is our page okay this is the the basics of what our page should be we're going to um add in our input file and we're going to say for now that's it okay that's all you really need to have an input file now it's not going to do anything we have no place to to save the files yet so and also we're not going to upload just one file we want multiple so this right here says okay this is a file input element but I want you to allow multiple files to be uploaded at once not just one at a time so we're allow multiple files in that one picker but we need to be able to to store these files so let's say a code section and we're going to say private async task and we're going to call this uh load files I think and we're going to say input uh file change event args e so what this is going to do is going to allow us to capture whenever the upload file picker gets chosen so when you are done choosing files you hit OK it's going to trigger this uploaded files so to do that we need to say on change equals at load files so this is now complete we now have a complete file input picker now if you are familiar with HTML you'll know that's not an HTML tag but what happens is this is a Blazer server tag that will get converted over to the proper HTML tag and we'll see that when we run this but we should probably do something with these files so let's do this let's um let's set some things up I'm going to go I want to keep this as as tight and as quick as possible so I want to explain as I go but we're going to create a bunch of code here so let's start with a private long and we're going to say Max file size and this is the size in bytes that the maximum file can be and we need to specify as because if you don't specify a file size then they could upload terabytes of data we don't want that we want this to be limited and so we're going to say that the size limit is three megabytes but you can't just say three because that's three bytes well three megabytes is a very large number we could put in here the actual value of however it's like 3 million um bytes but we're not going to do that instead we're going to do is we're going to say 10 24 which equals one kilobyte so every every kilobyte is 1024 bytes we're going to say times 10 24 because every 1024 kilobytes is one megabyte we're going to say times 3. so this value right here is a constant it's a calculation that's being a constant but because we put it in this format it's much easier to read we've got bytes kilobytes megabytes so now you can see that we've got three megabytes all right again if you wanted to calculate that out and just put that really long number in here you could do so but it seems simpler to do this way and you can also say um uh represents three megabytes okay so if you ever wondered why is three megabytes not just three million it's because the 1024. so there you go all right that's the first thing we're going to do next we're going to say let's create a private int and this will be a Max allowed files where I say three files for now and what this allows you to do is say hey you know what you can't upload more than the maximum number of files if you decide that with your multiple picker you can allow as many as you want well they could upload their entire hard drive as long as each file was less than three megabytes so that'd be a problem if you had you know ten thousand a hundred thousand files being uploaded that might not be what you intend for your server so we're going to say hey let's create a maximum files allowed around limit to three but notice these are all changeable now I could pull these even from the app settings so if you want to do that you could but I'm going to put them right in and hard code them that's fine okay and then I'm going to create a private list of string they call errors equals no what it'll be is this will be a a list of hey anytime you have an error I want to see it so we're going to do is up here we're going to say as if errors dot count is greater than zero then we'll have an H2 it says errors and we're going to have a UL with a class equal to text Dash danger in this is bootstrap 5 class and that's going to be a red text I'm going to say for each uh VAR let's go e in errors we could also say error that will work um we're gonna say Li at error and this will just display a list of the of the errors that are present that have been triggered okay so we're going to capture a list of any errors we occur that occur because we're not going to capture into somewhere else we're not going to do anything more you know Fancy with validation we're just going to say hey capture these errors and put them in a list so with that being said let's start working on our um our list here so we're going to say errors dot clear so first I'm going to do we're going to clear out the error list so we're starting over again loading files so let's clear out any errors that had occurred maybe they uploaded too many files and now we're saying hey wait back off let's start again try it again with one file so we want to clear that error list because we're starting over so now the next thing is we're going to check to see how many files are being uploaded yes e dot file count is greater than Max allowed files well we're going to say errors dot add and let's do strand interpolation here and say error attempting to upload uh e dot file count files but only and let's unpin this here so you can see it but only um Max files allowed files are allowed let's not put an L at the end of that so what this is doing is just saying hey we've got an error here that if you have more files being uploaded then we allow we're just going to put that as an error statement in our list and because this is Blazer if we add something to this list and we have this checkup here it says hey you have the error.count is greater than zero display this what's going to happen is a certainly add this error it's going to display this H2 section with that error we'll see that in a little bit but we're not done yet we also have to return so hey if we're if we're not going to um allow it to go on let's not even continue we're done we're just going to say hey there's an error and we're done but now let's allow the um a thing to continue since we know that we have less than or equal to a maximum number of files allowed so for each VAR file in E dot get multiple files or I say Max allowed files it's kind of a check because at this point we're saying hey you know what I want you to limit to only this number of files all right that's the maximum file count but we've already checked to make sure we're good but we're just going to double check here so with that been the case we're going to do is let's start creating a a place to store this okay so the first gonna do is we're going to create a new file name and the reason why is because well there's a couple reasons first of all we don't want to trust the user if the user puts some text in the file name that might cause a problem with our code or with an insert or something else maybe some file or a file name that's not allowed whatever the case may be we don't want to trust that now you should still also protect yourself in other ways but this is one of those ways that you can protect yourself by not allowing the same file name the other thing is if you're putting a bunch of files in One Directory let's say that you put all users profile pictures in One Directory well if I called my picture picture1.jpg and somebody else uploaded picture1.jpg what happens well you'd have a file conflict you'd have one file overwrite in the other and that's not what you want in most cases so what you want to do usually is rename the files so we're going to do that we're going to rename our files to be something um something new and so we're going to do is say string new file name equals path this is going to provide my Microsoft in the system.io namespace path dot change extension okay so we're going to change the file extension because we want to first path dot get random file name which get random file name is going to get you a random file name but it's going to give you a random file name with a random extension I don't want that I want the extension of whatever they're passing in so I'm going to say path dot get extension of file dot name okay that's a long statement there but what that's doing is it's getting the file they're passing in and saying hey what's the name you provide I want just the extension of that name and I'm going to add on to it the random file name with the extension of whatever you passed it so I trust the extension I'm gonna have the file name we're going to have that be the new file name so that's our first thing we've got a new file name and by the way um you can follow along by typing it I'd encourage you to do that because it is going to help you with that muscle memory but it also sometimes is helpful to watch the first time and then maybe type the second time but you can also use the link in the description to download the source code um you just need to provide your email address and it will be emailed to you um and that way uh you don't have to retype exactly you can try again or test your code so let's quick actions refactoring here um let's try it come on well it's not popping up okay no worries we'll just do it manually I'm going to um put these on new lines let me kind of crunch these down I can't crunch this down as easily because the fact that it's string interpolation but um I kind of could if I did this this is a new feature of of um dot net seven but we're not going to um any ads if you help me um but let's just continue on we'll not worry about this as much Okay so let's continue on and get the path that you want to capture so we're going to capture the path of where you want to store these files um actually it's just string string path equals path dot combine you want to combine a number of different things first of all we want a a starting point we're going to start from we're going to capture that in just a minute and then the next thing I want to combine is this is something that you should consider and that is whenever a logged in user gives you a file that you put you create a folder for that login user and put the file in that folder so we're going to pretend that I'm logged in as t-core this is one of those places where we're doing a shortcut because if you were um you know stamp authentication you would know who the logged in user is but since we're not setting up authentication we don't therefore we're going to pretend it's t chord and we're going to store it there but that would be the place where you would put the logged in user's username and they'll be part of the path you'll see that in just a minute and then we're going to say new file name so this does is path.conbine is it takes it and it combines the path into a full path it's going to try and do it in operating system independent way so that it can do it right for the operating system it's on um but it's going to combine these folders and files into a valid path now this first thing right here we're missing we need to capture something from the configuration which you don't have yet so let's go over to app settings.json and I'm going to say file storage is the name and we're going to give us a path and the path I'm going to give it is I've got a temp folder here we're going to go to storage and storage we're going to store all the files we upload so I'm going to copy that path I'm going to paste it in here notice it escapes out our slash so it creates doubles lashes that's what we want we want to have those double slash results it's escaping it properly so all right that's the initial path for our file storage so now you need to capture that or get that from the configuration which we don't have a way of doing that yet we've not yet brought it in from our source code so we need to inject this eye configuration we'll call it config now how am I injecting this well this depends the injection and where is this coming from well this is part of the base package that asp.net core gives you now I encourage you um here's a little side tip um if you're deciding hey I want to be a Blazer developer learn asp.net core first the actual base learn about the dependency injection what about app settings.json and the five types that it creates and so many other things that are kind of Base to all asp.net core projects and then from there you can add on Blazer and it'll be much easier because these stuff will be kind of baked in already and you understand what's going on so with that we now want to get the value now I could post off into a separate variable but let's do it right in line so we're going to say config dot get value and let's unpin this we have a little more space to see uh get value of type string and we're going to say that the value is file storage and that's the the name of the um the node over here so file storage that's we're going to look for when we say get string so with that it's yelling me because it says hey that could be no because I'm not positive that this exists well I am and we're going to just say exclamation point and saying yes we know this exists we could do a null check on this but it's not the end of the world um so we could you know pull us out make sure it exists or an exception if it doesn't but um we're not going to in this particular case but let's put these on new lines so that it's a little easier to see okay so now we have the path to where that file should go including its file name which is why we're putting it inside the 4-H because that path will change because it includes the file name all right so now we need to do a directory dot create directory and we're going to combine just the first two pieces here uh so we're going to say path dot combine again and we're going to copy just these um these first two things because if we include the file name that will create the directory with that file name it causes with a problem so this way we're going to do is we're going to create a directory that is that root path which by the way is right here storage right but then there's a t query folder which does not exist yet and so make sure that that full path including T query exists since it doesn't it's going to create that directory so again we could probably pull us apart and you know recombine it in different ways to not repeat yourself but there's repetition here is not a big deal so I'm going to leave it alone and keep going if you want to upload files that's the whole point so we're going to say await using file stream FS equals new we're passing the path and the file mode is create okay so we're going to pass in our path which is the entire thing including the file name and where I say hey let's go ahead and create that we're going to create it as a file stream that file stream just just opens up the connections okay when you put values in this stream they'll be saved to this file all right we need to actually use that file Stream So how we do that we say await file Dot open read stream Max file size that's important so say Hey you can only do this to the max file size and then we're going to say copy to async the file stream so we're opening a read stream that's maximum of this given file size three megabytes and we're saying okay I want you to file which is from our for each of the files that you're uploading I want to open a read stream to you and I want to copy you asynchronously to our currently open file stream and so it will save the the data to that file stream where await the completion of that and then we go to this curly brace well what happens at the curry brace well at the curly brace what's going to happen is that we're done and so it's going to close out the file stream because we open it with a using statement so that's important to add that using statement because it's going to properly close the stream when we get to the closing curly brace now so far this is all kind of the happy path it's going to work no problem we're good to go but what if it doesn't work well let's do this let's go ahead actually cut this it's just easiest you can do a just you know right click and say um it's I think it's annotation now nope um I don't even have it on on the um razor pages but there is a way to wrap this with a a try um so but it is just cut out and do a try and we'll say EX and we'll paste in our code all right so that's what the easiest way to put a try cash if you didn't already do that um I should be getting what I did so we now have this code wrapped in a try which means if there's anything goes wrong you know file system doesn't have permission and Etc then it will throw an exception and by the way it's as important your whatever you're running your Blazer server at whatever user is running your Blazer server that the user that has to have permission to whatever directory you're telling it to and when you put this on is or you put this on um you know whatever Linux server whatever hosting system you have nginx whatever um if whatever you put it on that usually does not run under your account it runs under a service account and so that service account has to have permission to whatever directory you're pointing to which is why this could work in development and not work when you deploy it because the fact that your permissions changed because you run and development you're running it under your account and you don't run Services under your account normally so just kind of a heads up there so we don't want to read through an exception here we just want to capture it error dot or errors dot add remember you have that list and we're going to say string interpolation file and we'll say the file name error ex Dot message now there's something that's important here that we're not dealing with and again it's because of a demo purposes but I want you to think through we're going to talk more about this in best practices at the end of this series um or in video 706 of this series um and that is this right here we're using the file.name now we're only using it in a list which is put it on the page as a um encoded and protected but still you need to think very carefully about using the names they give you be careful of that okay normally what I do is I'd probably do some cleanup on this where I would do um some intentional uh encoding of it or you know removing all non um Alpha Characters or alphanumeric characters um something like that to try and protect this from a malicious attack okay in our case we're just gonna put file.name we're trying to keep this simple and working okay so now we've done we've written a lot of code but we now have a working hopefully application so let's run this wait for it to run okay so you got the the page that says hey upload demo let's bring this over and I want to show you something I do have a folder called to upload and it's got some faces in there it's my team um as well as a test text document so let's try to upload those files to D Temp Storage so I'm going to choose and I'm going to say hey go to that folder and there we go and I can choose to upload um let's go and just upload myself for now I hit open and notice what happened on the right we now have a folder called t-core if you open that folder there is a file in there that's my headshot but note that the file name is I40 or OE three gel dot ping well what's that that's our randomly generated name but yet the extension that I chose because notice to upload it says Tim headshot.ping this says something different dot ping but if I were to go back here and upload my headshot again it uploads a second time because it has a different name and that's one of those why that randomly generated name is so helpful because you can actually have multiple files they might say well I want to preserve that file name you could and we'll talk more about that when you talk about uploading a SQL and how to capture some of that information but I recommend that your actual file name be converted to this random um gibberish because that will protect you against duplication now notice also it created that folder called T Corey so let's do this let's delete T C Corey let's choose files and this time we're going to choose um three files these three hit open it's chosen three files we have t query over here we have three files and that text file by the way is a simple and this is a test okay just to show we're we're doing something but it's working again we can delete it or not but let's choose this time all five files it has this error attempt to upload five files but only three files are allowed so there's our error we choose again let's choose just Tom this time and we hit open and now that works and Tom is over in the folder so we've got our multiple file uploads working we have our limit on the number of files and these files aren't very big um we're talking a megabyte and a half for most of them let's look at the um mine's even a half megabyte so let's do this let's limit it to only being one megabyte that's right go back over to Let's close our code out we could have refreshed it but that's um it's easier this way so let's run again and now it's representing one megabyte not three which means that I shouldn't be able to upload my team just just me so if I upload NOAA and open error okay that size is that large that's the size that is the maximum and again this is what we would put our code normally uh let's zoom in here a little bit so you can see it that number so one million forty eight thousand five hundred and seventy six unless you're a kind of a geek you probably don't know that represents one megabyte but when we put in our code 1024 times 1024 times 1 made a little easier to understand and this is again it's 1.5 megabytes roughly but um knowing that is is a little tricky so this now also allows us to limit the file size to only files that are within the range we're expecting so that's kind of the basics of it but let's get a little bit more specific here let's close this back out move us off again and let's say you know what I don't want to allow let's get back up bring up our our storage again I'm sorry to upload and noticeably this text document but we want to only allow you to upload an image for your profile picture and uploading a text document isn't a good profile picture so let's delete the T query again and we're going to only allow ping or jpegs so ping files or JPEG files that's it how we do that well what we do is come here to our input file and we say accept equals and we'll say dot PNG we'll put a comma and say dot jpg and we'll put another comma input dot jpeg okay and you could put as many as you want here but this is going to limit to only certain file types so let's run this again and again I'm not using hot reload but I could um but it's just for demo purposes if I use hot reload I have to move everything off a screen put it back on and just it seems simpler not to for demo purposes so we've got our storage here where it's got nothing in it let's choose some files notice the text document's gone it's still there but what I look for it's not there because the fact that it says hey you can only upload these files so that's our limiter to say hey you know what that's all that's allowed now I could say all files and see that I hit upload and it does upload well so what good was that well the good of it was that it's not a lineup by default however if you want to say you know what no I want to force you to not allow anything but ping files or JPEG files then what you're going to do is you're going to need to validate the files themselves you're going to say hey when you're going to upload the easiest check is first to check to see what the extension is if the extension is not PNG jpeg or jpeg then no I'm not gonna allow you but you'll probably go a little bit further and look at the mime type and make sure that the data matches up with a valid image image file or whatever file you're trying to upload but the easiest thing this the simplest um what's going to solve most of your problems okay the the 20 effort for 80 results is to have this file type here and say we're only allowing this but it's not the it's not a security thing it's just a um a Clarity thing to say hey this is what we're allowing uh so you know plan accordingly okay so that's how you would do that but I want to show you also let's hit F12 here yes open developer tools um don't care the welcome message we want to look at let's pop this out um okay if you don't know how to use developer Tools in Chrome or in Edge I'd highly encourage you to learn how to do that I have a whole course on being a web developer in fact the web developer Master course is focused in web development HTML CSS and JavaScript but a big part of it as well is learning how to use these tools because if here's another Pro tip if you want to be a Blazer server developer or an asp.net core developer or any web developer you need absolutely need to have a good foundation in HTML CSS and some JavaScript because if you don't you will still be able to do a job but you will make significant mistakes and mistakes that are not easily visible at first so I encourage you learn those foundational things it's very very very important part of that is knowing how to use your browser tools so let's look at if we inspect this file upload and let's um now zoom in on this there we go this is what it actually looks like in HTML so we saw it said input file but actually it's an input type and the type is oops the type is file so that's what translates to an actual HTML notice it says multiple here and notice it says accept equals that accept just gets passed right through to this because it's not actually in the Blazer server object input file so instead um it passes it through to the input and attaches it directly there which means you can also apply classes the same way so if we were to let's move this off let's move this off for now and if I were a set now this right here actually both of these just drop right to the input since they're not actually on input file another one you could do the same thing with is class or ID but let's go class so whereas a class equals and we're going to say this is the uh form um form control I believe yep form control this will apply the class form control just like you would with an HTML element and I hit save here it's going to a refreshed page and now we have a different look for our picker so it's a little different um it still works so it's still you grab those three and hit upload um it looks like two of them are too large but um if we you know um if we look actually if we go to the file notice that t Corey is there we actually have three files but two of them are zero bytes and the reason why is because that file stream was created but we had the error and so it closed it out but it's now empty now again here's another Pro tip if you check the file size first then you won't even create the file stream or if you create a file stream and you notice you have an exception you could check to see if that file stream um should or that file should be then deleted so a couple things you can do there but um those are zero byte files the only one that actually uploaded was my face because my face is only half a megabyte so it probably has to do with having less hair so that's you know that's how to view that but also that's how to style these things using that that pass through on the file input anything that the file input does not know how to deal with so it knows how to deal with on change because I got that that's me which because this is a Blazer control but it converts into an HTML control and so it says if I don't know about something like class it doesn't know about class so what it does is it takes the entire element and puts it on the input that it generates on the HTML page so therefore anything that works in HTML will work here so that's why you can Style with class we can put ID on it we can do you know pretty much anything else you would do with a normal HTML control so at the end of the day Blazer is just creating HTML controls so um so that's how to upload a file now we are not done we are not done by far because right now we're just uploading files but how you actually associate that with data how do you say okay this is connected to Tim Corey that's connected to you know Sue storm whoever um we do that by including this file input as part of a form in form upload however if you noticed the on change we ran this this method the upload the files so upload the files right away as soon as you selected them but in a form you wouldn't want to do that you'd want to wait until we submit the form and the form is valid so we're going to see how to do that in the next video I encourage you to come back for that thanks for watching and as always I am Tim Corey [Music] [Applause] thank you
Info
Channel: IAmTimCorey
Views: 5,294
Rating: undefined out of 5
Keywords: .net, C#, Visual Studio, code, programming, tutorial, training, how to, tim corey, C# course, C# training, C# tutorial, .net core, vs2022, .net 6
Id: 9H6hs61UK84
Channel Id: undefined
Length: 43min 10sec (2590 seconds)
Published: Wed Jan 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.