WEBVTT

00:00.000 --> 00:05.790
Okay, now that we've got our Cloudinary configuration set up next we're going to create a service so

00:05.790 --> 00:10.680
that we can upload an image via our API into Cloudinary.

00:10.680 --> 00:13.320
So we'll need a package from Cloudinary to do this.

00:13.320 --> 00:16.050
So let's open up a terminal and go to NuGet.

00:16.050 --> 00:18.750
And we're going to look for Cloudinary.

00:19.230 --> 00:22.410
And inside here we need the Cloudinary dotnet.

00:22.440 --> 00:28.170
Just grab the latest version of this and we'll add it into our project.

00:28.740 --> 00:33.030
And once we have this available let's go to our Solution Explorer.

00:33.030 --> 00:38.130
And inside the API let's create or we've already got a folder for services.

00:38.130 --> 00:40.590
So let's create a new service.

00:40.770 --> 00:42.390
And it's going to be a class.

00:42.390 --> 00:45.030
And I'm going to call it image service.

00:45.210 --> 00:51.030
And inside here we need to initialize our Cloudinary settings effectively.

00:51.030 --> 00:59.970
So I'm going to create a private read only variable called Cloudinary or using a type of cloudinary

00:59.970 --> 01:02.850
which we get from Cloudinary.

01:03.060 --> 01:03.330
Net.

01:03.330 --> 01:05.670
So please make sure you bring this in.

01:05.850 --> 01:10.560
And because it's a private variable, the convention is to start this with an underscore.

01:11.100 --> 01:14.340
So we'll have that and then we'll create a constructor.

01:14.340 --> 01:16.470
So we'll say ctor.

01:16.680 --> 01:21.210
And in the parameters here we're going to use our configuration.

01:21.240 --> 01:29.400
Now the way that we access it via our Cloudinary settings that we created over here and added as a configuration

01:29.400 --> 01:34.770
inside our program class is we can use the I options interface.

01:34.770 --> 01:37.530
So we're going to inject I options into this.

01:37.530 --> 01:45.390
And then we specify the type as the Cloudinary settings that we created and we'll call it config.

01:45.390 --> 01:51.120
And then inside our constructor we're going to create a new Cloudinary account effectively in here.

01:51.120 --> 01:54.570
So we'll say var acc for account equals new.

01:54.600 --> 01:56.760
And then we'll specify account.

01:56.760 --> 02:01.050
And be careful here because we do have account in a few different places.

02:01.050 --> 02:03.720
But we've already brought in cloudinary net.

02:03.720 --> 02:06.600
So that's where this is coming from.

02:07.380 --> 02:10.860
And then we need to give this some configuration values.

02:10.860 --> 02:16.440
So inside here if we take a look at the different options we've got for accounts, we can specify no

02:16.440 --> 02:23.520
parameters just the cloud name, the cloud name and a string of the OAuth token or the one that we're

02:23.520 --> 02:24.060
going to use.

02:24.060 --> 02:29.670
The fourth overload here where we specify the cloud name, the API key, and the API secret.

02:29.670 --> 02:34.350
They have to be presented to this method in this order.

02:34.890 --> 02:39.720
Any deviation from this, and you'll start getting errors from Cloudinary when you try and upload an

02:39.720 --> 02:40.290
image.

02:40.290 --> 02:44.970
So please pay attention to the ordering here because that is important.

02:44.970 --> 02:50.580
And inside the parentheses I'll just move this down to the next line and we'll use config.

02:50.580 --> 02:51.900
And then we use value.

02:51.900 --> 02:56.040
And then from here we can get access to our Cloudinary settings values.

02:56.040 --> 02:58.110
And the first one is the cloud name.

02:58.110 --> 03:09.690
The second one is config dot value dot api key, and the third one is config dot value dot API secrets.

03:09.780 --> 03:16.180
And close that with a semicolon, and then we can assign our new account or pass our new account to

03:16.210 --> 03:18.400
the cloudinary variable we created above.

03:18.400 --> 03:22.510
So I'm going to set Cloudinary equal to new cloudinary.

03:22.510 --> 03:25.780
And we'll pass in the account that we have created.

03:25.780 --> 03:31.720
So now we've got access to all of the Cloudinary functionality inside this variable here.

03:31.720 --> 03:38.680
And let's go down and add a couple of methods inside here we're going to have a method to add an image

03:38.680 --> 03:39.520
to Cloudinary.

03:39.520 --> 03:43.210
And we're going to have a method to remove an image from Cloudinary.

03:43.210 --> 03:46.090
So we'll use public async task.

03:46.660 --> 03:52.660
And this is going to return an image upload result we get from Cloudinary.

03:52.870 --> 03:57.730
Net actions and we'll call it add image async.

03:57.730 --> 04:04.960
And we're going to pass to this as a parameter an eye form file type and call it file.

04:04.960 --> 04:07.000
And then open curly brackets.

04:07.030 --> 04:13.390
And if I hover over the eye form file then this represents a file sent with an HTTP request.

04:13.390 --> 04:18.080
So that's how we're going to send the file up to our API server.

04:19.400 --> 04:22.280
And then we'll create an upload result variable.

04:22.280 --> 04:28.160
So we'll save our upload result equals new image upload result.

04:29.030 --> 04:32.480
So that's what we'll store it in when we get it back from Cloudinary.

04:32.480 --> 04:37.730
And then we'll need to check to make sure we've got a file being passed to us.

04:37.760 --> 04:42.290
So I'm going to check to see if the file dot length is greater than zero.

04:43.670 --> 04:49.160
And if it is, then we're going to effectively upload that file to cloudinary.

04:49.160 --> 04:51.860
And we'll use a streamreader for this.

04:51.860 --> 04:58.220
So a streamreader is something that we can use inside this method, but then dispose of as soon as we're

04:58.220 --> 05:00.920
finished with it because it does consume memory.

05:00.980 --> 05:06.170
So we'll use the using keyword so that it does get disposed of after we're finished with it.

05:06.170 --> 05:10.400
And we'll say using var stream equals file.

05:10.400 --> 05:13.760
And then we can use its open read stream method.

05:13.760 --> 05:16.280
And then we need to create some upload params.

05:16.280 --> 05:25.760
So I'll say var upload Params equals new image upload params which we again get from cloudinary and

05:25.760 --> 05:30.770
inside here we can specify the file that we're going to send up, and we'll set this equal to a new

05:30.770 --> 05:39.710
file description, and we'll pass in the file dot file name and the stream as the second parameter.

05:40.430 --> 05:41.570
And we'll add a comma.

05:41.570 --> 05:44.660
And we can specify a folder here and I will do.

05:44.660 --> 05:49.040
And as I use cloudinary for several other projects.

05:49.040 --> 05:53.060
So I want to make sure these go in a specific folder on Cloudinary.

05:53.060 --> 05:57.920
So we can easily locate the images that have been uploaded for this specific project.

05:58.010 --> 06:05.000
And I'll just say Rs dash course for this one, but you can use whatever you like or not even use a

06:05.000 --> 06:05.360
folder.

06:05.360 --> 06:11.390
It doesn't have to be contained inside a folder, you can just upload it without specifying a folder.

06:11.870 --> 06:19.940
And then I'm going to set the upload results that we created above equal to and I'll say await and then

06:19.970 --> 06:29.100
use Cloudinary and the upload a sync method and we can pass in our upload params.

06:30.600 --> 06:35.790
And then below the if statement we can return the upload results.

06:37.110 --> 06:39.210
So that takes care of the image upload.

06:39.210 --> 06:42.690
And below this we'll also have a method for deleting an image.

06:42.690 --> 06:49.710
So we'll use public async task that returns a deletion result.

06:50.490 --> 06:53.310
Again another type that we get from Cloudinary.

06:53.310 --> 06:57.570
And we'll use delete image async for this one.

06:57.570 --> 07:01.560
And in here we'll pass in the string of the public id.

07:01.590 --> 07:08.190
This is what Cloudinary uses as the unique ID for each image uploaded into Cloudinary.

07:08.880 --> 07:11.250
And then we can create some deletion parameters.

07:11.250 --> 07:20.340
So I'll say var delete params equals new deletion params and pass in the public id.

07:21.060 --> 07:24.150
And then I can create a variable to store the result in.

07:24.150 --> 07:31.890
So var results equals await and cloudinary, and we use the destroy async method from Cloudinary and

07:31.890 --> 07:35.370
pass it the deletes params.

07:35.400 --> 07:41.610
And then we can simply return the result, which is a type of deletion result.

07:42.300 --> 07:44.370
So what we have now is a new service.

07:44.370 --> 07:49.410
And like any other service, because we're going to inject this where we need to use it.

07:49.440 --> 07:51.690
We need to add this to our program class.

07:51.690 --> 07:56.190
So inside here let's find it neat and tidy place to put this.

07:56.190 --> 07:58.290
And I'll just add it underneath the payment service.

07:58.320 --> 08:04.950
In fact I'll even copy the payment service and just change this to image service.

08:04.950 --> 08:08.040
And we'll just check our terminal.

08:08.040 --> 08:13.260
And I think I'm just going to restart this because this looks like a mess.

08:13.260 --> 08:19.440
And I doubt that hot reload would accommodate the changes that I've made inside there.

08:19.440 --> 08:24.720
So now that we've got an image service and the ability to upload an image, we need to think about how

08:24.720 --> 08:26.520
we're going to deal with this on our API.

08:26.520 --> 08:30.420
And we'll take a look at creating a photo entity next.
