DEV Community

Aleksander Wons
Aleksander Wons

Posted on • Updated on

Symfony 7 vs. .NET Core 8 - Web application; the basics

Disclaimer

This is a tutorial or a training course. Please don't expect a walk-through tutorial showing how to use ASP.NET Core. It only compares similarities and differences between Symfony and ASP.NET Core.

The Web server

When developing any PHP application, we will need a web server to serve static files and forward requests to php-fpm. PHP has a built-in web server that can be used for development. We can use this one or the one provided by Symfony. In both cases, the provided web servers are for development purposes only. We won't be using them when deploying our application to production. There, we will still need to set up something like nginx or Apache.

This is different from how ASP.NET Core 8 will handle requests. It comes with a bundled web server called Kestrel. We can still use IIS if we prefer (only on Windows, obviously); but the default is Kestrel. Since it is production-ready, we don't need anything else.

Creating a project

With Symfony's CLI, we can bootstrap three types of applications:

  • a skeleton application (almost an empty project)
  • a web application
  • an API application

We want to start with a web application, so we can create a new project like this:

symfony new --webapp SymfonyWebApplication
Enter fullscreen mode Exit fullscreen mode

The above will bootstrap a Symfony application with many packages and features.

This is very similar to .NET. We can bootstrap a project from a template. There are built-in templates, but we can always create our own.

To see what options we have for a web application, let's list all the templates with web:

dotnet new list web
These templates matched your input: 'web'

Template Name                                 Short Name    Language  Tags                      
--------------------------------------------  ------------  --------  --------------------------
ASP.NET Core Empty                            web           [C#],F#   Web/Empty                 
ASP.NET Core Web API                          webapi        [C#],F#   Web/Web API/API/Service   
ASP.NET Core Web API (native AOT)             webapiaot     [C#]      Web/Web API/API/Service   
ASP.NET Core Web App (Model-View-Controller)  mvc           [C#],F#   Web/MVC                   
ASP.NET Core Web App (Razor Pages)            webapp,razor  [C#]      Web/MVC/Razor Pages       
Blazor Web App                                blazor        [C#]      Web/Blazor/WebAssembly    
Blazor WebAssembly Standalone App             blazorwasm    [C#]      Web/Blazor/WebAssembly/PWA
Web Config                                    webconfig               Config
Enter fullscreen mode Exit fullscreen mode

We will choose mvc as it is the closest to Symfony's approach and bootstraps an MVC-like application.

dotnet new mvc
Enter fullscreen mode Exit fullscreen mode

Application's entry point

Both Symfony and .NET Core have an entry point.

Symfony's version is pretty simplistic:

// public/index.php
<?php

use App\Kernel;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};
Enter fullscreen mode Exit fullscreen mode

A lot of magic happens behind the scenes or is delegated to configuration files.

On the other hand, .NET puts everything into the code. The entry point looks like this:

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
Enter fullscreen mode Exit fullscreen mode

A simple page

A bootstrapped application will render a default page. But let's try to add another one. We can follow Symfony's example with a page showing a randomly generated number. This is how we can do it with both frameworks.

Symfony

<?php
// src/Controller/LuckyController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class LuckyController
{
    #[Route('/lucky/number')]
    public function number(): Response
    {
        $number = random_int(0, 100);

        return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

.NET Core

// Controllers/LuckyNumberController.cs
using Microsoft.AspNetCore.Mvc;

namespace App.Controllers;

public class LuckyNumberController
{
    [Route("/lucky/number")]
    public string Number()
    {
        int randomNumber = new Random().Next(100);

        return $"Lucky number: {randomNumber}";
    }
}
Enter fullscreen mode Exit fullscreen mode

First impression

It feels similar

You can bootstrap a web application (MVC-like) to create the necessary scaffolding.

Web server

With Symfony, we need an external web server to take the application to production. A .NET Core app comes with the Kestrel web server and is ready to be deployed.

Configuration

Symfony configuration happens in external files, while .NET puts everything into code (which makes sense because it is a compiled language). We will get into more details later.

Controllers

The actual controller looks astonishingly similar. The only differences are the syntax and the fact that in Symfony, we need to return a Response object, and in .NET, we can return a string (that will be wrapped into the correct HTML tags).

Folder structures and namespaces

While not strictly necessary, C# usually follows a namespacing/folder structure identical to PHP's PSR-4 standard. This definitely simplifies navigating through the code.

What's next?

We didn't explore routing and rendering/templating in-depth, so those two topics will come next.
Feel free to leave a comment or reach out!

Top comments (0)