• Home

  • Custom Ecommerce
  • Application Development
  • Database Consulting
  • Cloud Hosting
  • Systems Integration
  • Legacy Business Systems
  • Security & Compliance
  • GIS

  • Expertise

  • About Us
  • Our Team
  • Clients
  • Blog
  • Careers

  • VisionPort

  • Contact
  • Using Razor templates to render HTML emails in ASP.NET Core

    Kevin Campusano

    By Kevin Campusano
    August 15, 2025

    The side of a gothic church from a very low angle. The ornate spires and gargoyles loom over the viewer, with dark stained glass beneath, sectioned by square stone pillars.

    A while ago I blogged about using Razor templates to render HTML emails in .NET. The method that I discussed there worked, but it was very verbose. Since then, .NET 8 has released, and with it came a simpler way of doing this. In this post we’ll explore how to use these new features to render HTML emails.

    You can find all the code in this post on GitHub.

    The plan

    Similar to the original article, the objective is simple: Sending emails from an ASP.NET Core app, and having the contents of those emails be rendered fromfrom Razor templates. To that end, we need four pieces:

    1. A class for sending emails.
    2. A class for rendering Razor templates into strings.
    3. A Razor template.
    4. A class that puts it all together. That is, takes in parameters, renders the email, and sends it.

    Step 1: Sending emails with the MailKit NuGet package

    With the help of the MailKit NuGet package, sending emails in .NET is easy. Let’s install it with:

    dotnet add package MailKit --version 4.13.0

    We also need some configuration in the appsettings.json file, to define the settings needed to establish a connection with an SMTP server:

    // ./appsettings.json
    
    {
        // ...
        "MailSettings": { …

    csharp aspdotnet email

    Vector Search for the End Point Blog

    Seth Jensen

    By Seth Jensen
    August 13, 2025

    A sidewalk and road lead to the left of the image, across from an industrial area with train tracks. Along the sidewalk are trees with white petals, many of which have fallen to the sidewalk.

    We’re excited to announce a new feature on the End Point Blog: AI-powered vector search.

    Below the “Our Blog” header at the top of this page, there is a new search bar with two adjacent buttons: “Search” and “LLM Expanded Search.” If you click “Search” (or press Enter), your search will be fed directly to our vector search/​similarity search engine. If you click “LLM Expanded Search” (or press Shift+Enter, Control+Enter, or Command+Enter on macOS) your query will first be expanded by an open-source LLM, then sent to the similarity search engine.

    The LLM is trained to expand the query to include similar terms, keywords, etc., before sending it to the similarity search engine. For example, if I search S3, similarity search alone returns no results — there isn’t enough semantic information for vector search to make useful connections. However, an LLM can expand this to s3, simple storage service, amazon s3, object storage, cloud storage..., providing more anchor points for vector search to connect to results.

    The model improves results fairly well, but it is still an experimental technology, so results will …


    company artificial-intelligence

    Processing payments with Authorize.Net in a Blazor app

    Kevin Campusano

    By Kevin Campusano
    August 11, 2025

    European rooftops curve at the bottom of the image upwards. The rest of the image is a partially overcast gray sky with some sun peeking from behind the clouds

    Blazor, the SPA framework from ASP.NET Core, is excellent technology. However, it is very particular when it comes to interacting with JavaScript. This is because Blazor apps are written in C# with Razor templates. So, if a Blazor app needs to interact with a JavaScript library (for example, to process credit card payments through Authorize.Net), special care is needed. In this article, we’ll see an approach on how to make that happen.

    We’ll develop a Blazor WebAssembly standalone app which will include a form to capture credit card information and send it to Authorize.Net using their Accept.js frontend integration library. Then, Authorize.Net will return a payment token that represents the captured credit card. Our frontend will then submit the resulting token to a backend API to actually effectuate the payment.

    This backend API, which we’ll also develop, will be a simple ASP.NET Core Web API. It’ll include an endpoint for submitting payment transactions to Authorize.Net, given the token obtained via Accept.js.

    You can find the all the source code discussed here on GitHub.

    The backend

    Let’s begin by creating a new ASP.NET Core Web API project with …


    csharp aspdotnet blazor payments

    Announcing Our 30th Anniversary!

    Benjamin Goldstein

    By Benjamin Goldstein
    August 8, 2025

    Today marks End Point’s 30th anniversary!

    On this date in 1995, as the Internet boom was just beginning, Rick Peltzman and I started the company, diving into the new and fast-changing world of the web. Since then, End Point has worked with a wide range of clients, tackled complex challenges, built reliable, long-term solutions, and adapted to continual waves of technological change — most recently integrating AI technologies into our work. The dedication and talent of our team have made all the difference.

    As we reflect on these 30 years, we’re grateful for the many clients, partners, and colleagues who have been part of our story. We look forward to continuing to learn, innovate, and create in the years ahead.


    company

    Building Offline-Capable Rails Apps Using Service Workers and Turbo

    Couragyn Chretien

    By Couragyn Chretien
    August 7, 2025

    The left half of the image is dominated by out-of-focus pink-red flower petals close to the camera, which give way to petals on branches which are in focus, with sunlight shining through the back.

    Users today expect web apps to continue working even when their internet connection is unstable or temporarily lost. Out of the box, Rails applications do not handle this well. In this blog post, we will walk through how to add offline support to a Rails app using Service Workers, Workbox, and Turbo. This approach gives users a smoother experience and better reliability when network conditions are not ideal.

    This guide focuses on a real-world setup. You will learn how to cache pages and assets, handle Turbo form submissions offline, and provide a fallback UI when needed.

    Why Offline Support Matters

    Turbo makes Rails applications fast and responsive by replacing traditional client-side JavaScript with HTML over the wire. However, if the network drops out, those Turbo requests fail silently. Adding a Service Worker allows us to intercept those requests and provide a better experience.

    Offline support improves performance, enhances user experience on mobile devices, and adds resilience in situations where network access is intermittent.

    Creating a Manifest File

    Start by adding a manifest file to your Rails app. This file lets the browser know your app supports offline behavior. …


    rails javascript

    A Rusty Web? An Excursion of a Perl Guy into Rust Land

    Marco Pessotto

    By Marco Pessotto
    August 5, 2025

    Several rusty chains are tied into the side of a rusty metal structure.

    In my programming career centered around web applications I’ve always used dynamic, interpreted languages: Perl, JavaScript, Python, and Ruby. However, I’ve always been curious about compiled, strongly typed languages and if they can be useful to me and to my clients. Based on my recent findings, Rust would be my first choice. It’s a modern language, has excellent documentation and it’s quite popular. However, it’s very different from the languages I know.

    I read most of the book a couple of years ago, but given that I didn’t do anything with it, my knowledge quickly evaporated. This time I read the book and immediately after that I started to work on a non-trivial project involving downloading XML data from different sources, database operations, indexing and searching documents, and finally serving JSON over HTTP. My goal was to replace at least part of a Django application which seemed to have performance problems. The Django application uses Xapian (which is written in C++) via its bindings to provide the core functionality. Indexing documents would be delegated to a Celery task queue.

    Unfortunately Xapian does not have bindings for Rust so …


    rust perl

    Integrating Grape with Sidekiq for Asynchronous Processing in Rails

    Couragyn Chretien

    By Couragyn Chretien
    August 4, 2025

    A mountain path leading into an aspen forest, with light shining from behind the trees. The image has a red cast, especially on the haze glowing around the leaves from the afternoon sun.

    When building an API in a Rails application using Grape, there is a natural tendency to handle all logic synchronously. For small applications or internal tools, that can work well. But for a growing SaaS platform or public-facing API, doing too much work in the request cycle leads to slower response times and can make your endpoints fragile.

    This post walks through the process of integrating Grape with Sidekiq so that heavy tasks can be moved to background workers. The goal is to keep endpoints fast and resilient while offloading expensive processing.

    Why asynchronous processing matters

    Many common tasks in an API do not need to be done immediately. Examples include sending confirmation emails, syncing to a third-party service, exporting data, or generating reports. By sending these jobs to a background processor like Sidekiq, the API can respond quickly and let the user continue without waiting.

    Separating these tasks also gives better observability and error handling. Sidekiq offers retries, job tracking, and simple ways to inspect queues out of the box.

    Setting up Grape and Sidekiq

    Assuming you already have a Rails application with Grape installed, the next step is to add …


    rails api

    Bash expansion techniques for a more efficient workflow

    Seth Jensen

    By Seth Jensen
    July 10, 2025

    A low-angle view of a brick building with half height walls creating an alternating pattern of wall and dark, shaded ceiling. mirrored about the center of the image. Each mirrored side of the image has two strong angles; the building protrudes from midway up the left edge, turning sharply down, then coming back up and to the right to the center.

    For any project, you need a quick and efficient way to wrangle your files. If you use Unix, Bash and Zsh are powerful tools to help achieve this.

    I recently needed to rename a file so that all its underscores were replaced with dash characters, to match the convention of the project. I could do this manually pretty quickly, but I knew there was a bash built-in one-liner waiting to be discovered, so I went down the rabbit hole to learn about Bash’s shell expansions and history expansion. See the “history expansion” section for how I solved the underscore/dash issue.

    Bash has seven types of expansion:

    • brace expansion
    • tilde expansion
    • parameter and variable expansion
    • command substitution
    • arithmetic expansion
    • word splitting
    • filename expansion

    The documentation is good and concise for each of these, so rather than try to recreate it, I’ll go over examples of how I use some of them.

    Shell parameter expansion

    Example: batch converting images to WebP

    I use parameter expansion frequently while maintaining this blog. We serve images in WebP format, so I generally loop over all the JPEGs and/or PNGs (after cropping and/or scaling) and convert them using cwebp:

    for f …

    linux shell tips
    Previous page • Page 2 of 222 • Next page