Elanat Competes with Microsoft; CodeBehind 2.4 Released
Tags: news, backend, performance, github
Published: 2024-03-05 13:14:12

About 8 months have passed since the birth of the [CodeBehind framework](https://github.com/elanatframework/Code_behind). In these 8 months, we have released 29 new versions with revolutionary innovations, performance improvements and new features; we have now released version 2.4; CodeBehind framework version 2.4 is the 30th version of this framework.

CodeBehind is a very powerful framework that is superior to the default ASP.NET Core structures (Razor pages and MVC) in every way.

**CodeBehind is .NET Diamond!**

CodeBehind framework belongs to Elanat team. We at [Elanat](https://elanat.net) want to make CodeBehind a valuable option for .NET developers.

# CodeBehind 2.4

In version 2.4, a new feature has been added to configure the Route for running the Controllers. We also rewrote some code and made some positive changes to how the final View class is created. We changed the way of calling View files to build and compile the View class to multi-threaded mode; this change makes the creation and recompilation of the View class up to 4 times faster. In this version, we have improved Razor syntax (`@Razor`) and standard syntax (`<%=standard%>`) so that you have a more comfortable experience for creating View pages.

## New feature for route configuration

CodeBehind is created based on a unique MVC architecture where there is no need to configure the Controller in the Route. In this architecture, the Controller is determined like a Model in the View pages, then the requests process first reach the View and the View creates an instance of the Controller class.

Because some developers may still be interested in configuring the Controller in the Route, we added a new feature to configure the Controller in the Route in the CodeBehind framework.

Compared to ASP.NET Core, the CodeBehind framework provides a dynamic and modular configuration Controller in route.

Example:
Route configuration in the CodeBehind framework
```csharp
var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

SetCodeBehind.CodeBehindCompiler.Initialization();

app.Run(async context =>
{
    CodeBehind.CodeBehindExecute execute = new CodeBehind.CodeBehindExecute();
    await context.Response.WriteAsync(execute.RunRoute(context, 0));
});

app.Run();
```

The code above shows the Route configuration in the CodeBehind framework in the `Program.cs` class. The `RunRoute` method takes two arguments. The first argument is the context and the second is the section that specifies the Controller.

Note: Section means the strings between slash characters.
Example: `example.com/section0/section1/section2`

If we set the section value to 0, if there is a Controller with the same name as the value of the first section, the `RunRoute` method will execute the Controller.

Example:

CodeBehind Controller
```csharp
using CodeBehind;

namespace YourProjectName
{
    public partial class home : CodeBehindController
    {
        public void PageLoad(HttpContext context)
        {
            Write("Route work fine");
        }
    }
}
```

According to the Controller class above, if the path `example.com/home` is requested, the Controller class above is executed and the `Route work fine` string is returned.

If the name of the Controller class matches the section in the url, Regardless of the namespace, the Controller class is executed.
The Controller class name is case sensitive. Therefore, the path `example.com/Home` cannot execute the Controller with the class name home.

This process is modular, so if you have an external dll that contains the Controller class of the CodeBehind framework, you can copy it to `wwwroot/bin` to call the Controller class.

Unlike the weak default structure of MVC in ASP.NET Core, the process of executing the Controller is dynamic and there is no need to create methods with `IActionResult` output; as a result, instead of a hard connection and full dependency, you will have a loose connection and little dependency.

Example:

Dynamic Controller in CodeBehind
```csharp
using CodeBehind;

namespace YourProjectName
{
    public partial class home : CodeBehindController
    {
        public void PageLoad(HttpContext context)
        {
            if (Section.Count() < 2)
            {
                Write("This is main page");
                return;
            }

            switch (Section.GetValue(1))
            {
                case "first": View("/page1.aspx"); break;
                case "second": View("/page2.aspx"); break;
                case "third": View("/page3.aspx"); break;
                case "fourth": View("/page4.aspx"); break;
            }
        }
    }
}
```

The code above shows a Controller that returns the string `This is main page` if there is no other section after section main. If another section named first, second, third, and fourth is requested after the main section, the pages `page1.aspx`, `page2.aspx`, `page3.aspx` and `page4.aspx` will be returned respectively.

Example:

Requesting `example.com/main/first` returns the page page1.aspx.

## The possibility of running the Controller with the text name of the Controller 

In version 2.4 of the Elanat framework, we added a new overload for the RunController method; in this new overload method, you can execute a controller with just the name of the Controller's text string.

The `RunController` method is located in the `CodeBehindExecute` class, and the method input is the name of a Controller class.

The example below is a change in the configuration type in the `Program.cs` class, which calls a Controller named `MyController` when the request route starts with `/path/`.

Program.cs
```csharp
using CodeBehind;

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

SetCodeBehind.CodeBehindCompiler.Initialization();

app.Run(async context =>
{
    CodeBehindExecute execute = new CodeBehindExecute();

    if (context.Request.Path.HasMatching("start_with", "/path/"))
    {
        await context.Response.WriteAsync(execute.RunController("MyController", context));
    }

    await context.Response.WriteAsync(execute.Run(context));
});

app.Run();
```

The `RunController` method also executes the Controller class that is in the external DLLs located in the `wwwroot/bin` path.

Note: Only the name of the Controller class must be written without namespace.

## Applying multi-threaded processing to create the View class

In version 2.4 of the CodeBehind framework, the view collection process is multi-threaded. This process increases the speed of creating the final View class up to 4 times.

[Elanat CMS](https://github.com/elanatframework/Elanat) has nearly 600 View files. With a mid-range processor it only takes 9 seconds to compile View. It is interesting to know that in previous versions, it took about 35 seconds to compile View pages in Elanat CMS.

Please note that the compilation process is done only once; so you don't need to worry about the compilation time.

Note: The new version of Elanat CMS has not been released yet. Elanat CMS version 2.2 will be released soon and the latest version of the CodeBehind framework will be updated.

## Page attributes with lowercase

According to the requests of users, we abandoned the policy of requiring uppercase for page attributes in the standard syntax.

From now on, you can write all page attributes in the standard syntax with lowercase letters.

Example:
```html
<%@ page
controller="MyController"
model="MyModel"
layout="/layouts/main.aspx"
template="/templates/responsive_table.astx"
islayout="true"
break="true"
section="true"
%>
```

**List of acceptable page attributes:**
 - Page or page
 - Controller or controller
 - Model or model
 - Layout or layout
 - Template or template
 - IsLayout or islayout
 - Break or break
 - Section or section

## Ability to add text tag with multiple lines in Razor syntax

When using Razor syntax, using the `text` tag in the extension blocks allows you to separate the required text from the server-side programming code. Before the 2.4 version of the CodeBehind framework, you could use the `text` tag only in one line; but in version 2.4 and later, you can use the `text` tag in multiple lines.

Example:
```html
@page
...
@if (!AcceptCookieMessage)
{
    <text><script>
        $(window).load(function() {
            // init Isotope
            var $projects = $('.projects').isotope({
                itemSelector: '.project',
                layoutMode: 'fitRows'
            });
            $(".filter-btn").click(function() {
                var data_filter = $(this).attr("data-filter");
                $projects.isotope({
                    filter: data_filter
                });
                $(".filter-btn").removeClass("active");
                $(".filter-btn").removeClass("shadow");
                $(this).addClass("active");
                $(this).addClass("shadow");
                return false;
            });
        });
    </script></text>
}
```

As you can see in the code above, using the `text` tag in multiple lines helps to better manage the display part in the server code.

## Problems that were solved

 - **Fixed the problem of finding the Microsoft.AspNetCore.App directory for some operating systems**

In the previous versions, the path of the `Microsoft.AspNetCore.App` directory was determined according to the `Microsoft.NetCore.App` path; for some operating systems this type of routing did not work. In version 2.4, the path of `Microsoft.AspNetCore.App` directory is determined automatically.

 - **Fixed problem matching projects whose name does not match for namespace name.**

The CodeBehind framework creates a new namespace from the project name in the final View class. When you create a new project, you may use characters in the project name that are unacceptable to create a namespace and the final View class will not compile. We at Elanat team solved this problem in version 2.4 of the CodeBehind framework.

The new namespace is created only based on uppercase and lowercase English letters, numbers, and the underscore character (_), and the underscore character replaces other characters (such as dot and space). If the project name starts with numbers, an underscore character is added to the name of the new namespace.

> Example:
> Project name: `123.Project - New-Module`
> New namespace name: `_123_Project___New_Module`

Note: The name of the new namespace is placed in the first line of the `views_class.cs.tmp` file located in the `code_behind` directory.

## Related links

CodeBehind on GitHub:
https://github.com/elanatframework/Code_behind

Get CodeBehind from NuGet:
https://www.nuget.org/packages/CodeBehind/

CodeBehind page:
https://elanat.net/page_content/code_behind