Introduction
In today’s world managing personal finances is essential.
Most of us have experienced the consequences of poor financial management, whether overspending, neglecting savings, or struggling to keep track of daily expenditures.
As someone who has personally struggled with this issue for far too long.
I decided to take develop IWallet
a C# Web API project dedicated to helping me gain control over my finances and foster healthier spending habits.
As a part of the ongoing C# Web API series, this article will guide you through creating essential components such as models, interfaces, Entity Framework integration, building controllers, and testing the API.
Contents
1.Chapter 1
2.Chapter 2
3.Chapter 3
4.Chapter 4
5.Chapter 5
- API Validation
6.Chapter 6
7.Chapter 7
8.Chapter 8
Prerequisite
- Microsoft visual studio 2022
- SQL
- Net SDK 6.0
- PostMan
Getting Started
Create an ASP.Net Web API Project in Microsoft visual studio 2022
follow the following steps:
Create a new project on Microsoft Visual studio 2022 →Search and Select ASP.NET Core Web API →Click Next →Add your Project Name –Click Next→Configure the .Net FrameWork → Click create
A New Project is created with the following a test project of weather forecast.Clear the Weather forecast Example .
Add Model
The Model Class acts as representation of the data structure.
- Add a new class
DailyExpense
with the following properties:
using WalletAPI.Entities;
using static WalletAPI.Enums.TransactionEnums;
namespace WalletAPI.Models
{
public class DailyExpense :BaseEntity
{
public string TransactionName { get; set; } = default!;
public string VendorName { get; set; } = default!;
public int TransactionCost { get; set; } = default!;
public int TransactionCostCharges { get; set; } = default!;
public ModeOfPayments ModeOfPayment { get; set; } = default!;
public DateTime DateOfTransaction { get; set; } = DateTime.Now;
public Categories Category { get; set; } = default!;
public int TotalAmount
{
get
{
return TransactionCostCharges + TransactionCost;
}
set { }
}
}
}
TransactionName
--> Represents the Name of Transaction Made Example:Shopping,Rent
VendorName
-->Represents the Name of the Vendor where the Transaction is being made Example:Name of Shop, etc.
TransactionCost
-->Amount spent.
TransactionCostCharges
--> Costs Involved during the Transaction
ModeOfPayment
-->How did you pay via Cash,Bank,MobilePayment etc
DateOfTransaction
--> Date payment was made.
Category
--> Category of the Transaction.
TotalAmount
--> The total amount spent on the Transaction (TransactionCostCharges +TransactionCost)
The DailyExpense class inherits the Id from the BaseEntity
class.
using WalletAPI.Entities;
public class DailyExpense :BaseEntity
Lets Create the BaseEntity
class:
- Create a new Folder
Entities
. - Add The Base Entity class.
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace WalletAPI.Entities
{
public class BaseEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column(TypeName = "int")]
[Display(Name = "Id")]
[Required]
public int Id { get; set; }
}
}
Enums
In the model class created above DailyExpense
the properties:
public Categories Category { get; set; } = default!;
are represented as Enums.
public ModeOfPayments ModeOfPayment { get; set; } = default!;
That is why we have using static WalletAPI.Enums.TransactionEnums
in the model class.
`Enums
also known as Enumeration is a way of Grouping Related Constants and they are declared using the
enum
keyword.`
Let's create a new class that incorporates the use of enums:
- Create a new folder
Enums
. - Add class
TransactionEnums
.
namespace WalletAPI.Enums
{
public class TransactionEnums
{
public enum Categories
{
None = 0,
Transport = 1,
Food,
Other
}
public enum ModeOfPayments
{
None = 0,
Mpesa = 1,
Bank,
Cash
}
}
}
Entity Framework
In this project we will use Entity Framework core to map the Entities Created in the Model Folder DailyExpense.cs
to the SQL Server database.
`Microsoft Entity Framework (EF) -->
is an object-relational mapper that enables .NET developers to work with relational data using domain-specific objects.It uses Code First Approach which means developers can define the application data model using C# and EF Core will automatically generate a database schema.`
https://learn.microsoft.com/en-us/aspnet/entity-framework
- Install the
Microsoft.EntityFrameworkCore
library from the Nugget Package manager or from dotnet cli. - Create a new folder
DatabaseContext
. - Add a new Class
DailyExpenseContext.cs
using Microsoft.EntityFrameworkCore;
using WalletAPI.Models;
namespace WalletAPI.DatabaseContext
{
public class DailyExpenseContext : DbContext
{
public DailyExpenseContext(DbContextOptions options) : base(options)
{
}
public DbSet<DailyExpense> DailyExpesnses { get; set; }
}
}
The DailyExpenseContext inherits from DbContext
base class which is a class in the Microsoft.EntityFrameworkCore library.
public DailyExpenseContext(DbContextOptions options) : base(options)
{
}
The constructor takes an instance of DbContextOptions
as its parameter which is used to configure the database connection.
public DbSet<DailyExpense> DailyExpenses { get; set; }
The Entity Framework
library includes DbSet
class to represent the model Entity created DailyExpense
.
Therefore the name of the corresponding database table will be DailyExpenses
.
Configuration of the database
- Create a new database in Msql.
- Configure the database created using connection strings configuration in the
appsettings.json
. - Add Connection string :
DefaultConnection
: that defines the value of the connection string.
Configuration of the DatabaseContext in Program.cs
Register the DailyExpenseContext
as DbContext to make it available for Dependancy injection.
builder.Services.AddDbContext<DailyExpenseContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
The builder.Configuration.GetConnectionString("DefaultConnection")
retrieves the connection string value from the configuration file (appsettings.json) using the key "DefaultConnection".
The retrieved connection string is then passed to the UseSqlServer method to configure the DbContext to use SQL Server with that connection string.
Migrations
Migration in EntityFrameworkCore is the process of updating the database schema to match the latest changes made to the model class.
Install the following NuGet Packages to use Migration.
- Microsoft.EntityFrameworkCore.Tools
- Microsoft.EntityFrameworkCore.Design The Migration involves the following steps.
- Open the Package manager console.
Add Migration command
FirstMigration
is the migration Name and its upto to specify the name that you want.
The Migration Command will add three files to your project Under theMigrations
Folder.Update the Database.
Other Migration Commands.
- Rollback a migration -->
Update-Database -TargetMigration:"{migration_name}"
- To remove a migration -->
Remove-Migration
- To view the migration history-->
Get-Migrations
Data Transfer Object(DTOs)
A DTO is an object that defines how the data will be sent over the network.Learn More on DTOs Here--https://learn.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5
- Create New Folder
DTO's
- Add a New Class
DailyExpenseDto
using System.ComponentModel.DataAnnotations.Schema;
using static WalletAPI.Enums.TransactionEnums;
namespace WalletAPI.DTO_S
{
public class DailyExpenseDto
{
public string TransactionName { get; set; } = default!;
public string VendorName { get; set; } = default!;
public int TransactionCost { get; set; } = default!;
public int TransactionCostCharges { get; set; } = default!;
public ModeOfPayments ModeOfPayment { get; set; } = default!;
public Categories Category { get; set; } = default!;
public DateTime DateOfTransaction { get; set; } = DateTime.Now;
}
}
AutoMapping
AutoMapper -->
AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type. Learn More -->https://docs.automapper.org/en/stable/Getting-started.html
- Install the
AutoMapper
NuGet package using the NuGet package manager or from the dotnet CLI - Create a New Folder
AutomapperProfile
- Add A new Class
AutoMapperProfiles
using AutoMapper;
using WalletAPI.DTO_S;
using WalletAPI.Models;
namespace WalletAPI.AutomapperProfile
{
public class AutoMapperProfiles :Profile
{
public AutoMapperProfiles()
{
CreateMap<DailyExpense, DailyExpenseDto>().ReverseMap();
}
}
}
The code above Maps between the DailyExpenseModel and DailyExpenseDto.
The AutoMapperProfiles
inherits from the Profile class provided by the Automapper.
Inside the AutomapperProfiles constructor the CreateMap()
Method specifies the source type (DailyExpense)
, while the second argument specifies the destination type (DailyExpenseDto)
The ReverseMap()
method is also called on the mapping, which creates a reverse mapping from DailyExpenseDto to DailyExpense.
API Validation
Validation
is the verification and assurance that an API operates accurately and meets the desired behavior. In this project, we will utilize Fluent Validation as a means to enhance the security of the API.
For more detailed information and insights on this topic, I recommend referring to the accompanying article that I have written.
Lets Create the Validator.
- Install
FluentValidation
Nuget Package. - Create a new folder
Validations
. - Add the class
DailyExpenseValidator
.
using static WalletAPI.Enums.TransactionEnums;
using FluentValidation;
using WalletAPI.DTO_S;
namespace WalletAPI.Validations
{
public class DailyExpenseValidator :AbstractValidator<DailyExpenseDto>
{
public DailyExpenseValidator()
{
RuleFor(exp => exp.TransactionName).NotEmpty().MinimumLength(2).MaximumLength(50);
RuleFor(exp => exp.TransactionCost).NotEmpty().GreaterThan(0);
RuleFor(exp => exp.VendorName).NotEmpty().MinimumLength(2).MaximumLength(30);
RuleFor(exp => exp.Category).IsInEnum().NotEqual(Categories.None).NotEmpty();
RuleFor(exp => exp.ModeOfPayment).IsInEnum().NotEqual(ModeOfPayments.None).NotEmpty();
}
}
}
IWallet Interface
An Interface
defines a contract for the behavior of a class. It defines set of methods, properties, or Events that a class that subscribes to it must implement.
The Interface class is Identified by theI
keyword.
Learn more on Interfaces-->(https://learn.microsoft.com/e
n-us/dotnet/csharp/language-reference/keywords/interface)
- Create a New Folder
Services
- Add A new Interface Class
IWallet
using WalletAPI.Models;
namespace WalletAPI.Services
{
public interface IWallet
{
Task<IEnumerable<DailyExpense>> GetTransactions();
Task<DailyExpense> GetExpenseByName(string
TransactionName);
Task<DailyExpense> AddTransaction(DailyExpense
dailyExpense);
Task<DailyExpense> UpdateTransaction(DailyExpense
dailyExpense);
Task DeleteTransaction(string TransactionName);
}
}
This Iwallet
interface declares several methods related to managing daily expense transactions.
Implement IWallet Interface.
- Create a new class
DailyExpenseService
using FluentValidation;
using Microsoft.EntityFrameworkCore;
using WalletAPI.DatabaseContext;
using WalletAPI.DTO_S;
using WalletAPI.Models;
using WalletAPI.Validations;
namespace WalletAPI.Services
{
public class DailyExpenseService:IWallet
{
private DailyExpenseContext DailyContext;
public IFileService FileService { get; }
public DailyExpenseService(DailyExpenseContext dailyContext,
IFileService fileService
)
{
DailyContext = dailyContext;
FileService = fileService;
}
public async Task<DailyExpense> AddTransaction(DailyExpense dailyExpense)
{
var _transaction = await DailyContext.DailyExpesnses.AddAsync(dailyExpense);
await DailyContext.SaveChangesAsync();
return _transaction.Entity;
}
public async Task DeleteTransaction(string TransactionName)
{
var deletedTransaction = await DailyContext.DailyExpesnses.FirstOrDefaultAsync(T => T.TransactionName == TransactionName);
if (deletedTransaction != null)
{
DailyContext.DailyExpesnses.Remove(deletedTransaction);
await DailyContext.SaveChangesAsync();
}
}
public async Task<DailyExpense> GetExpenseByName(string TransactionName)
{
var ExpenseEntity = await DailyContext.DailyExpesnses.FirstOrDefaultAsync(N => N.TransactionName == TransactionName);
return ExpenseEntity;
}
public async Task<DailyExpense> GetTransaction(int Id)
{
return await DailyContext.DailyExpesnses.FirstOrDefaultAsync(T => T.Id == Id);
}
public async Task<IEnumerable<DailyExpense>> GetTransactions()
{
var items = DailyContext.DailyExpesnses.ToList();
return items;
}
public async Task<DailyExpense> UpdateTransaction(DailyExpense dailyExpense)
{
var updatedExpense = await DailyContext.DailyExpesnses.FirstOrDefaultAsync(T => T.TransactionName == dailyExpense.TransactionName);
if (updatedExpense != null)
{
updatedExpense.TransactionName = dailyExpense.TransactionName;
updatedExpense.TransactionCost = dailyExpense.TransactionCost;
updatedExpense.VendorName = dailyExpense.VendorName;
updatedExpense.TransactionCostCharges = dailyExpense.TransactionCostCharges;
updatedExpense.Category = dailyExpense.Category;
updatedExpense.ModeOfPayment = dailyExpense.ModeOfPayment;
await DailyContext.SaveChangesAsync();
return updatedExpense;
}
return null;
}
}
}
This Class provides the implementation of the methods declared in the Iwallet interface
AddTransaction
public async Task<DailyExpense> AddTransaction(DailyExpense dailyExpense)
{
var _transaction = await DailyContext.DailyExpesnses.AddAsync(dailyExpense);
await DailyContext.SaveChangesAsync();
return _transaction.Entity;
}
This method adds a DailyExpense object to the DailyContext
(database context) and saves the changes asynchronously. It returns the added DailyExpense
object.
DeleteTransaction
public async void DeleteTransaction(string TransactionName)
{
var deletedTransaction = await DailyContext.DailyExpesnses.FirstOrDefaultAsync(T => T.TransactionName == TransactionName);
if (deletedTransaction != null)
{
DailyContext.DailyExpesnses.Remove(deletedTransaction);
await DailyContext.SaveChangesAsync();
}
}
This method deletes a transaction from the DailyContext
based on the provided TransactionName
.
It removes the transaction from the context and saves the changes asynchronously.
GetExpenseByName
public async Task<DailyExpense> GetExpenseByName(string TransactionName)
{
var ExpenseEntity = await DailyContext.DailyExpesnses.FirstOrDefaultAsync(N => N.TransactionName == TransactionName);
return ExpenseEntity;
}
This method retrieves a DailyExpense
object from the DailyContext
based on the provided TransactionName
.
GetTransactions
public async Task<IEnumerable<DailyExpense>> GetTransactions()
{
var items = DailyContext.DailyExpesnses.ToList();
return items;
}
This method returns a collection of DailyExpense objects representing all the transactions.
UpdateTransaction
public async Task<DailyExpense> UpdateTransaction(DailyExpense dailyExpense)
{
var updatedExpense = await DailyContext.DailyExpesnses.FirstOrDefaultAsync(T => T.TransactionName == dailyExpense.TransactionName);
if (updatedExpense != null)
{
updatedExpense.TransactionName = dailyExpense.TransactionName;
updatedExpense.TransactionCost = dailyExpense.TransactionCost;
updatedExpense.VendorName = dailyExpense.VendorName;
updatedExpense.TransactionCostCharges = dailyExpense.TransactionCostCharges;
updatedExpense.Category = dailyExpense.Category;
updatedExpense.ModeOfPayment = dailyExpense.ModeOfPayment;
await DailyContext.SaveChangesAsync();
return updatedExpense;
}
return null;
}
}
This method updates an existing DailyExpense
object in the DailyContext
based on the provided TransactionName
.
It modifies the properties of the existing object with the values from the passed DailyExpense object and saves the changes asynchronously. The updated DailyExpense object is returned.
Configuration Of Services
Register the interface,validator ,automapper and DbContext created in the program.cs class through Dependancy injection.
Dependancy injection -->
A software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies
By registering these services in the dependency injection container(Program.cs), they can be easily injected into the corresponding controller or other classes throughout the application
The Controller
A controller in ASP.NET is responsible for handling incoming HTTP requests, performing necessary operations, and returning the appropriate HTTP responses.
To add the controller in Microsoft Visual Studio 2022, follow these steps:
- Right-click on the project in the Solution Explorer window.
- Select "Add" -> "Controller" from the context menu. This will open the "Add Scaffold" dialog.
- In the "Add Scaffold" dialog, select "API Controller with actions, using Entity Framework" option.
- Click the "Add" button to proceed.
- In the "Add Controller" dialog, select the appropriate Model class (e.g., DailyExpense) and the appropriate Data context class (e.g., DailyContext).
- Click the "Add" button to generate the controller
using AutoMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using static WalletAPI.DTO_S.ReceiptPhotoUpdateDto;
using WalletAPI.DTO_S;
using WalletAPI.Models;
using WalletAPI.Services;
using WalletAPI.Validations;
using FluentValidation;
namespace WalletAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class DailyTransactionsController : ControllerBase
{
private readonly IWallet _wallet;
private readonly IMapper mapper;
private DailyExpenseValidator DailyExpvalidator { get; }
public DailyTransactionsController(IWallet _wallet,
IMapper mapper,
DailyExpenseValidator _dailyExpvalidator)
{
this._wallet = _wallet;
this.mapper = mapper;
DailyExpvalidator = _dailyExpvalidator;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<DailyExpenseDto>>> GetTransactions()
{
var expenses = await _wallet.GetTransactions();
var expenseDtos = mapper.Map<IEnumerable<DailyExpenseDto>>(expenses);
return Ok(expenseDtos);
}
[HttpGet("Transaction By Name/{TransactionName}")]
public async Task<ActionResult<DailyExpense>> GetTransactionByName(string TransactionName)
{
var ExpenseName = await _wallet.GetExpenseByName(TransactionName);
if (ExpenseName == null) { return NotFound(); }
return Ok(ExpenseName);
}
[HttpPost]
public async Task<ActionResult<DailyExpenseDto>> AddNewTransaction(DailyExpenseDto dailyExpenseDto)
{
await DailyExpvalidator.ValidateAndThrowAsync(dailyExpenseDto);
if (dailyExpenseDto == null) return BadRequest();
var expenseDtos = mapper.Map<DailyExpense>(dailyExpenseDto);
expenseDtos.TotalAmount = expenseDtos.TransactionCostCharges + expenseDtos.TransactionCost;
var CreatedTransaction = await _wallet.AddTransaction(expenseDtos);
return Ok(CreatedTransaction);
}
[HttpPut("{TransactionName}")]
public async Task<ActionResult<DailyExpenseDto>> UpdateExistingTransaction(string TransactionName, DailyExpenseDto dailyExpenseDto)
{
await DailyExpvalidator.ValidateAndThrowAsync(dailyExpenseDto);
if (TransactionName != dailyExpenseDto.TransactionName)
{
return BadRequest("Transaction Name does not match");
}
var expense = mapper.Map<DailyExpense>(dailyExpenseDto);
var transactionToUpdate = await _wallet.GetExpenseByName(TransactionName);
if (transactionToUpdate == null)
{
return NotFound("Transaction not found");
}
transactionToUpdate.TransactionName = expense.TransactionName;
transactionToUpdate.VendorName = expense.VendorName;
transactionToUpdate.TransactionCost = expense.TransactionCost;
transactionToUpdate.TransactionCostCharges = expense.TransactionCostCharges;
transactionToUpdate.ModeOfPayment = expense.ModeOfPayment;
transactionToUpdate.Category = expense.Category;
transactionToUpdate.DateOfTransaction = expense.DateOfTransaction;
transactionToUpdate.isNecessaryTransaction = expense.isNecessaryTransaction;
await _wallet.UpdateTransaction(transactionToUpdate);
var updatedExpenseDto = mapper.Map<DailyExpenseDto>(expense);
return Ok(updatedExpenseDto);
}
[HttpDelete("{TransactionName}")]
public async Task<ActionResult<DailyExpenseDto>> DeleteExistingTransaction(string TransactionName)
{
string DeleteSucess = "Item Deleted Successfully";
var transactionToDelete = await _wallet.GetExpenseByName(TransactionName);
if (transactionToDelete == null)
{
return NotFound();
}
await _wallet.DeleteTransaction(TransactionName);
return Content(DeleteSucess);
}
}
}
Let's break down the code:
The constructor of the DailyTransactionsController
class receives several dependencies through dependency injection. These dependencies are:
- IWallet _wallet: An interface representing the wallet service.
- IMapper mapper: An interface for object-object mapping.
- DailyExpenseValidator _dailyExpvalidator: An instance of the DailyExpenseValidator class used for validation.
HTTPGet
[HttpGet]
public async Task<ActionResult<IEnumerable<DailyExpenseDto>>> GetTransactions()
{
var expenses = await _wallet.GetTransactions();
var expenseDtos = mapper.Map<IEnumerable<DailyExpenseDto>>(expenses);
return Ok(expenseDtos);
}
This Method retrieves all the transactions by calling the _wallet.GetTransactions()
method asynchronously.
The retrieved transactions are then mapped to DailyExpenseDto
object using the mapper.Map
method.Then the list of DailyExpenseDto
object is returned as the response.
GetTransaction By Name.
[HttpGet("Transaction By Name/{TransactionName}")]
public async Task<ActionResult<DailyExpense>> GetTransactionByName(string TransactionName)
{
var ExpenseName = await _wallet.GetExpenseByName(TransactionName);
if (ExpenseName == null) { return NotFound(); }
return Ok(ExpenseName);
}
It retrieves a specific transaction by its name, using the _wallet.GetExpenseByName
method.
If the transaction is found, it is returned as the response, otherwise a NotFound response is returned.
HTTPPut
[HttpPut("{TransactionName}")]
public async Task<ActionResult<DailyExpenseDto>> UpdateExistingTransaction(string TransactionName, DailyExpenseDto dailyExpenseDto)
{
await DailyExpvalidator.ValidateAndThrowAsync(dailyExpenseDto);
if (TransactionName != dailyExpenseDto.TransactionName)
{
return BadRequest("Transaction Name does not match");
}
var expense = mapper.Map<DailyExpense>(dailyExpenseDto);
var transactionToUpdate = await _wallet.GetExpenseByName(TransactionName);
if (transactionToUpdate == null)
{
return NotFound("Transaction not found");
}
transactionToUpdate.TransactionName = expense.TransactionName;
transactionToUpdate.VendorName = expense.VendorName;
transactionToUpdate.TransactionCost = expense.TransactionCost;
transactionToUpdate.TransactionCostCharges = expense.TransactionCostCharges;
transactionToUpdate.ModeOfPayment = expense.ModeOfPayment;
transactionToUpdate.Category = expense.Category;
transactionToUpdate.DateOfTransaction = expense.DateOfTransaction;
transactionToUpdate.isNecessaryTransaction = expense.isNecessaryTransaction;
await _wallet.UpdateTransaction(transactionToUpdate);
var updatedExpenseDto = mapper.Map<DailyExpenseDto>(expense);
return Ok(updatedExpenseDto);
}
It updates an existing transaction with the specified name. First, the dailyExpenseDto
object is validated using the DailyExpvalidator
.
If the validation fails, an error response is returned. If the validation passes, the dailyExpenseDto
object is mapped to a DailyExpense
object.
The existing transaction is retrieved using the _wallet.GetExpenseByName
method. If the transaction is not found, a NotFound response is returned. Otherwise, the properties of the existing transaction are updated with the new values from the expense object. Finally, the updated transaction is returned as the response.
HTTPPost
[HttpPost]
public async Task<ActionResult<DailyExpenseDto>> AddNewTransaction(DailyExpenseDto dailyExpenseDto)
{
await DailyExpvalidator.ValidateAndThrowAsync(dailyExpenseDto);
if (dailyExpenseDto == null) return BadRequest();
var expenseDtos = mapper.Map<DailyExpense>(dailyExpenseDto);
expenseDtos.TotalAmount = expenseDtos.TransactionCostCharges + expenseDtos.TransactionCost;
var CreatedTransaction = await _wallet.AddTransaction(expenseDtos);
return Ok(CreatedTransaction);
}
It accepts a DailyExpenseDto
object in the request body. First, the dailyExpenseDto
object is validated using the DailyExpvalidator
and FluentValidation
library.
If the validation fails, an error response is returned.
If the validation passes, the dailyExpenseDto
object is mapped to a DailyExpense
object using the mapper.Map
method.
The total amount of the expense is calculated by summing TransactionCostCharges
and TransactionCost
.
Then, the expense is added to the wallet using the _wallet.AddTransaction method
. The created transaction is returned
HTTPDelete
[HttpDelete("{TransactionName}")]
public async Task<ActionResult<DailyExpenseDto>> DeleteExistingTransaction(string TransactionName)
{
string DeleteSucess = "Item Deleted Successfully";
var transactionToDelete = await _wallet.GetExpenseByName(TransactionName);
if (transactionToDelete == null)
{
return NotFound();
}
await _wallet.DeleteTransaction(TransactionName);
return Content(DeleteSucess);
}
This Methods deletes an existing transaction with the specified name. First, the transaction to delete is retrieved using the _wallet.GetExpenseByName
method.
If the transaction is not found, a NotFound
response is returned. If the transaction is Found the message Item Deleted Successfully
is displayed.
Testing With PostMan
Note:
The 200 OK
status code indicates that the request was successful, and the API was able to process it without any issues.
Learn More on Status Codes Here -->(https://learn.microsoft.com/en-us/rest/api/searchservice/http-status-codes)
Add New Transaction
We will create two transactions lunch and BreakFast.
Get all Transactions
HTTP Put
Lets change content of one of the transaction added.
Delete the Transaction By Name
Lets delete the transaction that we named lunch.
Conclusion
While this article has focused on the initial stages of IWAllet's
development, it serves as a catalyst for further exploration in the C# Web API series. Future articles will dive deeper into additional functionalities, such as authentication, data visualization, advanced analytics, and integration with external services.
Your feedback on how I can make this article even better/more helpful is most appreciated!
Thank you for reading❤️️
Top comments (0)