.NET APIs Part 5 – All the CRUD APIs

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):

{
    “id”: 4,
    “name”: “subaru impreza”,
    “mpg”: “16”,
    “cylinders”: “8”,
    “displacement”: “304”,
    “horsepower”: “150”,
    “weight”: “3433”,
    “acceleration”: “12”,
    “model_year”: “22”,
    “origin”: “usa”,
    “is_deleted”: “0”
}

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:

{
        “name”: “chevrolet chevelle malibu”,
        “mpg”: “18”,
        “cylinders”: “8”,
        “displacement”: “307”,
        “horsepower”: “130”,
        “weight”: “3504”,
        “acceleration”: “12”,
        “model_year”: “70”,
        “origin”: “usa”,
        “is_deleted”: “0”
    }

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

{
    “id”: 409,
    “name”: “chevrolet chevelle malibu”,
    “mpg”: “18”,
    “cylinders”: “8”,
    “displacement”: “307”,
    “horsepower”: “130”,
    “weight”: “3504”,
    “acceleration”: “12”,
    “model_year”: “70”,
    “origin”: “usa”,
    “is_deleted”: “0”
}

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.

Unknown's avatar

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. Liberty is a Senior AI Engineer at the University of Pittsburgh Medical Center, and was a Team Lead and Senior Software Engineer for various corporations, a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a 21 year Microsoft MVP.
This entry was posted in Essentials. Bookmark the permalink.

2,765 Responses to .NET APIs Part 5 – All the CRUD APIs

  1. I am a first-time visitor and have come across a lot of fascinating content in the casino, especially in the discussions. The many comments on your articles show I am not the only one enjoying this experience. Well done! Casino Plus Ph

  2. Charlessuerm's avatar Charlessuerm says:

    Успех наркологического центра “Здоровая Жизнь” обеспечивается командой высококвалифицированных специалистов, которые объединены не только профессионализмом, но и искренним желанием помочь людям в трудной ситуации.
    Получить дополнительную информацию – https://надежный-вывод-из-запоя.рф/vyvod-iz-zapoya-anonimno-v-voronezhe.xn--p1ai/

  3. betflikauto's avatar betflikauto says:

    I just like the valuable information you provide for your articles.
    I will bookmark your blog and test again right here regularly.
    I am reasonably sure I’ll be informed a lot of new stuff right here!
    Best of luck for the next!

  4. 星座's avatar 星座 says:

    Your blog is my digital coffee break—always worth the read!juben.yingheshe.com

  5. LarryOpeve's avatar LarryOpeve says:

    Детоксикация — это не одна «капельница», а серия мероприятий, направленных на снижение токсической нагрузки, выравнивание жизненно важных показателей и возвращение контроля над самочувствием. На старте врач проводит осмотр, при необходимости — экспресс-диагностику и ЭКГ, объясняет цели инфузионной терапии, отвечает на вопросы о препаратах и возможных ощущениях в первые часы после начала. Если состояние пациента позволяет, первые шаги выполняются дома: так легче согласиться на помощь и сохранить приватность. При выраженной интоксикации, обезвоживании, скачках давления и пульса, нарушении ориентации или риске судорог безопаснее выбрать стационар: расширенная диагностика и круглосуточный мониторинг снижает вероятность осложнений и даёт возможность гибко корректировать назначения. После купирования острых проявлений команда переходит к стабилизации — настройке сна, питания, гидратации и поддерживающих схем с понятными целями на ближайшие дни.
    Получить больше информации – http://narkologicheskaya-klinika-moskva9.ru/narkologicheskaya-klinika-v-moskve-ceny/

  6. Stephenviaps's avatar Stephenviaps says:

    Wow that was strange. I just wrote an incredibly long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Anyway, just wanted to say superb blog!
    teen gay porno

  7. IsmaelNiz's avatar IsmaelNiz says:

    Howdy very cool website!! Guy .. Beautiful .. Amazing .. I’ll bookmark your website and take the feeds additionally? I’m glad to search out numerous helpful info here in the publish, we want work out extra strategies in this regard, thanks for sharing. . . . . .
    free gay porn video

  8. OLanepiliA's avatar OLanepiliA says:

    Hmm is anyone else encountering problems with the pictures on this blog loading? I’m trying to find out if its a problem on my end or if it’s the blog. Any responses would be greatly appreciated.
    sleep aid pills online

  9. Hawaiian Snow strain
    Very informative blog, highly recommended

  10. Hawaiian Snow strain
    Very informative blog, highly recommended

  11. Durban Poison strain
    Very precise information. Thank you for sharing.

  12. Ein gutes Live Casino zeichnet sich durch eine breite Spielauswahl, faire Setzlimits und
    qualifizierte Croupiers aus. Diese Spiele bieten nicht nur spannende Themen, sondern auch attraktive Gewinnmöglichkeiten. In Deutschland sind online slot aufgrund ihrer Vielfalt
    und hohen Gewinnchancen äußerst beliebt.
    Online Slots sind das Herzstück vieler Online Casinos und bieten eine unglaubliche Vielfalt an Themen und Spielmechaniken.
    Im Jahr 2025 stehen diese Casinos an der Spitze des Online-Glücksspiels und bieten eine erstklassige Erfahrung für alle Spieler.
    Diese Seiten bieten Spiele mit hohen RTPs (Return to
    Player), was bedeutet, dass Spieler eine höhere Chance auf
    Gewinne haben, besonders bei Online Casino Echtgeld Spielen.
    Diese Casinos bieten Spielern bessere Gewinnchancen und ein transparentes Spielumfeld, was sie besonders für Echtgeld-Spieler attraktiv macht.
    Spiele mit einer hohen Auszahlungsquote (RTP) sind bei Spielern besonders beliebt, da sie bessere
    Gewinnchancen in einem Echtgeld Casino bieten.

    References:
    https://online-spielhallen.de/24-casino-aktionscode-ihr-schlussel-zu-exklusiven-vorteilen/

  13. EarnestCor's avatar EarnestCor says:

    This is really interesting, You are a very skilled blogger. I’ve joined your rss feed and look forward to seeking more of your excellent post. Also, I’ve shared your web site in my social networks!

    Crypto OTC desk

  14. Timsothybioli's avatar Timsothybioli says:

    Hi everyone, it’s my first pay a visit at this website, and piece of writing is genuinely fruitful in favor of me, keep up posting such content.
    gratis pornos downloaden

  15. JeffreyGickY's avatar JeffreyGickY says:

    Дом — это тишина, отсутствие «социального шума» и лишних свидетелей. Выездной врач «НоваТонуса» приезжает анонимно, начинает с очной оценки и допуска к терапии, сверяет совместимости с тем, что человек принимал за последние двое суток, проверяет давление, пульс, сатурацию, температуру, кратко оценивает неврологический статус и уровень тревоги. Только после допуска запускается индивидуальная инфузионная поддержка: коррекция воды и электролитов, защита органов мишеней, симптом-контроль тошноты и головокружения, при показаниях — мягкая настройка сна без избыточной седации. В конце визита — переоценка, перевод на per os-схемы, памятка на 24–48 часов и заранее оговорённое окно контрольного контакта. Такой маршрут даёт устойчивую динамику на сутки и неделю, а не минутное облегчение.
    Выяснить больше – narkologicheskaya-klinika-obratnyj-zvonok

  16. LhanepiliA's avatar LhanepiliA says:

    Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.
    viagra fiyat

  17. LewisGor's avatar LewisGor says:

    What a material of un-ambiguity and preserveness of precious familiarity regarding unpredicted feelings.
    получить гражданство румынии

  18. Jamescaupt's avatar Jamescaupt says:

    Домашняя помощь — это клиника, перенесённая в тихую комнату. Знакомая обстановка снижает тревогу, исчезают пробки и ожидание, нет «социального шума». Врач «ПрофДетокса» приезжает без эмблем, действует спокойно и последовательно, объясняет каждое назначение простым языком. Мы не используем мифические смеси. Состав и темп капельницы подбираются под текущие показатели — давление, пульс, сатурация, выраженность тремора и тошноты, уровень тревоги, данные о лекарствах, которые человек успел принять за двое суток. Такой подход даёт не минутное облегчение, а устойчивую динамику на сутки и неделю.
    Детальнее – http://narkolog-na-dom-ivanteevka8.ru

  19. GichardAmomi's avatar GichardAmomi says:

    Heya this is somewhat of off topic but I was wanting to know if blogs use WYSIWYG editors or if you have to manually code with HTML. I’m starting a blog soon but have no coding skills so I wanted to get guidance from someone with experience. Any help would be greatly appreciated!
    официальный сайт lee bet

  20. EarnestCor's avatar EarnestCor says:

    What’s up, its pleasant paragraph concerning media print, we all know media is a wonderful source of data.
    казино либет

  21. IsmaelNiz's avatar IsmaelNiz says:

    Hello I am so excited I found your site, I really found you by error, while I was searching on Askjeeve for something else, Anyways I am here now and would just like to say many thanks for a tremendous post and a all round interesting blog (I also love the theme/design), I don’t have time to browse it all at the minute but I have saved it and also added in your RSS feeds, so when I have time I will be back to read a great deal more, Please do keep up the fantastic work.
    бонус Banda Casino

  22. Stephenviaps's avatar Stephenviaps says:

    Attractive section of content. I just stumbled upon your website and in accession capital to assert that I acquire actually enjoyed account your blog posts. Any way I’ll be subscribing to your augment and even I achievement you access consistently quickly.
    888p casino

  23. MichaelNindy's avatar MichaelNindy says:

    We know, why investing matters. Site about yor investment: https://groshi.xyz

  24. LewisGor's avatar LewisGor says:

    Hello there, You have done an excellent job. I will certainly digg it and personally recommend to my friends. I am confident they will be benefited from this web site.

    friv.com juegos

  25. Marcusjar's avatar Marcusjar says:

    Мы используем модульную терапию: каждый контур решает одну клиническую задачу и сопровождается понятной динамикой. Это помогает мягко вести пациента и не «замазывать» вклад отдельных шагов параллельными усилениями.
    Подробнее можно узнать тут – срочный вывод из запоя в казани

  26. Любителям динамичных и увлекательных игр отлично подойдут wincasino азартные развлечения . Платформа предлагает широкий выбор развлечений: слоты, рулетка, блэкджек, баккара и интерактивные шоу с живыми дилерами. Все игры обладают высоким качеством графики и честной системой выплат, что делает игровой процесс захватывающим и безопасным. Удобный интерфейс и поддержка мобильных устройств позволяют наслаждаться игрой в любое время и в любом месте. Благодаря бонусам и акциям, wincasino азартные развлечения становятся привлекательным вариантом как для новичков, так и для опытных игроков.

  27. Любители прогнозировать и следить за спортивными событиями по достоинству оценят Спортивные ставки Win Casino . Платформа предлагает широкую линию для ставок: футбол, баскетбол, теннис, хоккей, бокс, киберспорт и множество других дисциплин. Игроки могут делать ставки в прематче или в режиме лайв, отслеживая изменения коэффициентов в реальном времени. Интуитивно понятный интерфейс помогает быстро находить нужные матчи и оформлять прогнозы. Благодаря высокой надежности, честной системе выплат и привлекательным бонусам, Спортивные ставки Win Casino становятся отличным выбором как для новичков, так и для опытных беттеров.

  28. Your writing style is very engaging.

  29. GregorySar's avatar GregorySar says:

    обновление 1С Печать форм для бизнеса Нс Диджитал Франчайзинг 1С Бухгалтерия, продажа и разработка продуктов 1с

  30. IsmaelNiz's avatar IsmaelNiz says:

    Playbet Nigeria offers betting – Racing & Numbers Online Nigeria on dozens of sports in live and pre-match (line) modes, a live online casino with tables available 24/7, and a huge selection of popular slots. A unique welcome bonus is offered for deposits made in cryptocurrency. Round-the-clock support and fast withdrawals of winnings.

  31. Fobertnap's avatar Fobertnap says:

    Playbet Kenya offers – Bet on Sports Kenya betting on dozens of sports in live and pre-match (line) modes, a live online casino with tables available 24/7, and a huge selection of popular slots. A unique welcome bonus is offered for deposits made in cryptocurrency. Round-the-clock support and fast withdrawals of winnings.

  32. OLanepiliA's avatar OLanepiliA says:

    Inbet Nigeria — thousands of live sports events sports Bet Nigeria . Fast payouts, high odds, 24/7 support, and match broadcasts. Bet on sports and play slots, roulette, blackjack at Inbet Nigeria. Mobile app, jackpots, promos, welcome & deposit bonuses.

  33. OLanepiliA's avatar OLanepiliA says:

    Hey there, You have done a fantastic job. I will certainly digg it and personally recommend to my friends. I am sure they will be benefited from this web site.
    palo alto globalprotect download

  34. Nehmen wir an, du möchtest beim Blackjack spielen den Bonus freispielen und dabei 5€ pro Hand setzen.
    Während die Einsätze an Spielautomaten und Rubbellosen eigentlich immer vollständig anerkannt werden,
    werden Einsätze an Tischspielen wie Roulette
    und Blackjack schlechter gewichtet. Die Bonus Angebote sind mit ein Grund
    dafür, warum Casinospieler zu Online Casino Spieler konvertieren und ihre örtliche Spielhalle für
    die Internet Spielbank aufgeben.
    Folgen Sie unserem Leitfaden und spielen Sie online ohne Angst
    vor Betrügern. Sie bieten deutschen Spielern eine große Auswahl an kostenlosen Slots.
    Unsere Empfehlungen zeigen Ihnen ausserdem auch Casinos an,
    bei welchen Sie das jeweilige Spiel kostenlos mit Bonus online spielen können.

    References:
    https://online-spielhallen.de/wurfelspiele-im-casino-regeln-top-spiele-tipps/

  35. Insgesamt können Sie hierbei bis zu 1.200 € und 220
    Freispiele absahnen. Sie erhalten bis zu Ihrer
    vierten Einzahlung einen Verde Casino Bonus. Unter
    anderem erhalten Sie mit jeder VIP-Stufe unter anderem einen höheren Reload-Bonus und mehr Cashback.

    Dazu gehören zahlreiche Varianten von Roulette (einschließlich online roulette
    deutschland), Blackjack, Baccarat und Poker. Dieses Paket kann einen erheblichen Bonusbetrag sowie eine große Anzahl
    an Freispielen beinhalten. Nach der Erstellung Ihres Kontos können Sie sich bei Verde Casino anmelden, um zu spielen. Verde Casino bietet den 25€ Bonus ohne
    Einzahlung und den Willkommensbonus für neue Spieler.

    Die Auszahlung von wöchentlichen Freispielen ist auf das 5-fache des Gewinns begrenzt, der durch
    sie erzielt wurde. Der Betreiber Verde Casino 25
    euro welche spiele sieht 5 Tage für die Umsetzung jedes Willkommensbonus
    sowie für das Cashback-Scrolling vor. Um an regulären Promotionen teilzunehmen, müssen Sie keine Verde casino bonus code angeben – es reicht, die Bedingungen des
    speziellen Angebots zu erfüllen.

  36. Freispiele sind fast immer an bestimmte Spiele gebunden. Deshalb
    haben sie jedem No-Deposit-Bonus klare Geschäftsbedingungen angefügt, um sich vor Bonusmissbrauch – zum Beispiel durch Sie oder mich – zu schützen. Bei jedem Freispielangebot prüfen wir den Spin-Wert und
    bestätigen, dass er unsere 15-€-Schwelle erreicht oder übertrifft.

    Spielen und Umsatzbedingungen erfüllen Vulkan Vegas
    50 Freispiele 50 Freispiele ohne Einzahlung

    References:
    https://online-spielhallen.de/top-neue-online-casinos-in-deutschland-nov-2025/

  37. GregorySar's avatar GregorySar says:

    сопровождение 1С ЗУП ПРОФ в России Нс Диджитал Франчайзинг 1С Бухгалтерия, продажа и разработка продуктов 1с

  38. Stephenviaps's avatar Stephenviaps says:

    Hello everybody, here every person is sharing these kinds of knowledge, therefore it’s fastidious to read this weblog, and I used to visit this weblog every day.
    https://urist-rt.ru/

  39. Perryvap's avatar Perryvap says:

    Мы заранее объясняем, какие шаги последуют, чтобы пациент и близкие понимали логику вмешательств и не тревожились по поводу непредвиденных «сюрпризов». Карта ниже — ориентир; конкретные параметры врач уточнит после осмотра.
    Узнать больше – вывод из запоя круглосуточно первоуральск

  40. GichardAmomi's avatar GichardAmomi says:

    Hi just wanted to give you a quick heads up and let you know a few of the pictures aren’t loading properly. I’m not sure why but I think its a linking issue. I’ve tried it in two different internet browsers and both show the same results.
    netextender download for mac

  41. Timsothybioli's avatar Timsothybioli says:

    Hello to all, the contents present at this website are genuinely remarkable for people knowledge, well, keep up the good work fellows.
    watchguard vpn

  42. GregorySar's avatar GregorySar says:

    модернизация 1С Электронная подпись дистанционно Нс Диджитал Франчайзинг 1С Бухгалтерия, продажа и разработка продуктов 1с

  43. GichardAmomi's avatar GichardAmomi says:

    Today, I went to the beach front with my children. I found a sea shell and gave it to my 4 year old daughter and said “You can hear the ocean if you put this to your ear.” She placed the shell to her ear and screamed. There was a hermit crab inside and it pinched her ear. She never wants to go back! LoL I know this is completely off topic but I had to tell someone!
    Qfinder Pro download

  44. Несколько коллег по бизнесу подсказали, что лучше всего подключить whatsapp к битрикс через специалистов, которые реально понимают, как работает CRM. Решил попробовать — и не пожалел. Интеграция заработала сразу, диалоги автоматически попадают в сделки, менеджеры перестали терять переписки. Особенно понравилось, что всё сделали без сложностей и долгих объяснений. Инструмент действительно помогает ускорить работу отдела продаж.

  45. LewisGor's avatar LewisGor says:

    Today, I went to the beach with my kids. I found a sea shell and gave it to my 4 year old daughter and said “You can hear the ocean if you put this to your ear.” She placed the shell to her ear and screamed. There was a hermit crab inside and it pinched her ear. She never wants to go back! LoL I know this is completely off topic but I had to tell someone!
    fortinet vpn

  46. Peoramewah's avatar Peoramewah says:

    Мы живём в эпоху, где автоматизация становится стандартом сервиса. И одно из самых мощных решений — это чат бот whatsapp. Он отвечает круглосуточно, консультирует, помогает оформить заказ и разгружает операторов. Такой инструмент создаёт новый уровень взаимодействия между бизнесом и клиентами. Простота, скорость и надёжность — именно то, чего ждёт современный рынок.

  47. Krenzabluro's avatar Krenzabluro says:

    Многим компаниям требуется поддерживать регулярную коммуникацию с клиентами, поэтому востребованы ватсап рассылки для бизнеса. Они позволяют быстро информировать об акциях, статусах заказов, изменениях в графиках и других важных событиях. Официальный канал обеспечивает высокую доставку и безопасность сообщений, а автоматизация сокращает нагрузку на сотрудников. Такой инструмент помогает уверенно поддерживать контакт с клиентами и повышать эффективность маркетинговых кампаний.

  48. GregorySar's avatar GregorySar says:

    подключение 1С Документооборот быстро Нс Диджитал Франчайзинг 1С Бухалтерия, продажа и разработка продуктов 1с

  49. AndrewRed's avatar AndrewRed says:

    «ПрофДетокс» — выездная наркологическая служба для жителей Ивантеевки и ближайших районов. Мы запускаем помощь без очередей и лишней огласки: врач приезжает анонимно, проводит очную оценку, допускает к терапии и запускает инфузионную поддержку без универсальных коктейлей. Наша задача — снять интоксикацию и абстиненцию, стабилизировать давление и пульс, снизить тревогу, мягко наладить сон по показаниям и дать семье понятный план на ближайшие двое суток. Если дома нет условий для безопасной ночи, предложим палату «ПрофДетокса» с круглосуточным наблюдением. Приватность встроена в процесс, а смета фиксируется до начала процедур.
    Детальнее – https://narkolog-na-dom-ivanteevka8.ru/narkolog-na-dom-srochno-v-ivanteevke

Comments are closed.