Building an event information portal with ASP.NET 5 & DotVVM
Tags: dotnet, csharp, webdev, sql
Published: 2021-02-24 14:18:57

On many occasions, when we organize large events, we need to build an informational web portal to be able to show our users the data of an event, the sessions that will be held, information about the organizers and sponsors, and also a section for them to register. 

For these purposes, in this article, we will review how to build an informational web portal, with ASP.NET 5, starting from the database, to the design of the corresponding website with a technology called DotVVM on .NET, which will help us with the design process.

##**Previous article: a web portal for event management**

In a previous article we were able to analyze how to build a dashboard to manage our event data, whose portal looked like this:

![](https://dev-to-uploads.s3.amazonaws.com/i/z19jtx2mgg14f0iaqp7c.png)

The tutorial article to build this dashboard can be found here: [Web portal to manage events and conferences with ASP.NET 5 and DotVVM](https://dev.to/esdanielgomez/web-portal-to-manage-virtual-or-in-person-events-with-asp-net-5-and-dotvvm-fl9).

And the source code in this repository on GitHub: [EventAdmin](https://github.com/esdanielgomez/EventAdmin).

##**Sections of the information website**

This informational website is for the sole purpose of presenting data to the user (no information will be saved from this page), whose highlighted sections are as follows:

+ **Main section or cover**. Shown here is the event title and some general information, such as the event date and location. 
+ **Event Schedule**, which lists the talks or conferences with which the event will count, along with the speakers, and the start times for each of these sessions. 
+ **Organizers**, to show in general to those communities and/or institutions that are organizing the event. 
+ **Sponsors**. Here we can show those sponsors who are supporting the event. 
+ **Registration**, where indicated or displayed to the user where they can register to be part of the event. 

The final result of the web page will look approximately as follows:

![](https://dev-to-uploads.s3.amazonaws.com/i/aemir2ph3monu6k5ux3s.png)

Now that we are aware of the sections that will be included, let's start building our web portal.

##**Solution Structure**

All part of the database where the event information is stored. For this platform, the entities in the database are: `Organizer`, `Sponsor`, `Event`, `Speaker`, `Session`, `Speaker_has_Session`, `SessionLevel`, and `SessionType`.

![](https://dev-to-uploads.s3.amazonaws.com/i/dj700u3ofk9tg6t8uafs.png)

***Note***: As a database manager, we plan to use SQL Server.

However, if we consider Visual Studio as a working environment for the construction of this website, in this solution we will have three projects:

![](https://dev-to-uploads.s3.amazonaws.com/i/xsk5flh25ku3kn6z2be1.png)

+ **Data Access Layer (DAL)**: A class library to handle connection and access to the database.
+ **BL (Business Layer)**: another library of classes for the management of services and the logic of the website domain.
+ **APP - App presentation layer**. This section is where we have the Views and Viewmodels for the layout of the event web page with DotVVM.
With this in mind, let's now look at the steps we need to take in these three projects for the development of our web portal. 

##**DAL – Data Access Layer**

This first project corresponds to a class library. In this sense, as a first task, we have to relate our project to the database in SQL Server. We can achieve this goal with entity framework, through the Database-First approach, so that we can generate the classes of existing entities from our database. 

In this project we will need three Nuget packages:

+ `Microsoft.EntityFrameworkCore.Design`
+ `Microsoft.EntityFrameworkCore.Tools`
+ `Microsoft.EntityFrameworkCore.SqlServer`

From the package management console we can do Scaffold, to generate the classes from existing entities using the following command:

```
Scaffold-DbContext "Server=YOUR_SERVER; Database=DATABASE_NAME; Username=YOUR_USERNAME; Password=YOUR_PASSWORD Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir DAL/Entities
```

When the console process is complete, we'll have something like this:

![](https://dev-to-uploads.s3.amazonaws.com/i/v63s0964570sgmh455ds.png)

So far, the connection and configurations required to work with the SQL Server database are ready.

##**BL – Business Logic Layer**

Now it's up to us to define the models and create the services to handle the logic of our application. In this case, we will create a second class library to have a general list of entities (`Event`, `Organizer`, `Session`, `Speaker`, `Sponsor`) and the specific information of each of them.

In the solution within Visual Studio 2019 about the EventPortal.BL project we will have something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwvet6erk9m60iftab1y.png)

Similarly with the administrative web portal, for this website, there is an important aspect to mention, and it corresponds to the identification of the event since the database is designed so that several events can be handled at once. In the `EventId` class, inside the `Services` folder, we can control the ID of the event we want to work with.

```csharp
public class EventId
{
    private static EventId instance { get; set; } = null;

    public int Id { get; set; } = 1;

    private EventId() { }

    public static EventId GetInstance()
    {
        if (instance == null) {
            instance = new EventId();
        }

        return instance;
    }
}
```

With this mentioned, in this class library, we have two important parts. As a first point, the models specify the attributes with which we want to work for each of the corresponding cases. 

The models are as follows:

| **Models** |
|------------- |
| `EventModel` | 
| `OrganizerModel` |
| `SessionModel` | 
| `SpeakerModel` |
| `SpeakerHasSessionModel` |  
| `SpeakerModel` | 
| `SponsorModel` |

The second important part to consider is services. All these services have methods, whose sole purpose is to consult the list of records for a particular case. In this sense, the methods of these services are as follows:

| **Services** | **Methods** |
|------------- |------------- |
| `EventService` | `GetEventByIdAsync()` |
| `OrganizerService` | `GetAllOrganizersAsync()` |
| `SessionService` | `GetAllSessionAsync()`, `GetAllSessionByDayAsync(DateTime date)`, y `GetSpeakerHasSessionList(int IdSession)` |
| `SpeakerService` | `GetAllSpeakerAsync()`, y `GetSpeakerByIdAsync(int IdSpeaker)` |
| `SponsorService` | `GetAllSponsorsAsync()` |

Most methods of the services are intended to obtain a list of records. However, for the case of `SessionService`, there are two additional methods, the first `GetAllSessionByDayAsync(DateTime date)` to get all sessions from a given date, and the second `GetSpeakerHasSessionList(int IdSession)` to get the speakers associated with a session. Similarly, SpeakerService has an additional method called `GetSpeakerByIdAsync(int IdSpeaker)`, where we can get a specific speaker, along with listing its associated sessions. 

With this mentioned, let's review the layout of the website for our attendees. 

##**PL – Presentation Layer**

Now that we have defined the whole part for data handling, we can start designing each of the sections of the website. In DotVVM, pages consist of two parts: 

+ ***A View***, which is based on HTML syntax and describes what the page will look like. 
+ ***A ViewModel***, which is a class in C- that describes the state of the page (for example, values in form fields) and handles user interactions (for example, button clicks).

Considering the Views and Viewmodels files for the web page, in Visual Studio 2019 for this project we'll see the following:

![](https://dev-to-uploads.s3.amazonaws.com/i/47qmu150g8ms8irgpnqy.png)

According to each of the sections of the page (cover, event schedule, organizers, sponsors and registration), then we will analyze each of these sections, along with the format of the page.

##**General Page Format**

In DotVVM, master pages or master pages are known as Masterpage, whose files have a `.dotmaster` extension. In this case, this page will be useful to set our HTML skeleton, import CSS & JavaScript files, and define the contents that will be visible in all sections of the page (lists, forms, records). 

In the `MasterPage.dotmaster` file, the overall structure of the web page is as shown below:

![](https://dev-to-uploads.s3.amazonaws.com/i/202i8g8p0hjfc7s79snd.png)

Where, 

+ ***Section 1***, is the HTML header where we will find the page title, CSS fonts and referenced JavaScript files, and other specifications. 
+ ***Section 2***, the header of the page, which will be useful to show the options or menu of this page.

![](https://dev-to-uploads.s3.amazonaws.com/i/lole2azok2aukb2dtaqe.png)

+ ***Section 3***, this is one of the most important parts of the MasterPage. This space displays the contents of the child page, whose ID corresponds to the MainContent.  
+ ***Section 4***, here we will find the footer or footer of the page. 

With this structure, now let's look at the `MainContent`, which will be the subpage where the informational sections of the event are located. For this particular case, we will only have one child page or view, whose file is named `Default.dothtml`. The structure of this view is as follows:

![](https://dev-to-uploads.s3.amazonaws.com/i/9szaj65g6xnoglk91ktr.png)

Under this same sequence, in the corresponding ViewModel of this view, that is, in the file `DefaultViewModel.cs`, we find the definitions of the collections that allow us to consult the data of organizers, sponsors, sessions and speakers, and the general information of the event.

Some of these definitions, according to the models defined in the BL (Business Layer) are as follows:

```csharp
public List<SponsorModel> Sponsors { get; set; }
public List<OrganizerModel> Organizers { get; set; }
public List<CalendarSpeakers> Calendar { get; set; } = new List<CalendarSpeakers>();

public EventModel Event { get; set; }
``` 

Now that we know the overall structure of the page, now let's look at each of the corresponding sections.

**Cover**

The first section of the page corresponds to the cover page. For this case, this section is only displaying the event title using the `Event` object defined in the ViewModel.

![](https://dev-to-uploads.s3.amazonaws.com/i/uvcondknzwfz67bsa5nq.png)

```html
<section id="about">
	<div class="container" data-aos="fade-up">
		<div class="row">
			<div class="col-lg-6">
				<h2>About the event</h2>
				<p>
					{{value: Event.Description}}
				</p>
			</div>
		</div>
	</div>
</section>
```

Here we can add the event description, start date, and such attributes. 

**Agenda or schedule of the event**

The next part corresponds to the agenda with the sessions of the event, arguably this is the most important part of the page. Here we have a calendar or a list of sessions per day, and in turn, these sessions have their corresponding information and the list of speakers that will be part of that session.

![](https://dev-to-uploads.s3.amazonaws.com/i/sos9e9p8dvxt83z5ll8x.png)

Since the intention is that each session is automatically displayed per day, a DotVVM control called `Repeater` is used here. This control aims to repeat a template for each item in a collection specified in the `DataSource`, in this case, for each day, a list of sessions will be displayed.

Within this Repeater, we can put another control (one inside the other), to assemble a list of sessions. In each row of this list, we can display as a template all sessions with their start date, the name of the session, the name of the speakers involved, and the type of the session (conference, workshop, panel, etc.). 

These nested controls can be viewed below for the `Calendar` and `Sessions` listings respectively.

```html
<dot:Repeater DataSource="{value: Calendar}" class="tab-content row justify-content-center" data-aos="fade-up" data-aos-delay="200">
	<ItemTemplate>
		<div role="tabpanel" html:id="{{value: NumberOfDayRef}}" class="{{value: Css}}">
			<dot:Repeater DataSource="{value: Sessions}" class="row schedule-item">
				<ItemTemplate>
					<div class="col-md-2"><time><b>{{value: StartDate.Value.ToString("hh:mm tt")}}</b></time></div>
					<div class="col-md-10">
						<div class="speaker">
							<img src="assets/img/speakers/1.png" alt="{{value: SpeakerString}}">
						</div>
						<h4>{{value: Name}}.</h4>
						<span>{{value: SpeakerString}}.</span>
						<p>{{value: NameSessionType}}.</p>
						<p><br /></p>
					</div>
				</ItemTemplate>
			</dot:Repeater>
		</div>
	</ItemTemplate>
</dot:Repeater>
```

**Organizers**

The next section involves the communities, companies, or institutions that are organizing the event.

![](https://dev-to-uploads.s3.amazonaws.com/i/y2nug5g9szwefrr60v7m.png)

As for the event agenda, here we can also use a `Repeater` control to create a design template listing all the organizers registered and defined in the ViewModel. For this case, the template is an image of the organization (link of the image stored in the database), and this image shows the name of the community and a small description. By clicking on this image, the user can access one of the social networks or websites of the organizing community. 

The template for this collection is defined as follows:

```html
<dot:Repeater DataSource="{value: Organizers}" class="row">
	<ItemTemplate>
		<div class="col-lg-4 col-md-6">
			<div class="speaker" data-aos="fade-up" data-aos-delay="100">
				<img src="{{value: LogoLink}}" alt="{{value: Name}}" class="img-fluid">
				<div class="details">
					<h3><a href="{{value: FacebookLink}}" target="_blank">{{value: Name}}</a></h3>
					<p>{{value: Description}}</p>
					<div class="social">
						<a href="{{value: TwitterLink}}" target="_blank"><i class="fa fa-twitter"></i></a>
						<a href="{{value: FacebookLink}}"><i class="fa fa-facebook" target="_blank"></i></a>
					</div>
				</div>
			</div>
		</div>
	</ItemTemplate>
</dot:Repeater>
```

**Sponsors**

Continuing our analysis, we now come across the sponsors section.

![](https://dev-to-uploads.s3.amazonaws.com/i/f3ugyms8snzz9ggon8o5.png)

Unsurprisingly, here we also use a `Repeater` control to automatically list all sponsors based on records stored in the database. For this template, the base collection corresponds to Sponsors as set out in the ViewModel:

```html
<dot:Repeater DataSource="{value: Sponsors}" class="row no-gutters supporters-wrap clearfix" data-aos="zoom-in" data-aos-delay="100">
	<ItemTemplate>
		<div class="col-lg-3 col-md-4 col-xs-6">
			<div class="supporter-logo">
				<a href="{{value: WebPage}}" target="_blank">
					<img src="{{value: LogoLink}}" class="img-fluid" alt="{{value: Name}}">
				</a>
			</div>
		</div>
	</ItemTemplate>
</dot:Repeater>
```

**Registration and contact**

Finally, here we find the registration and contact section.

![](https://dev-to-uploads.s3.amazonaws.com/i/x3uzxxcf1qts9rvd0v3v.png)

For this case, it has been considered that the registration of attendees can be done through an external form such as Microsoft or Google Forms, so in this section, we can place a button that redirects to that registration form. With this in mind, we only need to reference the `RegistrationLink` attribute of the `Event` object defined in the ViewModel:

```html
<form method="POST" action="{{value: Event.RegistrationLink}}">
	<div class="form-row justify-content-center">
		<div class="col-auto">
			<button type="submit">Register</button>
		</div>
	</div>
</form>
```

We can also do the same for the means of contact.

##**What's next?**

Amazing, we have already reached the final part of this article where we have been able to learn in a general way how to build a website with ASP.NET 5 & DotVVM to publicize the data of some event that we are organizing. 

The source code for this project can be found in the following repository on GitHub: [EventPortal](https://github.com/esdanielgomez/EventPortal).

**Additional resources:**

There are many things we can build with ASP.NET, and many more that we can add to this portal that we have built. In this sense, here are some additional resources to further acquire knowledge in this field:

+ [.NET 5: Deploying web apps with Azure App Service](https://dev.to/esdanielgomez/net-5-deploying-web-apps-with-azure-app-service-5349)
+ [Deploy web applications with ASP.NET Core and DotVVM on AWS Elastic Beanstalk](https://dev.to/dotvvm/deploy-web-applications-with-asp-net-core-and-dotvvm-on-aws-elastic-beanstalk-2m92).
+ [Working with web services through ASP.NET Core and DotVVM (A step by step guide)](https://dev.to/dotvvm/working-with-web-services-through-asp-net-core-and-dotvvm-a-step-by-step-guide-2le).

Thank you very much for reading this article, I hope that this demo can be of help for the organization and dissemination of events. If you have any questions or ideas that you need to discuss, it will be nice to be able to collaborate and together exchange knowledge with each other.

If you like, we can stay in touch on [Facebook](https://www.facebook.com/esDanielGomez), on [Twitter](https://twitter.com/esDanielGomez), or in [Telegram](https://t.me/esdanielgomez) too. :)