Images can be stored in a database in two ways: you can either save the file to the server's file system and store the name and/or path of the image file, or you can store the file itself in binary format. Each approach has its pros and cons. Rather than get into the debate about which storage method is better, I'll show how to work with the Carousel using both approaches.
The carousel transitions through a series of content which can include images and text. A huge number of carousel components are available, ranging widely in terms of their features and complexity. The Bootstrap carousel benefits from not requiring any additional components and from its simplicity. It caters for the majority of use cases, supporting cycling content from right to left, fade transitions and simple replacement of content. It also supports controls, indicators and captions.
The key elements of a Bootstrap carousel are an element with the carousel
class applied to it, and a number of elements with the
carousel-item
class applied to them within an element with carousel-inner
applied to it.
<div class="carousel"> <div class="carousel-inner"> <div class="carousel-item active>...</div> <div class="carousel-item>...</div> <div class="carousel-item>...</div> </div> </div>
The content to be displayed is placed within the carousel-item
elements, one of which needs to have the active
class added to make
the carousel visible.
The carousel supports a number of options which can be applied declaratively
via CSS classes or data-*
attributes, or they can be specified in
client-side code. At the moment, the carousel simply replaces one set of content
with the next without any transition between them. The slide
class
causes content to slide in from right to left. The default interval between
transitions is 5 seconds. You can use the data-interval
attribute
to specify a different interval in milliseconds. The data-ride
option is used to specify whether the carousel should auto play. A value of
carousel
results in the carousel auto-playing on load. Using these options, the
following set up will result in a carousel that slides content from right to
left every 2 seconds and auto plays:
<div class="carousel slide" data-ride="carousel" data-interval="2000"> <div class="carousel-inner"> <div class="carousel-item active>...</div> <div class="carousel-item>...</div> <div class="carousel-item>...</div> </div> </div>
First, I'll look at images stored in the file system. I'm using the Northwind
sample database for the demo and will display employees' photos in the carousel.
The Employee entity has a property named PhotoPath
, which is a string. In my
version, the value stored in the corresponding database column is just the file
name of the employee's photo. The image files are located in wwwroot/images:
I have an EmployeeService
class responsible for obtaining data using Entity
Framework Core. It has one method that gets all employee data:
public class EmployeeService : IEmployeeService { private readonly NorthwindContext context; public EmployeeService(NorthwindContext context) => this.context = context; public async Task<List<Employee>> GetEmployees() => await context.Employees.ToListAsync(); }
The GetEmployees
method is called in the PageModel class and the data assigned to a public property:
public class CarouselModel : PageModel { private readonly IEmployeeService employeeService; public CarouselModel(IEmployeeService employeeService) => this.employeeService = employeeService; public List<Employee> Employees { get; set; } public async Task OnGetAsync() { Employees = await employeeService.GetEmployees(); } }
In the content page, the PhotoPath
property is used to build a relative URL to each image
as each employee
is iterated and a corresponding carousel-item
element is rendered:
<div class="carousel slide" data-ride="carousel" data-interval="2000" style="width:192px;"> <div class="carousel-inner"> @foreach (var employee in Model.Employees) { <div class="carousel-item @(employee == Model.Employees.First() ? "active" : "")"> <img src="~/images/@employee.PhotoPath" alt="@employee.FirstName @employee.LastName"> </div> } </div> </div>
Note that the width of the carousel has been constrained to the width of the
images. Also see that the active
class is applied to the
carousel-item
element generated for the first employee entity in the
sequence to ensure the carousel appears. The first and last name of the
employee
is used to generate a suitable alt
attribute value.
So how do you get binary images into a carousel? Probably the easiest way is
to use data URIs.
Using this approach, you embed the binary data encoded as a Base 64 string and
assign it to the src
attribute of an img
element.
The .NET data taype that maps to the database varbinary or BLOB types is a
byte array. The Employee
entity has a property named Photo
that maps to the
appropriate database column:
public byte[] Photo { get; set; }
This is how the code that generates the carousel-item
elements is modified
to
make use of data URIs:
@foreach (var employee in Model.Employees) { <div class="carousel-item @(employee == Model.Employees.First() ? "active" : "")"> <img src="data:image/jpg;base64,@Convert.ToBase64String(employee.Photo)" alt="@employee.FirstName @employee.LastName"> </div> }
The format of the data URI is the scheme data
folowed by a colon, then the mime type, in this case image/jpg
, although just
image
will do. This is followed by a semi-colon, and then the
encoding. A number of encodings are supported, but Base64 encoding is used for
binary data. This is followed by a required comma, and then the actual data,
encoded using the suitable .NET method.
What about including a caption? This is achieved by adding the
carousel-caption
class to an element within each carousel-item
:
@foreach (var employee in Model.Employees) { <div class="carousel-item @(employee == Model.Employees.First() ? "active" : "")"> <img src="data:image/jpg;base64,@Convert.ToBase64String(employee.Photo)" alt="@employee.FirstName @employee.LastName"> <div class="carousel-caption"> <p class="mb-0">@employee.FirstName @employee.LastName</p> </div> </div> }
Summary
Whether you store images in the file system or as binary data, it is pretty easy to display them using the Bootstrap carousel in Razor Pages.