In the previous posting we saw how to create an API to get all the cars in our database. In this posting we’ll look at the remaining CRUD (Create Review Update Delete) operations.
As you may remember, we created a controller named CarController. ASP.NET will strip off the word Controller, leaving us with Car, which we will use to access the endpoints of our API.
An endpoint is just a URL that takes us to the operation we want.
We looked at GetAll, let’s take a look at Get. In this case, we have an id for the car we want, but we want all the details of that car. Simple!
First we need a method in our controller:
[HttpGet("{id}")]
public async Task<ActionResult<Car>> Get(int id)
{
var car = await _carRepository.Get(id);
if (car == null)
{
return NotFound();
}
return car;
}
Notice that next to the HttpGet attribute we indicate that the endpoint will take the id of the car we want
[HttpGet("{id}")]
This means we need to modify the URL to access the endpoint by adding the actual id of the desired record.
The first thing we do is call the repository, passing in the id.
public async Task<Car?> Get(int id)
{
var query = "select * from car where id=@id";
using var db = databaseConnectionFactory.GetConnection();
return await db.QuerySingleOrDefaultAsync<Car>(query, new {id});
}
In the Get method of the repo we create our query, get our connection and execute the query returning the value we retrieved (if any). This is very close to what we did previously.
Back in the controller, we check to ensure that we received a Car. If not, we return NotFound which is a shorthand way of returning a 404 message. Otherwise we return the Car as a Json object. You can see this in Postman:
We’ll issue a Get command passing in the URL, ending with the id of the car we want (in this case 4)
Notice that we get back a 200, indicating success. In the body of the returned Json we get back all the details of the Car. (If you decide to use DTOs you can get whatever subset of the information makes sense):
Post
Adding a Car to the database is quite similar. We need a method in the controller and one in the repo. Here is the controller method:
[HttpPost]
public async Task<ActionResult<Car>> Post([FromBody] Car car)
{
try
{
car = await _carService.Insert(car);
}
catch (Exception e)
{
return BadRequest(e);
}
return CreatedAtAction(nameof(Get), new { id = car.Id }, car);
}
Look at the attribute in the parameter ([FromBody]. This indicates to the API that the data needed to insert this Car will be in the body of the call. The alternative is FromQuery. You can, in fact, use both in one call.
Note: CreatedAction causes a return code of 201, which is what we want. Here’s the body we’ll insert:
When we click Send this data is sent to the API which returns 201 (created) and in the body of the returned data we see the new id assigned to this car
Service Class
Notice that this time, instead of calling the Repo directly, the method in the controller calls into a service class. A service class is a great way to get the logic out of the controller, where it does not belong, without putting it into the repo, where it also does not belong.
Here’s the top of the CarService
public class CarService : ICarService
{
private readonly ICarRepository _carRepository;
public CarService(ICarRepository carRepository)
{
_carRepository = carRepository;
}
public async Task<Car> Insert(Car car)
{
var newId = await _carRepository.UpsertAsync(car);
if (newId > 0)
{
car.Id = newId;
}
else
{
throw new Exception("Failed to insert car");
}
return car;
}
All the logic associated with this insert (e.g., making sure we get back a legitimate id from the repository, etc.) is encapsulated in the service.
This leaves the repository free to just talk to the database,
public async Task<int> UpsertAsync(Car car)
{
using var db = databaseConnectionFactory.GetConnection();
var sql = @"
DECLARE @InsertedRows AS TABLE (Id int);
MERGE INTO Car AS target
USING (SELECT @Id AS Id, @Name AS Name, @Model_Year AS Model_Year,
@Is_Deleted AS Is_Deleted, @Origin AS origin ) AS source
ON target.Id = source.Id
WHEN MATCHED THEN
UPDATE SET
Name = source.Name,
Model_Year = source.Model_Year,
Is_Deleted = source.Is_Deleted,
Origin = source.Origin
WHEN NOT MATCHED THEN
INSERT (Name, Model_Year, Is_Deleted, Origin)
VALUES (source.Name, source.Model_Year,
source.Is_Deleted, source.Origin)
OUTPUT inserted.Id INTO @InsertedRows
;
SELECT Id FROM @InsertedRows;
";
var newId = await db.QuerySingleOrDefaultAsync<int>(sql, car);
return newId == 0 ? car.Id : newId;
}
Rather than having an insert and an update method, we combine that logic into this upsert method. This is a common idiom for database manipulation.
Note: to make this work, be sure to fill in all the fields for a car (or at least as many as you want to have in the Database.
Delete
As noted earlier, we will implement a soft delete; that is, rather than actually removing the data from the database, we’ll just set the is_deleted column to true. This allows us to reverse the action, and make the row not-deleted by simply changing that value to false.
[HttpDelete(“{id}”)]
public async Task<IActionResult> Delete(int id)
{
try
{
await _carService.Delete(id);
}
catch (Exception e)
{
return BadRequest(e);
}
return NoContent();
}
As you would expect, the endpoint takes an id (the id of the car we want to delete). The controller then hands that off to the service, which calls the repository which, in turn, marks that id as deleted:
public async Task<int> DeleteAsync(int id)
{
using var db = databaseConnectionFactory.GetConnection();
var query = "UPDATE car SET Is_Deleted = 1 WHERE Id = @Id";
return await db.ExecuteAsync(query, new { Id = id });
}
If you are comfortable with SQL none of this will be very surprising. The key walkaway is:
Summary
In this post we saw that endpoints are just URLs with (potentially) data in the body of the request. The controller handles the URL and in our case passes the id or other data to the service. The service handles the (business) logic and then delegates talking to the database to the repository.
Book
This posting is excerpted from my forthcoming book Building APIs with .NET and C# to be released next year by Packt.







































Hey there, You’ve done a great job. I will definitely digg it and individually recommend to my friends. I am confident they will be benefited from this website.
Hello there, You have done a fantastic job. I will definitely digg it and for my part recommend to my friends. I am sure they’ll be benefited from this site.
寒鸦守夜人高清版手机在线观看,信念崩塌后重新站起童话冒险明亮治愈镜头语言克制有力细节经得起看希望感在低谷里慢慢亮起寒鸦守夜人高清版手机在线观看
Macksood Urology Urological Services: Generic Cialis without a doctor prescription – Macksood Urology Urological Services
viagra https://macksoodurology.com/ed-medications/ erectile dysfunction pills online
Hey there, You’ve done a fantastic job. I will certainly digg it and for my part suggest to my friends. I am confident they will be benefited from this website.
https://griffinmrzp71787.pages10.com/1xbet-promo-code-for-registration-1x200mix-130-offer-77058243
https://sepharm.shop/# Svenska Pharma
https://mexicorx.online/# order antibiotics from mexico
Right now it seems like Expression Engine is the top blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?
https://mexicorx.online/# order medication from mexico
https://sans-ordonnance.club/# Quand une femme prend du Viagra homme
https://sansordonnance.shop/# Viagra femme sans ordonnance 24h
https://sepharm.shop/# Svenska Pharma
meds from mexico: reliable rx pharmacy – pharmacy in mexico online
https://tituslmgx61605.free-blogz.com/89228174/melbet-new-customer-promo-code-fork777
Right now it sounds like Drupal is the preferred blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?
слоты на реальные деньги с выводом
https://mexicorx.online/# mexican pharmacy prices
https://svpharm.xyz/# kolla blodtryck apotek
Levitra tablet price PrecisionCare Pharm Buy Levitra 20mg online
币圈版的“民间武术团”——名字叫学院,其实是一帮爱好者自己练。Cryptify Hub就是这种画风:没有正规课程,没有考核标准,主打一个“大家一起玩”。社群里有人分享工具链接,有人讨论行情,有人吹水。作为社群型品牌,它的生命力在于活跃度,而不是权威性。所以用它找链接、参与讨论都可以,但别把它的话当圣旨。民间组织嘛,听听就好。
一个有趣的观察:币圈里最坑人的往往是那些热情洋溢的“导师”。而Cryptify Hub这种一句话不多说的网址大全,反而安全——因为它不怂恿你做任何事。它只是把工具链接放那里,你自己看着办。在这个充满噪音的圈子里,安静本身就是一种美德。
https://bluelinepharmacy.shop/# BlueLine Pharmacy
BlueLine BlueLine BlueLine
excellent points altogether, you simply received a new reader. What could you recommend about your post that you made a few days ago? Any certain?
constantly i used to read smaller articles that also clear their motive, and that is also happening with this post which I am reading here.
I like the valuable information you provide in your articles. I will bookmark your weblog and check again here regularly. I’m quite certain I will learn many new stuff right here! Best of luck for the next!
Вывод запоя в клинике Сочи: лечение алкогольной интоксикации, капельница, детоксикация, помощь нарколога на дому и в стационаре круглосуточно, анонимно
Получить больше информации – вывод из запоя цена в сочи
I am curious to find out what blog platform you are using? I’m having some minor security issues with my latest blog and I would like to find something more risk-free. Do you have any recommendations?
pharmacy wholesalers canada: reputable canadian online pharmacies – Easy North RX
звоните круглосуточно по телефону горячей линии клиники: наши специалисты готовы оказать необходимую помощь в решении проблемы алкогольной зависимости.
Подробнее тут – http://vivod-iz-zapoya-sochi22.ru/
Hello are using WordPress for your blog platform? I’m new to the blog world but I’m trying to get started and set up my own. Do you need any html coding knowledge to make your own blog? Any help would be greatly appreciated!
Easy North RX: canada pharmacy online – canadian pharmacy world reviews
https://mexicaredirect.com/# reliable rx pharmacy
https://www.foriio.com/xbetbestcode2
mostbet qeydiyyat add??mlar?? az??rbaycanca
http://fleximedsindia.com/# mail order pharmacy india
whoah this blog is great i like reading your posts. Stay up the great work! You already know, a lot of persons are looking around for this information, you could help them greatly.
https://mexicaredirect.com/# MexiCare Direct
Excellent post! We are linking to this great content on our site. Keep up the good writing.
https://keragenix.com/code-promo-1xbet-pour-bonus-vip-de-130-e/
real canadian pharmacy: Easy North RX – Easy North RX
canadian pharmacy online store canadian pharmacy store official website pharmacy rx world canada
References:
Rivers casino chicago https://annieiges553676.atualblog.com/48249145/casino-of-gold-dein-ultimativer-guide
References:
Casino tropez https://doodleordie.com/profile/coltgum46
https://fleximedsindia.shop/# Online medicine order
References:
Lord of the rings slot machine https://500px.com/p/sejersendujparker
References:
Harrington casino https://boardgameswiki.site/wiki/Offizielles_Casino_Deutschland_2026
References:
Slots machine https://leaqghr834706.blogsuperapp.com/42104548/casino-of-gold-dein-ultimativer-guide