How to Create Photo/Image Gallery Using C# Asp.Net Core 5 Mvc, Cloudinary  and Auth0 Api
Published: 2021-10-16 09:52:22

**Table of Content**
- Introduction
- Required Tools Needed
- Setting Up
    - Cloudinary Account
    - Visual Studio
    - Auth0 Account
- Coding Proper
- Test One
- Adding Cloudinary Credentials to the  Project
- Test Two
- Test Three
- Test Four
- Cloudinary Check
- Adding Auth0 to the Project
- Test Five
- The End

 We are going to build an image or photo gallery using Cloudinary Api as the remote image server, Auth0 for authentication with C# Asp.Net Core as the backend technology. This project is aimed at providing a working tool for human right activist by automating image upload process as they embark on their work in difficult and hazard situations. The users of this tutorial must have some proficiency in C# technology.

**Required Tools  We Need**
1. Sign up with Cloudinary
2. Get Visual Studio 2019
3. Sign up with Auth0
4. Note pad
5. Sql server

**Setting Up**
Cloudinary Account
 
The first thing to do is to sign up on Cloudinary here https://cloudinary.com/documentation/cloudinary_get_started so that we can get access to the required Api for image upload.
Upon successful sign up, the following are automatically generated for you:
Cloud name:
API Key:
API Secret:
API Environment variable:

So click on the account settings section to see what your Api key, Cloud name and Api secret are. Copy out this values and keep it in your notepad.
Since we intend to use Cloudinary within a DotNet application, we will rely heavily on this Cloudinary documentation for DotNet https://cloudinary.com/documentation/dotnet_integration.
At this moment, this would be all for Cloudinary. Next we set up our coding environment.

**Setting Up**
Visual Studio
The IDE for this project is visual studio 2019, so open your browser and go to https://visualstudio.microsoft.com/downloads/ click on Visual studio 2019  and download the community version.
Installation and set up procedure for the visual studio 2019 can be found here https://www.tektutorialshub.com/visual-studio/how-to-download-and-install-visual-studio-2019/
Launch the newly installed app and select create a project and select Asp.Net Core Web Application Net 5 as the version. Lets call the name of this project  ImageGallery.

![new projectScaffold test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mh4jrcze73ymq04d969g.jpeg)
Fig 1.0
Run the project to ensure everything is fine.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gnnwgmrvmat6f9n3jk1.jpeg)
Fig 1.1
You should see a web browser fired up automatically similar to this shown below:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bq7u527hkt7fgb8ivnaz.jpeg)

Fig 1.2
Go to the Url section of this page above and now copy the text written there. This should be similar to this  https://localhost:44375/ . This value will be our call back Url which will be used much later in the project. For now just save it inside your notepad:
**Setting Up**
Auth0 Account
 
If you don’t already have an account with Auth0, the first thing you have to do us is to sign up for    free by using this link https://auth0.com/ click the sign up button to sign up and follow the prompts.
Choose a Region where you want the app to be hosted then click the Create account button.
Next click on the link written “Create Application” it is similar to the figure below.

![Auth0 setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dyin28g02xw4ssrzz6gj.jpeg)
Fig 1.3
The Auth0 service will ask that you supply the following values such as :

- Name:  This is asking you to fill in the name of your DotNet application
- Application Type:  Select the type of application you want to build
- What Technology are using to build your project :Select Asp.Net Core v3

 A client Id number will be automatically generated for you, copy this and paste it inside the notepad.
![Auth0 setup 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gqytk3aw34gh718sp43c.jpeg)
Fig 1.4

Next you have to make Auth0 to be aware of your Asp.Net app, by clicking the Settings button in the figure above.
![Auth0 setup 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8vbpmub3fgria2wdtwrg.jpeg)
Fig 1.5

Copy and paste the following parameters Name, Domain, Client Id, Client secret which were automatically generated for you into the notepad document above.
Scroll down to the Application Url section of the settings, copy the call back Url from the notepad  and paste this into the “Allowed Call Back Url” box and then attach  /callback at the end of the text.
Next we also copy and past the call back Url into the “Allowed Logout Url”
![Auth0 setup 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06kibe69kie23zp9c4ql.jpeg)

 Fig 1.6
Let’s quickly have a snap shot of what we have in our notepad file
![Notepad cross section](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/alw5sjk2t1751s8iwto9.jpeg)

Fig 2.0

**Coding Proper**
We will return now to the visual studio and start proper coding for the project.
Right click on the solution file and click add new project. This will take you to the same screen where we selected the type of Asp.Net core template that we chose initially.
Go to the search box and type class library and select Class Library (.Net Core), name this SimpleImageGallery.Data
We need one more class library so repeat the process a second time but this time around, we will call the name of this class library SimpleImageGallery.Services. 
![Project arrangement](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h6cejvaxctlwx26x2hc0.jpeg)
Fig 2.1
We will refer to SimpleImageGallery.Data as the Data layer. This layer will handle all data access issues such as entity model classes, database class , Migration files etc.
We will refer to SimpleImageGallery.Services as the Service layer. 

**Project  Referencing**
 
Now we need to make the three separate projects above communicate with each other.
Starting from the ImageGallery project, click on dependencies, add SimpleImageGallery.Data and  SimpleImageGallery.Services respectively as dependencies.
Now move to the  SimpleImageGallery.Services project add SimpleImageGallery.Data as a dependencies.
Now right click the data layer and add a folder, name this folder Models,  add a class, to the Models folder name this class GalleryImage.cs
**Entity Models**
{% gist https://gist.github.com/dyagzy/4c158f743e6f3f4cb761bae7525e242d %}

We add another entity class Image tag

{% gist https://gist.github.com/dyagzy/1a4b4f614066cd7f0929cfe56b8bea17 %}

Right click on the web ImageGallery project and select ManageNugget package.
add Microsoft.EntityFrameworkCore.Design as dependency.

**Database Context**
Next we need to add the Database context class lets call this class SimpleImageGalleryDbContext.
The SimpleImageGalleryDbContext will represent our data access class i.e. the class via which we can talk to the database.
Add the following nuggets packages as dependencies.

![nuggets packages](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6w47l9s1tz4jliu71u2.jpeg)
Fig 2.2
We will add three different packages below to the data access layer one after following the process above.

1. MicrosoftEntityFrameworkCore (5.0.10)
2. MicrosoftEntityFrameworkCore.SqlServer (5.01.0)
3. MicrosoftEntityFrameworkCore.Tools (5.01.0)

Add DbSet properties to the SimpleImageGalleryDbContext  and initialize it with the code as written below.
 See the snippet below:

 {% gist https://gist.github.com/dyagzy/48d1ee760bdacb3bc2e5cb35bb7e491f %}
**Migrations**
Return to the ImageGallery project i.e., the web project and open up the appsettings.json file
![appsettings 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/blua4mrkr4eudc2wmgte.jpeg)

Fig 2.3
We need to add connection strings to the appsettings.json file
Just before the "AllowedHosts": "*" add the your connection strings.
 {% gist https://gist.github.com/dyagzy/a64182bf308d6ccddb76c6968af0bfe3 %}

Now we have to register the Sql server in the StartUp class. 
{% gist https://gist.github.com/dyagzy/18c31e00bf1fc266c2fe848442aa01da %}
 
Now we are all set to run our migration
 Select Package manager console and type the command below Add-Migration firstMigration press the enter key.
![migration cmd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ljy9tdv8ii7r82c6kay1.jpeg)
Fig 2.5
Next enter this second command Update-Database at the PM> prompt and press enter.
 Open your Sql server to confirm that your new database has been created there.
![database cross section](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5331l1uwvrtjmzf7rnzz.jpeg)
Fig 2.6
Now lets go over to the Web app project (ImageGallery) open it and add a class to the models folder there. Lets call this class UploadImageModel

 {% gist https://gist.github.com/dyagzy/ce1345059401a67510b8df673132ec0f %}
Next we will add another class to the models folder and name it GalleryIndexModel. The GalleryIndexModel will have two properties as shown below.

 {% gist https://gist.github.com/dyagzy/cf73b92dd658f01ac4bfc88ce4c3fbf7 %}
 
Next we will add another class to the models folder and name it GalleryDetailModel. The GalleryDetailModel will have five properties as shown below.

 {% gist https://gist.github.com/dyagzy/594ee062a403a9e9c9081637cd6496db %}

**Interface  Declarations**
Right click on the Data layer project and click add a class name it IImageService.
Copy the following codes into this interface class

 {% gist https://gist.github.com/dyagzy/7162fb9bd54d62a9833a6949d5c30eef %}

 Head over to the Service layer, add a new class which will implement the IImageService.
Create a constructor of the ImageService class and then inject an instance of  the SimpleImageGalleryDbConetx class.
![constructor injection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yw9o3y59mutr34fuy5hu.jpeg)

Fig 3.0
Copy the codes below as shown below
 
 {% gist https://gist.github.com/dyagzy/7250899ad69e3277496da85ecc4694bd %}
       
The GetWithTag is similar to the GetById method except that it returns the images alongside the tag description of each images.
 
**Views**
Return to the web project , right click on the Views folder and add another folder name it Gallery.
Add a file to the folder call name it Index.cshtml

![empty views file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1z7e1pqn1b1j3pc4tju.jpeg)

Fig 3.1
 
Delete all the text in fig 3.1 replace with the codes below.

 {% gist https://gist.github.com/dyagzy/f1d83e1f3760edab0479be8f433dca16 %}
 
Also, right click on the Views folder and add another folder name it Image then add a new view file call it  UploadImage.cshtml
![empty views file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1z7e1pqn1b1j3pc4tju.jpeg)
Fig 3.2

 {% gist https://gist.github.com/dyagzy/489d15853d29299a8e01db46e439e8e4 %}

The code above basically helps to create a form with a minimalist styling  for presenting an image on the  browser. 
**Controller**
Add a new controller to the controller’s folder name it GalleryController. Inject the Image service as a constructor injection into this controller

![controller injection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jk2wg0ptcayvrm0oozac.jpeg)
  Fig 3.3
Next we write the Http action method and name it Index

 {% gist https://gist.github.com/dyagzy/b748802c0c538f325de9a93ba9ce8fc8 %}

**CSS Styling**
Open the wwwroot folder in the web project, click the CSS folder and  double click on the site.css file to open it.
This file already contains the basic CSS styling that is used to render the default Asp.Net core Mvc page when the project is run, we will only modify this file to accommodates the changes that we want to see whenever the Upload.cshtml file is rendered on the browser.
Add this code below to the site.css file

 {% gist https://gist.github.com/dyagzy/45e28679680b931f4c9e3beebecd2c05 %}
 
 **Add Upload Button**
Next we need to add an upload button to the navigation bar so that we can begin to upload images to the database
To do this, open the _Layout.cshtml file located in the Shared folder. When this file is opened, it already contains some default codes used for rendering the layout.

![default codes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/132xd8q846rtj9xd224d.jpeg)

  Fig 3.4
Identify the portion of the _Layout.cshtml that has the code similar to the one below then delete

 {% gist https://gist.github.com/dyagzy/40abe930146be3e05f9bfddcfded51ec %}
Paste this code below to replace the code you had just deleted above
 {% gist https://gist.github.com/dyagzy/ff745c8b664755d037269add4e7b9a01 %}
 
Lastly, before we test our application, go to the Startup class and lets modify the Mvc route.
![add routing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mg85e3qdk6mzzk361h2m.jpeg)

 Fig 3.5
Locate the  app.UseEndPoints method and it should look like what is above.
 {% gist https://gist.github.com/dyagzy/aaf90e0d62fc63766e2f6e47be120e58 %}

 **Register Interface Service**
Now we need to register the IImage interface class in the StartUp class by adding the snippet below.

 {% gist https://gist.github.com/dyagzy/c4b57556439ad9f77532e23b520286a9 %}

**Test One**
Run the app, you should see a web browser similar to this below
![added upload button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6oydbdw07hg26vlr20m.jpeg)

  Fig 3.6
If you have a similar web browser as shown above then you should congratulate yourself, else, try to go over the steps above a second time so as to trace where you missed out.
Now you can see the Upload button has been  successfully added but when the Upload button is clicked, we get a 404 page not found error, so lets  fix this.

**Image Upload Service**
To be able to use the  Cloudinary service in our project, we need to have an interface that will hold the implementation of how we want this Cloudinary Api to function within our application. So return back to the Web project, right click to add a folder name it Infrastructures.
Add an interface class to the Infrastructures name it ICloudinaryImageUpload.cs. Inside this interface class add the code snippet below.

 Task<string> UploadPicture(UploadImageModel model);
 
Add another class to the Infrastructures folder name it CloudinaryImageUpload.cs. This class has  to implement the ICloudinaryImageUpload interface 
![cloudinary class](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qzuf7i0j4yq2ei1ei2ia.jpeg)
 Fig 4.0
 **Adding Cloudinary Credentials to the  Project**
Now we need to add the Cloudinary Api credentials that we got upon sign up into our project. We can hide this in the appsettings.json file. Now open the appsettings.json file and add the following code snippets as a json object.

 {% gist https://gist.github.com/dyagzy/de4f427d7744aafde113cd9b7ed7c2d2 %}
![appsettingCloudinary](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60olvycfmcpeaep0o6v2.jpeg)

 Fig 4.1
  Go to the CloudinaryImageUpload class and add the Cloudinary credentials to this class as a private properties
 {% gist https://gist.github.com/dyagzy/6c3a813479673fe2bd075d24a7312ef6 %}
Right click on the web project and add the nugget package for Cloudinary add Cloudinary.DotNet as a dependency.

![Image Cloudinary sdk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h152mggsm7770p0dsqoz.jpeg)
  Fig 4.2
Next we initialize all the private properties of the Cloudinary Api credentials  as shown below.

  {% gist https://gist.github.com/dyagzy/a254c7388966aa7bd77555e8f35390e9 %}
 
Now lets write the logic that will expose our application to the remote Cloudinary service 

  {% gist https://gist.github.com/dyagzy/c6125c6e6b40083a93ff526090a509ff %}

We will write a small private function to handle passing in tags  when uploading images for us and then call it in the method above see code snippet below

  {% gist https://gist.github.com/dyagzy/a49e1013b3e6fad64b1604bb33f0a0dd %}
We are done setting up the logic that will expose our application to the Cloudinary Api in the remote server.
Create a constructor of the ImageController and inject the ICloudinaryImageUpload interface service.

![ImageController](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97q97mtgd7l9bqhk8byd.jpeg)
  {% gist https://gist.github.com/dyagzy/a49e1013b3e6fad64b1604bb33f0a0dd %}
We are done setting up the logic that will expose our application to the Cloudinary Api in the remote server.
Create a constructor of the ImageController and inject the ICloudinaryImageUpload interface service.

![](https://paper-attachments.dropbox.com/s_130D4051B20D7BD1D4482FD2BC142C23536ED27B806A3AC41882727210A27051_1632931700719_ImageController.JPG)

   Fig 4.3
 Inside this controller class, we need two methods, the first will handle a Get Http action while the second will handle the POST Http action respectively.

 {% gist https://gist.github.com/dyagzy/1c6a63f702dc5eefc745da321bda27f1 %}
So lets quickly talk through what is happening here.
Lastly, we return a redirect to action response which basically is to take the user back to the home page where he or she could see the newly uploaded image.
We are all set and ready to run a second test of our application to see how far we are doing or not.

**Test Two**
Run the application and click on the Upload button, you should see this exception shown in fig 4.4 below.
 
See the figure below
![exception page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/id3jjji7ri5vw525g0cw.jpeg)

Fig 4.4

 What the exception is saying is that we need to register the ICloudinaryImageUpload in the configure method of the StartUp class.
Now go to the configure method of the StartUp class and register the above Interface as a Scooped service  using the codes snippet below:
services.AddScoped<ICloudinaryImageUpload, CloudinaryImageUpload>();
 
Your code should look like the image below
![StartUp class](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drnbwwqi4zqzwmx7e4je.jpeg)

 
Fig 4.5
 **Test Three**
Now we are ready to  test our application again to see how we are doing.
Run the application and then click the Upload button.
![Image upload viewPage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c0jbs278z99mq3whwuq9.jpeg)

  Fig 4.6
 Fill in the  boxes, choose any image from your local machine and then click submit.

![EndSars Aisha](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xucliq2axnfolp29rgl8.jpeg)

  Fig 5.0

**Test Four**
For test four, we simply want to confirm that our uploaded images are stored up in the Cloudinary server and also on our local database.

**Local DataBase Check**
So lets check the database first,
Launch your Sql database, navigate to your database and open the GalleryImages table to check
![database 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqxba1xxzlpv2kd5yent.jpeg)
  Fig 5.1
    
  Just pay attention to the  Url of the last two images, we can see the Url path to the images we uploaded to the Cloudinary server  sitting right there on our local database. You can copy this Url and past it into your browser to see the exact image.
 
**Cloudinary Check**
Next login into your Cloudinary account on the browser, click the Media Library button and you should see  the uploaded image here.
![Image cloudinary 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w5nxobfwzwxauxizi4m2.jpeg)
   Fig 5.2
![EndSars Aisha](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xucliq2axnfolp29rgl8.jpeg)
Fig 5.3
   
At this point we are 85% done with our project.
Now  we need to configure authentication.
**Adding Auth0 to the Project**

We will use the  Auth0 authentication Api, which we have already signed up for at the beginning of this tutorial or you click here
The first thing we have to do is to add the Auth0 credentials i.e. Domain, ClientId, ClientSecret to the appsettings.json file
See the figure below

![Auth0 cred](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jb9n5owp0yf0tpvwa1av.jpeg)
  Fig 5.4
   
The next thing we will do is to go to the Web project and add the necessary nugget packages we need in other to be able to use theAuth0 authentication Api.
Go to the manage Nugget manager window and type this
Microsoft.Asp.NetCore.Authentication.OpenIdConnect, then install it.
Then we will follow the Auth0 DotNet documentation 
[here](https://auth0.com/docs/quickstart/webapp/aspnet-core)

  {% gist https://gist.github.com/dyagzy/4e4b038a6320e313034330071961c895 %}

![AddScopped](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1sbv9k9rhvnzq2bqvky.jpeg)
  Fig 5.5

  {% gist https://gist.github.com/dyagzy/009411f6fae66e533b9886008ff3a825 %}
 
 Click [here](https://auth0.com/docs/quickstart/webapp/aspnet-core/01-login#configure-your-application-to-use-auth0) to learn more
 
 **Test Five**
 
 Launch the application again and click on Login button.
 It should take you to the Auth0 login page see below.
![Auth0 login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ce0rmjdnuep6ll1qem7.jpeg)
Fig 5.6
 Provide your username and password that you had used to sign up on Auth0 then click on Continue.
 
 At this point we are sure that our application is working well.
 But at the moment when a user clicks on the Upload button , the user is able to upload images immediately without login in into our application. This is not supposed to be so. The ideal situation is such that a user must login first before he or she could be allowed to upload an image.
 
 To fix this, we return back to the ImageController and then add the Authorize attribute on the Upload action method see Fig 6.0 below.
![Authorize Annotation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hza6sp6l54jxtvmut01j.jpeg)

 Fig 6.0
Test the application again by clicking on the Upload button and then the application should immediately direct you to the Auth0 login page as above.

This is the end of this tutorial.

Please drop me comments, questions, let me know about what you are building with what you have learnt.
The entire code can be found [here](https://github.com/dyagzy/EndSars-Image-Album/tree/master)
Thank you for your time.
Content created for the [ Hackmamba ](https://content.hackmamba.io/) Jamstack Content Hackathon using [ Auth0 ](https://auth0.com/)and [ Cloudinary](https://cloudinary.com/)