CodeBehind Framework 2.2 Released
Tags: news, dotnet, backend, csharp
Published: 2024-01-26 16:50:52

[CodeBehind Framework](https://github.com/elanatframework/Code_behind) is the most serious competitor of ASP.NET Core. The [Elanat team](https://elanat.net) has created the CodeBehind framework based on a specific, unique and very modern architecture; in this architecture, the controller is determined (like the model) in the view pages, and there is no need to configure the controller in the route anymore; therefore, in the CodeBehind framework, it is possible to create different parts of a system at the same time in the form of MVC, Model-View, and only view.

# CodeBehind 2.2

The Elanat team has released version 2.2 of the CodeBehind framework with the big update. The Elanat team has focused on ease of use for developers to deliver the 2.2 version of the CodeBehind framework. Version 2.2 includes a revolutionary new idea from the Elanat team that will surprise you.

## Caller view path

CallerViewPath and CallerViewDirectoryPath are two new attributes that are available in all three sections of Controller, Model, and View.

CallerViewPath holds the path of the view file and CallerViewDirectoryPath holds the path of the view file without the name and extension of the view file.

The CallerViewPath value is most commonly used in the controller; if you have several views that have a controller, you can find out the path of the view that called the controller by checking the CallerViewPath.

Example
```csharp
using CodeBehind;

namespace YourProjectName
{
    public partial class DefaultController : CodeBehindController
    {
        public DefaultModel model = new DefaultModel();
        public void PageLoad(HttpContext context)
        {
            switch (CallerViewPath)
            {
                case "/page/slideshow/View1.aspx": model.Title = "View1"; break;
                case "/page/slideshow/View2.aspx": model.Title = "View2"; break;
                case "/page/slideshow/View3.aspx": model.Title = "View3"; break;
                case "/page/slideshow/View4.aspx": model.Title = "View4"; break;
            }

            View(model);
        }
    }
}
```

## Better control over errors

In version 2.2, we separated the errors related to the compilation of view pages. Previously, all errors were displayed in the views_compile_error.log file; now we have isolated minor errors that do not cause problems for compilation and added an option to display minor errors in the options file; if this option is disabled, only compilation errors will be displayed, and if enabled, other less important errors will also be displayed.

For example, if you create a variable and do not use it anywhere in the method or class, a minor error will occur, but the compilation will be done.

```diff
view_path=wwwroot
move_view_from_wwwroot=true
rewrite_aspx_file_to_directory=false
access_aspx_file_after_rewrite=false
ignore_default_after_rewrite=true
start_trim_in_aspx_file=true
inner_trim_in_aspx_file=true
end_trim_in_aspx_file=true
set_break_for_layout_page=true
convert_cshtml_to_aspx=false
+show_minor_errors=false
error_page_path=/error.aspx/{value}
```

## Error handling

We added an error page to the default CodeBehind template. We also added the path to the same error page in the options file. In the error page, we activated the section page attribute by default (in the rest of the article, we will introduce the section attribute). If you look carefully at the path of the error page in the options file, you will see the value value surrounded by two brackets. This is a variant and the numeric value of the error replaces this variant.

```diff
view_path=wwwroot
move_view_from_wwwroot=true
rewrite_aspx_file_to_directory=false
access_aspx_file_after_rewrite=false
ignore_default_after_rewrite=true
start_trim_in_aspx_file=true
inner_trim_in_aspx_file=true
end_trim_in_aspx_file=true
set_break_for_layout_page=true
convert_cshtml_to_aspx=false
show_minor_errors=false
+error_page_path=/error.aspx/{value}
```

Example
`/error.aspx/500`

According to the path above, the value 500 is substituted for the {value} variant.

You can call up the error page according to the type of error. The following example is an implemented example of error handling in the CodeBehind framework.

Program.cs class
```csharp
using CodeBehind;
using SetCodeBehind;

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

CodeBehindCompiler.Initialization();

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

    string PageResult = execute.Run(context);

    if (execute.FoundPage)
        await context.Response.WriteAsync(PageResult);
    else
        await context.Response.WriteAsync(execute.RunErrorPage(404, context));
});

app.Run();
```

The example above shows a not found error. `FoundPage` attribute and `RunErrorPage` method have been added in the `CodeBehindExecute` class. According to the above codes, the `Run(context)` method puts the executable file string in the PageResult variable. If a page is not found, the FoundPage attribute is set to false. The `RunErrorPage(404, context)` method also calls the error page.

Note: If you do not need to use context in the error page, you can call the RunErrorPage method without context.
`RunErrorPage(404)`

Please note that to use the RunErrorPage method, you must create the error view file and set its path in the options file. Of course, if you create a new project under ASP.NET Core 7.0 Empty for the first time and there is no wwwroot directory in your project, if you run the project once, the default CodeBehind framework template along with the view error file will be added.

## CodeBehindConstructor without arguments

From version 2.2 onwards, you can also call the CodeBehindConstructor method without requiring an input argument. To call, just add open and close parentheses without input data in front of the controller or model class name.

We used to encourage developers to add constructor methods with the same name as the controller or model class name; for this reason, we did not allow the CodeBehindConstructor method to be created without an input argument; but due to the addition of new features, constructor methods will not have access to some attributes and facilities; so now we recommend that developers use the CodeBehindConstructor method in the controller and model. Of course, the PageLoad method can still be used in the controller.

Example of determining the CodeBehindConstructor method in view pages (Razor syntax)
```diff
@page
+@controller YourProjectName.DefaultController()
+@model YourProjectName.DefaultModel()
<!DOCTYPE html>
<html>
<head>
<title><%=model.Title%></title>
...
```

Example of determining the CodeBehindConstructor method in view pages (standard syntax)
```html
<%@ Page Controller="YourProjectName.DefaultController()" Model="YourProjectName.DefaultModel()" %>
<!DOCTYPE html>
<html>
<head>
<title>@model.Title</title>
...
```

Example of creating the CodeBehindConstructor method in the controller
```csharp
using CodeBehind;

namespace YourProjectName
{
    public partial class DefaultController : CodeBehindController
    {
        public DefaultModel model = new DefaultModel();

        public void CodeBehindConstructor()
        {
            model.Title = "My page has controller constructor";
            View(model);
        }
    }
}
```

Example of creating the CodeBehindConstructor method in the model
```csharp
using CodeBehind;

namespace YourProjectName
{
    public partial class DefaultModel : CodeBehindModel
    {
        public string Title { get; set; } = "";

        public void CodeBehindConstructor()
        {
            Title += " and model constructor";
        }
    }
}
```

## Controller class without PageLoad method

From version 2.2 onwards, it is no longer required to add the PageLoad method in the controller.

Controller example without PageLoad method
```diff
using CodeBehind;

namespace YourProjectName
{
    public partial class DefaultController : CodeBehindController
    {
-       public void PageLoad(HttpContext context)
-       {

-       }
    }
}
```

Please note that the constructor methods (not to be confused with the CodeBehindConstructor method) in the controller do not have full access to the controller's attributes.

Example
```csharp
using CodeBehind;

namespace YourProjectName
{
    public partial class DefaultController : CodeBehindController
    {
        public DefaultController()
        {
            // Your Code
        }
    }
}
```

Adding a **constructor method is not a good idea**; this makes you not have access to some attributes of the page.

## Model class without abstract

In version 2.2 and later, the model class can be specified without the need for the CodeBehindModel abstract. If you put the value of the model attribute in the view pages in open and closed brackets, there is no need to add the CodeBehindModel abstract.

Example of add method without abstract in Razor syntax
```diff
@page
+@model {YourProjectName.DefaultModel}
<!DOCTYPE html>
<html>
...
```

Example of add method without abstract in standard syntax
```html
<%@ Page Model="{YourProjectName.DefaultModel}" %>
<!DOCTYPE html>
<html>
...
```

If we don't put the model in the open and close brackets, we have to add the CodeBehindModel abstract.

Example
```diff
using CodeBehind;

namespace YourProjectName
{
+   public class DefaultModel : CodeBehindModel
    {

    }
}
```

But if we put the model in open and closed brackets, there is no need to add the CodeBehindModel abstract.

Example
```diff
using CodeBehind;

namespace YourProjectName
{
+   public class DefaultModel
    {

    }
}
```

## Section

Section is a new attribute that applies to aspx pages.

Section is a new feature whose activation makes all paths after the aspx path refer to the current aspx path.

Section is one of the latest revolutionary ideas of the Elanat team. Enabling section in aspx pages gives you full control over the paths.

Example of section activation in Razor syntax
```diff
@page
+@section
<!DOCTYPE html>
<html>
...
```

Example of section activation in standard syntax
```html
<%@ Page Section="true" %>
<!DOCTYPE html>
<html>
...
```

If you enable section in the `/page/about.aspx` path, any path added after the current path will be considered a section and the executable file in the `/page/about.aspx` path will still be executed.

Example
`/page/about.aspx/section1/section2/.../sectionN`

If you enable the section in an executable file called Default.aspx, you will still have access to the default path.

Example
`/page/about/Default.aspx/section1/section2/.../sectionN`
or
`/page/about/section1/section2/.../sectionN`

You will have access to section in all three sections, view, controller and model.

Example section in view (Razor syntax)
```html
<b>section 1 is: @Section.GetValue(0)</b>
```

Example section in view (standard syntax)
```html
<b>section 1 is: <%=Section.GetValue(0)%></b>
```

Example section in controller
```diff
using CodeBehind;

namespace YourProjectName
{
    public partial class DefaultController : CodeBehindController
    {
        public void PageLoad(HttpContext context)
        {
+           Write(Section.GetValue(0));
        }
    }
}
```

Example section in model
```diff
using CodeBehind;

namespace YourProjectName
{
    public partial class DefaultModel : CodeBehindModel
    {
        public void CodeBehindConstructor()
        {
+           Write(Section.GetValue(0));
        }
    }
}
```

Activating the section makes it no longer necessary to have a query string.

Please note that if you activate the section in a path, none of the view files (aspx) in the subdirectories of that path will be executed.

Example
`/page/about/Default.aspx`
If you enable the section in the path above, the path below will no longer be accessible.
`/page/about/license/Default.aspx`

You can use Exist method and check the existence of section values.

Example
```html
@if (!Section.Exist(0))
{
    <b>Value not exist</b>
}
```

We at Elanat team put a lot of effort into adding the section feature. Coordination of the section feature with the feature of rewriting aspx files as a directory was a very difficult and complicated process.

## Other cases

A series of minor new features have also been added in this version; we have also rewritten some codes and improved performance and provided a stable version.

**Some cases:**

 - The detection of code brackets in Razor syntax has also been improved
 - Added new number overloads for Write method of controller and model
 - Improve the debugging process
 - Add Set method in HtmlData class collections to avoid creating identical values
 - Rewriting some CodeBehindExecute class methods
 - Improved detection of apostrophes in code blocks in Razor syntax
 - Adding new application methods in the ExtensionMethodsClass class
 - Added new features in the view section

### Related links

[How to Use CodeBehind framework](https://github.com/elanatframework/Code_behind/blob/elanat_framework/doc/how_to_use_code_behind.md)

[CodeBehind on GitHub](https://github.com/elanatframework/Code_behind)

[CodeBehind in NuGet](https://www.nuget.org/packages/CodeBehind/)

[CodeBehind Website](https://elanat.net/page_content/code_behind)