Introduction
CodeBehind is a flexible web back-end framework based on ASP.NET Core. CodeBehind was developed by Elanat in 2023 and competes with Microsoft’s default web frameworks (ASP.NET Core MVC and Razor Pages and Blazor). The type of structure and naming in CodeBehind is a nostalgia that reminds of former Microsoft Web-Forms.
Added support for Web-Forms controls
After the release of CodeBehind framework version 2.8, we at Elanat team promised to bring Web-Forms back to ASP.NET Core; we kept our promise and added the new Web-Forms structure in version 2.9 of the CodeBehind framework.
The new Web-Forms structure is one of the new revolutionary ideas of the Elanat team, where all HTML tags are managed on the server.
The new Web-Forms is an engineering masterpiece that consists of a JavaScript component called WebFormsJS and a server-side response structure that automatically communicates with a proprietary protocol.
CodeBehind framework Web-Forms example
Before we explain the structure of Web-Forms in the CodeBehind framework, we will show you the stunning functionality of WebFormJS with an example.
Note: In the header of the layout.aspx file, the following script tag has been added in the head section.
<script type=”text/javascript” src=”/script/web-forms.js”></script>
View (MyPage.aspx)
@controller MyController
@layout “/layout.aspx”
<form method=“post” action=“/MyPage.aspx” >
<label for=“txt_Name”>Your Name:</label>
<input name=“txt_Name” id=“txt_Name” type=“text” />
<br>
<label for=“txt_FontSize”>Set Font Size</label>
<input name=“txt_FontSize” id=“txt_FontSize” type=“number” value=“16” min=“10” max=“36” />
<br>
<h3>Which framework is under ASP.NET Core?</h3>
<input value=“1” name=“rdbtn_RadioButton” id=“rdbtn_RadioButton1” type=“radio” checked=“” /><label id=“rdbtn_RadioButtonLabel1” for=“rdbtn_RadioButton1”>ASP.NET Core MVC</label>
<input value=“2” name=“rdbtn_RadioButton” id=“rdbtn_RadioButton2” type=“radio” /><label id=“rdbtn_RadioButtonLabel2” for=“rdbtn_RadioButton2”>Razor Pages</label>
<input value=“3” name=“rdbtn_RadioButton” id=“rdbtn_RadioButton3” type=“radio” /><label id=“rdbtn_RadioButtonLabel3” for=“rdbtn_RadioButton3”>Blazor</label>
<input value=“4” name=“rdbtn_RadioButton” id=“rdbtn_RadioButton4” type=“radio” /><label id=“rdbtn_RadioButtonLabel4” for=“rdbtn_RadioButton4”>CodeBehind Framework</label>
<input value=“5” name=“rdbtn_RadioButton” id=“rdbtn_RadioButton5” type=“radio” /><label id=“rdbtn_RadioButtonLabel5” for=“rdbtn_RadioButton5”>All options</label>
<br>
<br>
<input name=“btn_Button” type=“submit” value=“Click to send data” />
</form>
There are several inputs in the View page. Input the name and font size and several radio buttons that form the answers to a 5-choice question. A submit button called btn_Button has been added to send data to the server.
Controller (MyController class)
public partial class MyController : CodeBehindController
{
public void PageLoad(HttpContext context)
{
if (!string.IsNullOrEmpty(context.Request.Form[“btn_Button”]))
btn_Button_Click(context);
}
private void btn_Button_Click(HttpContext context)
{
IgnoreAll();
string Name = context.Request.Form[“txt_Name”];
int FontSize = context.Request.Form[“txt_FontSize”].ToNumber();
int RadioButtonValue = context.Request.Form[“rdbtn_RadioButton”].ToNumber();
WebForms Form = new WebForms();
Form.SetFontSize(InputPlace.Tag(“body”), FontSize);
Form.SetBackgroundColor(InputPlace.Id(“rdbtn_RadioButtonLabel5”), “green”);
Form.SetDisabled(InputPlace.Name(“btn_Button”), true);
if (RadioButtonValue == 5)
Form.SetText(InputPlace.Tag(“h3”), Name + “, you answered correctly!”);
else
{
Form.SetText(InputPlace.Tag(“h3”), Name + “, your answer is not correct!”);
Form.SetBackgroundColor(InputPlace.Id(“rdbtn_RadioButtonLabel” + RadioButtonValue), “red”);
}
Control(Form);
}
}
The PageLoad method is the default method in the Controller class in the CodeBehind framework, which is executed along with the Controller call. In the PageLoad method, we first determine whether the btn_Button value exists in the form data or not. If there is, the btn_Button_Click method is executed to respond to the user.
In the btn_Button_Click method, the IgnoreAll method is first called to disable the View and Layout values. If we don’t call this method, then it has no effect, but sends the View data again, which is not suitable in terms of performance. We put the input data of the three values of the name and font size and the response of the radio button from the form data into three variables; then we create an instance of the WebForms class.
Initialization to the WebForms class:
We call the SetFontSize method for the body tag and set its value equal to the value received from the font size input.
The call type of the SetFontSize method determines the font size of the body tag.
Set the SetBackgroundColor method for the label tag to the correct answer (with the id rdbtn_RadioButtonLabel5) with the string green.
The call type of the SetBackgroundColor method sets the background color of the tag with the id rdbtn_RadioButtonLabel5 to green.
We set the SetDisabled method for the button named btn_Button with the correct value (true).
Calling the SetFontSize method disables the btn_Button tag so that it cannot be clicked again.
We check if the correct answer was entered, by calling the SetText method, we value the text inside the h3 tag by combining the received input name and the correct answer string.
The type of call to the SetText method causes the received name to be combined with a string you answered correctly and placed inside the h3 tag.
If the answer is not correct, by calling the SetText method, we set the text inside the h3 tag by combining the received input name and the wrong answer string.
The type of call to the SetText method causes the received name to be combined with a your answer is not correct string and placed inside the h3 tag.
If the answer is not correct, the SetBackgroundColor method is called and the background color of the label tag with the incorrect answer is red.
Calling method SetBackgroundColor turns the background color of the tag with label id red. The label id tag is obtained from the combination of the rdbtn_RadioButtonLabel string and the value received from the radio button input.
Finally, we place the created instance of theWebForms class in the Control method.
You can see the wonderful structure of Web-Forms in the CodeBehind framework in the screenshot below.
The following values are the server response received after clicking the button. These values are interpreted in WebFormsJS.
Server response
fs<body>=22px
bcrdbtn_RadioButtonLabel5=green
sd(btn_Button)=1
st<h3>=Fred, your answer is not correct!
bcrdbtn_RadioButtonLabel1=red
In the following, we fully explain the functionality of WebFormsJS.
This is a simple example of the new Web-Forms functionality in the CodeBehind framework. This is the first version of CodeBehind to which the Web-Forms structure has been added. We at Elanat will increase the performance of Web-Forms in newer versions.
If you are familiar with a back-end framework, please tell us in the comments section how you implement this example in that framework?!
WebFormsJS
WebFormsJS is a JavaScript library that provides the infrastructure for interacting with web controls in the CodeBehind framework; this allows developers to easily manage HTML tags on the server-side.
WebFormsJS is a new architecture similar to Microsoft’s former Web-Forms, but has none of its disadvantages. The performance of WebFormsJS is much more than the previous Web-Forms, so that it manages all HTML tags.
Using WebFormsJS allows the developers to focus on the server response and therefore there is no need to develop the front side and the developers set the controls on the server-side. WebFormsJS can also be used outside of the CodeBehind framework. In the rest of this article, we teach how to set the server response to interact with WebFormsJS.
The bandwidth consumption when using WebFormsJS is very low. WebFormsJS is like a gasoline car that absorbs carbon pollution as much as it pollutes the air.
When you run the CodeBehind framework for the first time, WebFormsJS will be automatically created in the /wwwroot/script/web-forms.js path.
Advantages of using WebFormsJS:
WebFormsJS provides features like postback, progress bar and script extraction.
WebForms is an advanced system that can be run with simple HTML pages without View or server script pages.
WebFormsJS automatically sends form data through AJAX. WebFormsJS serializes form data as a string or a FormData object, depending on whether the form is multipart or not.
Using WebFormsJS reduces the complexity of web development.
PostBack and GetBack method
PostBack and GetBack are two methods in WebFormsJS.
PostBack requests the URL string in the condition that it also transfers the input data to the server. The PostBack method should only be used inside a form tag. The PostBack method is automatically activated on submit type inputs.
GetBack only requests the URL string regardless of the input data. The URL string can also contain the query string. The GetBack method can be used without the form tag on the page.
There are three overloads for the GetBack method:
GetBack(): Requests the current URL path executed in the browser.
GetBack(this): should be used only in situations where the form tag must be present on the page. If executed inside a form, the action path requests the form, otherwise it requests the path of the first form on the page.
GetBack(“YourURL”): Requests the URL path entered as an argument.
New options
These are the default values in the CodeBehind framework options file. This file is created in the following path:
code_behind/options.ini
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}
prevent_access_default_aspx=false
default_role=guest
+web_forms_script_path=/script
+auto_create_web_forms_script=true
+recreate_web_forms_script_after_recompile=false
+web_forms_view_place=<body>
In version 2.9 of the CodeBehind framework, 4 new options have been added to the options file, all of which are related to WebFormsJS settings.
The web_forms_script_path option specifies the path to the WebFormsJS file. According to the /script value, the WebFormsJS file is created in the following path:
/script/web-forms.js
If the auto_create_web_forms_script option is enabled, the WebFormsJS file will be created automatically.
If the recreate_web_forms_script_after_recompile option is enabled, the WebFormsJS file will be created after each compile.
The web_forms_view_place option is for situations where the Action Control is not present in the response and determines the tag location of the server’s response.
Action Controls
Action Controls are WebFormsJS received codes that are received in INI format. WebFormsJS automatically detects whether the server response has Action Controls or not. If the server’s response is based on the structure of an INI file that starts with [web-forms], it will process the Action Controls, otherwise it will replace the server’s response in the form of AJAX on the page.
Example of received Action Controls:
as<body>=background-color:green
saCheckBoxInput=onchange|MyNewFunc()
deMyTagId=1
ta<i>2=right
aoSelectInput=OptionValue|Option Text|1
al(InputName)=My Input Title
Line 1: as<body>=background-color:green
Here, the first two characters are as, which means adding a style, and then it is specified that it will be applied to the body tag, and after the equal character (=), the style attribute is specified.
Line 2: saCheckBoxInput=onchange|MyNewFunc()
Here, the first two characters are sa, which means adding an attribute, and then it is specified that it will be applied to a tag with the id CheckBoxInput, and after the equal character (=), the name and value of the attribute is specified, which is specified by the character (|) are separated.
Line 3: deMyTagId=1
Here, the first two characters are de, which means to delete the tag, and then it is determined that it will be applied to a tag with the id MyTagId, and after the equal character (=) there is a value of 1, which means to apply deletion.
Line 4: ta<i>2=right
Here, the first two characters are ta, which means text align, and then it is determined that it will be applied to a third tag named li, and after the equal character (=) there is a value of right which means right to left.
Line 5: aoSelectInput=OptionValue|Option Text|1
Here, the first two characters are ao, which means adding the option tag, and then it is specified that it will be applied to a tag with the id name SelectInput, and after the equal character (=), the option value is placed, and after the character (|) option text is placed and at the end after the (|) character is the number 1, which means that the option is active (checked).
Line 6: al(InputName)=My Input Title
Here, the first two characters are al, which means adding a title, and then it is specified that it will be applied to a tag named InputName, and after the equal character (=), the title text is specified.
Explanation of the action controls
Action controls are received in the form of an INI file format. In the first line of the response there is the word [web-forms] and each of the following lines is an action control.
The first two characters determine the action code. For example, things like adding styles and removing tags can be obtained from action codes. The first two letters stand for actions and indicate that an action must be performed.
After the first two letters, there are 6 status types that specify the tag. Then the equal character is placed and after that the values are placed.
Below is the list of all action codes:
Add
The following items are added to the available amount:
ai: Add Id – Value: Id
an: Add Name – Value: Name
av: Add Value – Value: Value
ac: Add Class – Value: Class
as: Add Style – Value: Style
ao: Add Option Tag – Value: Value|Text|1 or 0
ak: Add CheckBox Tag – Value: Value|Text|1 or 0
al: Add Title – Value: Title
at: Add Text – Value: Text (string value $[ln]; it replaces by n character)
aa: Add Attribute – Value: Attribute|Value
nt: Add Tag – Value: TagName|Id
Set
The following replaces the existing values:
si: Set Id – Value: Id
sn: Set Name – Value: Name
sv: Set Value – Value: Value
sc: Set Class – Value: Class
ss: Set Style – Value: Style
so: Set Option Tag – Value: Value|Text|1 or 0
sk: Set Checked – Value: For input with checked type 1 or 0 – For any tags Value|Text|1 or 0
sl: Set Title – Value: Title
st: Set Text – Value: Text (string value $[ln]; it replaces by n character)
sa: Set Attribute – Value: Attribute|Value
sw: Set Width – Value: Width
sh: Set Height – Value: Height
bc: Set Background Color – Value: Color
tc: Set Text Color – Value: Color
fn: Set Font Name – Value: Name
fs: Set Font Size – Value: Size
fb: Set Font Bold – Value: 1 or 0
vi: Set Visible – Value: 1 or 0
ta: Set Text Align – Value: Align
sr: Set Read Only – Value: 1 or 0
sd: Set Disabled – Value: 1 or 0
mn: Set Min Length – Value: Length
mx: Set Max Length – Value: Length
ts: Set Selected Value – Value: Value
ti: Set Selected Index – Value: Index
ks: Set Checked Value – Value: Value|1 or 0
ki: Set Checked Index – Value: Index|1 or 0
Insert
The following items are added only if there are no pre-existing values:
ii: Insert Id – Value: Id
in: Insert Name – Value: Name
iv: Insert Value – Value: Value
ic: Insert Class – Value: Class
is: Insert Style – Value: Style
io: Insert Option Tag – Value: Value|Text|1 or 0
ik: Insert CheckBox Tag – Value: Value|Text|1 or 0
il: Insert Title – Value: Title
it: Insert Text – Value: Text (string value $[ln]; it replaces by n character)
ia: Insert Attribute – Value: Attribute|Value
Delete
The following will remove the current values:
di: Delete Id – Value: 1
dn: Delete Name – Value: 1
dv: Delete Value – Value: 1
dc: Delete Class – Value: Class
ds: Delete Style – Value: Style (only the style name is entered without a value)
do: Delete Option Tag – Value: Value
dk: Delete CheckBox Tag – Value: Value
dl: Delete Title – Value: 1
dt: Delete Text – Value: 1
da: Delete Attribute – Value: Attribute
de: Delete Tag – Value: 1
Increase
The following increment the current numeric values:
+n: Increase Minimum Length – Value: Number
+x: Increase Maximum Length – Value: Number
+f: Increase Font Size – Value: Number
+w: Increase Width – Value: Number
+h: Increase Height – Value: Number
+v: Increase Value – Value: Number
Descrease
The following decrease the current numerical values:
-n: Descrease Minimum Length – Value: Number
-x: Descrease Maximum Length – Value: Number
-f: Descrease Font Size – Value: Number
-w: Descrease Width – Value: Number
-h: Descrease Height – Value: Number
-v: Descrease Value – Value: Number
Note: Action controls are executed sequentially; if an action control decides to change an id attribute from a tag, subsequent action controls cannot perform actions with the previous id attribute.
Define the tag
After the first two characters, there are 6 status types that define the tag:
Based on id: Based on the name of the id, it recognizes the tag and the character (=) is placed immediately after it.
By name: Identifies the tag based on the name attribute. It is placed in open and closed parentheses ((Name)), and if a number is placed after it, it specifies the index, and then the (=) character is placed after it.
Based on the tag name: Based on the tag name, it recognizes the tag. It is placed inside the smaller and larger signs (<tag name>)), and if a number is placed after it, it specifies the index, and then the (=) character is placed after it.
Based on class name: Identifies the tag based on the class name. It is placed in open and closed brackets ({class name}), and if a number is placed after it, it specifies the index, and then the character (=) is placed after it.
Based on query: Identifies the tag based on the query. The query string is placed after the (*) character , and then the character (=) is placed after it. If there are equal characters (=) in the query value, they should be replaced by $[eq]; string.
Based on query all: It applies to multiple tags and identifies tags based on “query”. The query string is placed after the ([) character , and then the character (=) is placed after it. If there are equal characters (=) in the query value, they should be replaced by $[eq]; string.
Note: By default, the indexes of the name, class name, and tag name are set to 0.
Example: Action control with the value de<li>=1 is not different from the value de<li>0=1.
You can also specify the desired tag nested (query all is not supported in this case).
Example:
at>{my-class}1|<u>|<li>2=My text string
In the example above, the My text string is placed inside the third li tag which is inside the first ul tag, and the ul tag itself is a tag inside the tag whose class is equal to the value of my-class.
Possibility to ignore Layout
One of the new features in this version is the ability to disable Layout. From now on, you can disable Layout in the Controller, Model, and View sections. Disabling Layout is useful when we want to change page content using AJAX.
To disable Layout, you need to enable the IgnoreView attribute.
Ignore View through Model class
When you use the MVC pattern in the CodeBehind framework, you can disable View and Model. In the Controller class, there is an attribute named IgnoreViewAndModel attribute, and if you activate the IgnoreViewAndModel attribute, it will ignore the values of Model and view and you will only see a blank page; this feature allows you to display the values you need to the user and avoid multiple redirects and transfers.
Now in version 2.9 and later you can develop your systems based on the Model-View structure and disable the View in the Model class.
To disable the View in the Model class, you need to enable the IgnoreView attribute.
Note: This possibility only includes Model classes that have CodeBehindModel abstract class.
IgnoreAll method
IgnoreAll is a new method added in the Controller abstract class and the Model abstract class.
Calling the IgnoreAll method in the Controller class causes the IgnoreViewAndModel and IgnoreLayout attributes to be activated.
Calling the IgnoreAll method in the Model class causes the IgnoreView and IgnoreLayout attributes to be activated.
Automatic moving dll files
In this version, if the move_view_from_wwwroot option is enabled in the options file, and the view_path option is set to a path other than wwwroot, all dll files will be automatically moved from the wwwroot/bin path to the bin directory in the view_path path.
Related links
CodeBehind on GitHub:
https://github.com/elanatframework/Code_behind
CodeBehind in NuGet:
https://www.nuget.org/packages/CodeBehind/
CodeBehind page:
https://elanat.net/page_content/code_behind
WebFormsJS on GitHub:
https://github.com/elanatframework/Web_forms