I have recently been working on a C# .NET project. I like the language and framework. My background is in Objective-C, Swift, Python, and others. Now that I have a year’s experience in C# and .NET, I decided Notic Meet would be written in this language. I also now have a friend helping me with the project. Let me explain a bit about what has happened since I last wrote about Notic Meet.
Switching from SwiftUI to .Net is quite the change. Still, due to how busy I was working in C# and then trying to re-learn SwiftUI, focusing on building the project in a language and framework I was rapidly becoming familiar with made sense. It has changed priorities a little such as iPad was the original goal, but now we are shooting to launch a web frontend. A SwiftUI app may follow, or we might opt for MAUI and use that to create native apps for iOS and Android. I have some experience with this, although setting it up will be somewhat of a learning curve.
I created the project in Visual Studio on my Mac a couple of months ago. I created a .NET project using C# that makes the Client, Server, and Shared projects into a solution.
The Client project is the front end. The project uses Razor syntax for the pages with the @code block for defining the C# code that handles the logic and data. As well as using Razor, we also opted for MudBlazor for the UI components. I like the look of MudBlazor, and the bonus is that it provides a quick way to get moving on the front end. I have only created a few simple pages for testing login and registration and a page allowing you to update your profile. However, having worked with MudBlazor for a year, it will enable the project to move more rapidly from my “limited” experience.
The server project in the solution defines the server-side code for the business logic. Here I have defined controllers, services, and some middleware.
The controllers are used to handle incoming requests to the server. I have the UserController setup that defines the register user, get user, login, and a few other endpoints.
The controllers call the UserService, which contains the logic for handling a request from the front end. This is where the bulk of the logic is. We are using MongoDB for the data store currently hosted at DigitalOcean. The services interact with a generic MongoDB class so that any model type can be fetched from the server.
The shared project is used for logic shared with the client and server and is responsible for making the Get and Post requests to the server’s endpoints. Models and Data Transfer Objects are also found in shared given that the server needs to know about them, as does the front end. Shared contains the client services such as ClientUserService.
The process to make an API request and have something stored or fetched from Mongo is quite simple:
- On the client, create a Dto and make a call as follows:
var loginResult = await ClientUserService.Login(loginDto);
Here, loginDto is a class that defines what the Login method needs to be able to process and do what it needs to do.
- In the ClientUserService the Login method is very simple for this case:
public Task Login(LoginDto data) => Post(“user/login”, data);
The lambda operator (=>) creates the Post request to user/login and passes in the LoginDto (called data here). It returns a Task,
- Server side, the Login endpoint picks up the request, does some checks to make sure that there is a correctly formatted email address and password in the Dto, and then calls the user service.
- The login method of UserService uses a Get request to get the user model stored in Mongo. If a user document is fetched then it runs through the logic of logging the user in such as checking the password is correct compared to the password hash. It then returns a result back which eventually makes it to the client that can then look at the response and determine if the user is logged in or if they entered incorrect credentials.
The shared project may seem like it’s adding an extra step in the middle, but moving the logic for making an HTTP request into shared means that on the front end, we need a line of code to make a Login request.
This is the only pattern I know in C#. Others may use the Shared project differently, but for me, this makes sense.
Having models and dto’s in Shared allows me to access them in both the client and server projects. I also do not need to worry about making HTTP requests because all of that logic is in a generic base class that each service can inherit.
At the moment, I have most of the logic written for the base classes, as well as interaction with MongoDB, except for pulling down collections. Although it might be flawed and lacks a data context and some caching, the project is still moving in the right direction.
It has been great bringing a friend on board with this project because now it feels more real and work can advance at a faster pace.
If you have any questions, please feel free to leave a comment below.