<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Elanat Framework</title>
    <description>The latest articles on DEV Community by Elanat Framework (@elanatframework).</description>
    <link>https://dev.to/elanatframework</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1106033%2Fd06a8be3-da79-4eeb-ad53-1401e09446cc.png</url>
      <title>DEV Community: Elanat Framework</title>
      <link>https://dev.to/elanatframework</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elanatframework"/>
    <language>en</language>
    <item>
      <title>A New Approach to Form Data Handling in CodeBehind 4.7</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Sat, 05 Sep 2026 20:05:56 +0000</pubDate>
      <link>https://dev.to/elanatframework/a-new-approach-to-form-data-handling-in-codebehind-47-1ieh</link>
      <guid>https://dev.to/elanatframework/a-new-approach-to-form-data-handling-in-codebehind-47-1ieh</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/elanatframework/Code_behind" rel="noopener noreferrer"&gt;CodeBehind&lt;/a&gt; 4.7 introduces an important improvement to the way Form data is handled in incoming requests.&lt;/p&gt;

&lt;p&gt;From this version onward, Form data should no longer be accessed directly through &lt;code&gt;context.Request.Form&lt;/code&gt;. The internal structure responsible for injecting Form data into every request has been removed from the CodeBehind core.&lt;/p&gt;

&lt;p&gt;Previously, developers could use conditions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Button"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;Has&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;Button_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this approach is no longer supported. If a request does not contain Form content, attempting to access &lt;code&gt;context.Request.Form&lt;/code&gt; will cause an error. For example, if the incoming request is a GET request, the condition above attempts to read Form data from a request that does not contain Form content.&lt;/p&gt;

&lt;p&gt;To prevent this issue, Form data should only be accessed after verifying that the request contains Form content through &lt;code&gt;HasFormContentType&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;CodeBehind 4.7 also provides the &lt;code&gt;IfForm&lt;/code&gt; extension method as a simpler and safer solution. It allows developers to conditionally access Form data without directly attempting to read Form values from requests that do not contain Form content.&lt;/p&gt;

&lt;p&gt;The previous code can therefore be replaced with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IfForm&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;"Button"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;Has&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;Button_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;IfForm&lt;/code&gt; extension method provides a safer way to work with Form data and prevents unnecessary attempts to read Form values from requests that do not contain Form content.&lt;/p&gt;

&lt;p&gt;This improvement also reduces unnecessary processing inside the CodeBehind core. Since the Form data injection structure has been removed from the CodeBehind core, requests that do not require Form processing, such as GET requests, are no longer subject to unnecessary Form-related processing.&lt;/p&gt;

&lt;p&gt;This approach is particularly important because &lt;a href="https://elanat.net/page_content/code_behind" rel="noopener noreferrer"&gt;CodeBehind&lt;/a&gt; is designed around processing incoming requests through the &lt;code&gt;PageLoad&lt;/code&gt; method in the controller. In the recommended CodeBehind development pattern, submitted Form data is examined to identify the type of request, and the appropriate operation or event is executed based on the available data.&lt;/p&gt;

&lt;p&gt;For this reason, using conditions based on Form data is one of the primary approaches for handling different requests within a controller. With &lt;code&gt;IfForm&lt;/code&gt;, these checks can be performed safely, allowing requests such as GET requests, which do not contain Form content, to be processed without causing an error.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;PageLoad&lt;/code&gt; method can handle requests associated with different controls based on their Form data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;       
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IfForm&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;"run_test1"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;Has&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Button1_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IfForm&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;"run_test2"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;Has&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Button2_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IfForm&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;"run_test3"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;Has&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Button3_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightblue"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/contact"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this structure, Form requests are checked first. If the request contains the data associated with one of the operations, the corresponding method is executed and request processing ends. If the request does not correspond to any of these operations, execution continues through the &lt;code&gt;PageLoad&lt;/code&gt; method and the normal page content is processed.&lt;/p&gt;

&lt;p&gt;This pattern provides a simple, clear, and controlled structure for handling different types of requests within a single controller.&lt;/p&gt;

&lt;p&gt;The new approach provides a cleaner and more controlled way to process incoming requests while making Form data access safer and simpler for developers.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>codebehind</category>
      <category>webdev</category>
      <category>performance</category>
    </item>
    <item>
      <title>WebForms.php 2.1 Released - DeepSeek Converted and Qwen Evaluated</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Sat, 05 Sep 2026 18:18:20 +0000</pubDate>
      <link>https://dev.to/elanatframework/webformsphp-21-released-deepseek-converted-and-qwen-evaluated-284</link>
      <guid>https://dev.to/elanatframework/webformsphp-21-released-deepseek-converted-and-qwen-evaluated-284</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/webforms-core/php" rel="noopener noreferrer"&gt;WebForms.php&lt;/a&gt; 2.1 has been released as the PHP back-end implementation of WebForms Core 2.1.&lt;/p&gt;

&lt;p&gt;This release is different from a typical porting story.&lt;/p&gt;

&lt;p&gt;The PHP implementation was converted from the C# implementation of &lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; using DeepSeek, and then independently evaluated with Qwen.&lt;/p&gt;

&lt;p&gt;The process was not simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C# → PHP&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C# → DeepSeek conversion → manual review → Qwen evaluation → corrections → testing → release&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article explains that process and some of the interesting problems that appeared during the conversion.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is WebForms.php?
&lt;/h2&gt;

&lt;p&gt;WebForms.php is the PHP back-end part of WebForms Core.&lt;/p&gt;

&lt;p&gt;WebForms Core is a server-driven web technology based on the Commander–Executor concept.&lt;/p&gt;

&lt;p&gt;The server generates commands that describe UI operations and execution flow. &lt;a href="https://github.com/webforms-core/Web_forms" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;, running in the browser, interprets and executes those commands.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd720qck37abl66f8rn49.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd720qck37abl66f8rn49.jpg" alt="WebForms Core in PHP" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/webforms-core/Web_forms_classes" rel="noopener noreferrer"&gt;WebForms class&lt;/a&gt; itself does not manipulate the browser DOM directly.&lt;/p&gt;

&lt;p&gt;It generates the WebForms Core command structure.&lt;/p&gt;

&lt;p&gt;This makes the WebForms class particularly suitable for implementation in multiple programming languages.&lt;/p&gt;

&lt;p&gt;The PHP implementation provides the same WebForms Core programming model for PHP applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Convert the C# Implementation?
&lt;/h2&gt;

&lt;p&gt;WebForms Core already has implementations for multiple programming languages.&lt;/p&gt;

&lt;p&gt;The C# implementation is the primary reference implementation and contains a large number of methods for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DOM manipulation&lt;/li&gt;
&lt;li&gt;event management&lt;/li&gt;
&lt;li&gt;Fetch operations&lt;/li&gt;
&lt;li&gt;conditions&lt;/li&gt;
&lt;li&gt;loops&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;storage&lt;/li&gt;
&lt;li&gt;browser history&lt;/li&gt;
&lt;li&gt;WebSockets&lt;/li&gt;
&lt;li&gt;SSE&lt;/li&gt;
&lt;li&gt;templates&lt;/li&gt;
&lt;li&gt;selectors&lt;/li&gt;
&lt;li&gt;Action Controls&lt;/li&gt;
&lt;li&gt;and other WebForms Core operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The WebForms class mainly generates command strings.&lt;/p&gt;

&lt;p&gt;Because of this architecture, the fundamental logic does not need to be redesigned for every language.&lt;/p&gt;

&lt;p&gt;The objective of the PHP implementation was therefore to preserve the behavior and output of the C# implementation while adapting the code to PHP conventions and language capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  DeepSeek Conversion
&lt;/h2&gt;

&lt;p&gt;I provided the C# implementation and related helper classes to DeepSeek.&lt;/p&gt;

&lt;p&gt;The instructions were intentionally strict.&lt;/p&gt;

&lt;p&gt;DeepSeek was asked to first analyze the structure and explain the conversion approach.&lt;/p&gt;

&lt;p&gt;The important requirement was that the conversion should preserve the behavior of the C# implementation.&lt;/p&gt;

&lt;p&gt;However, the PHP implementation should not simply look like C# code written with PHP syntax.&lt;/p&gt;

&lt;p&gt;The destination language's conventions were explicitly required.&lt;/p&gt;

&lt;p&gt;For example, PHP naming conventions should be used where appropriate.&lt;/p&gt;

&lt;p&gt;A C# method such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nf"&gt;SetWidth&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;should become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;setWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and parameters should follow PHP naming conventions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$inputPlace&lt;/span&gt;
&lt;span class="nv"&gt;$width&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than preserving C#-style parameter names such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$InputPlace&lt;/span&gt;
&lt;span class="nv"&gt;$Width&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same principle applied to language features.&lt;/p&gt;

&lt;p&gt;If C# used a feature that did not exist in PHP, the conversion needed to use an appropriate PHP equivalent rather than attempting to reproduce the syntax literally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overloading Was One of the Interesting Problems
&lt;/h2&gt;

&lt;p&gt;C# supports method overloading.&lt;/p&gt;

&lt;p&gt;PHP does not support traditional method overloading based on parameter signatures in the same way.&lt;/p&gt;

&lt;p&gt;Therefore, overloaded C# methods needed to be represented using PHP language features where possible.&lt;/p&gt;

&lt;p&gt;For example, instead of creating unnecessary methods for different parameter types, PHP Union Types can be used.&lt;/p&gt;

&lt;p&gt;A method can accept:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and determine the appropriate behavior internally.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$width&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$width&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$width&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'px'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sw'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$width&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the public API compact while preserving the behavior expected from the overloaded C# methods.&lt;/p&gt;

&lt;p&gt;Nullable parameters were also handled using PHP's nullable types and default values.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can represent an optional second argument when converting an overloaded method such as a random-number operation.&lt;/p&gt;

&lt;p&gt;The important point is that the goal was not to reproduce the C# method signatures.&lt;/p&gt;

&lt;p&gt;The goal was to preserve their behavior using the capabilities of PHP.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First Review
&lt;/h2&gt;

&lt;p&gt;After the DeepSeek conversion, the generated code was reviewed manually.&lt;/p&gt;

&lt;p&gt;This was necessary because syntactically valid PHP does not necessarily mean behaviorally compatible PHP.&lt;/p&gt;

&lt;p&gt;The two languages have important differences in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;type conversion&lt;/li&gt;
&lt;li&gt;null handling&lt;/li&gt;
&lt;li&gt;method overloading&lt;/li&gt;
&lt;li&gt;string conversion&lt;/li&gt;
&lt;li&gt;arrays&lt;/li&gt;
&lt;li&gt;optional parameters&lt;/li&gt;
&lt;li&gt;naming conventions&lt;/li&gt;
&lt;li&gt;object handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A port can therefore compile and run while still producing a different WebForms Core command.&lt;/p&gt;

&lt;p&gt;This is particularly important for WebForms Core because the generated command is effectively part of the protocol between the WebForms class and WebFormsJS.&lt;/p&gt;

&lt;p&gt;A small difference in generated output can therefore become a functional difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qwen Evaluation
&lt;/h2&gt;

&lt;p&gt;After the initial conversion, I gave the PHP implementation to Qwen for an independent evaluation.&lt;/p&gt;

&lt;p&gt;The purpose was not to ask Qwen to rewrite the entire implementation.&lt;/p&gt;

&lt;p&gt;It was asked to evaluate the conversion and look for incompatibilities between the PHP implementation and the original C# behavior.&lt;/p&gt;

&lt;p&gt;This produced several useful findings.&lt;/p&gt;

&lt;p&gt;Two of them were particularly important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue 1: &lt;code&gt;implode()&lt;/code&gt; and Mixed-Type Arguments
&lt;/h2&gt;

&lt;p&gt;The C# implementation could use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;US&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;Args&lt;/code&gt; could contain objects or values of different types.&lt;/p&gt;

&lt;p&gt;C# converts the values to their string representation when joining them.&lt;/p&gt;

&lt;p&gt;The corresponding PHP implementation initially used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;US&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$Args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not equivalent for arbitrary mixed values.&lt;/p&gt;

&lt;p&gt;PHP's behavior around non-string values passed to &lt;code&gt;implode()&lt;/code&gt; is different, particularly with newer PHP versions.&lt;/p&gt;

&lt;p&gt;Qwen therefore identified the need to explicitly convert the values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;US&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'strval'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$Args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the intended conversion explicit and avoids relying on PHP's implicit behavior.&lt;/p&gt;

&lt;p&gt;The important lesson was that a direct API-to-API translation is not always a semantic translation.&lt;/p&gt;

&lt;p&gt;The C# expression and the PHP expression may look equivalent while behaving differently with real input types.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue 2: &lt;code&gt;null&lt;/code&gt; and Empty String Behavior
&lt;/h2&gt;

&lt;p&gt;Another issue involved the internal &lt;code&gt;add()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;The C# implementation uses &lt;code&gt;StringBuilder.Append()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Appending a null value does not insert the four characters &lt;code&gt;"null"&lt;/code&gt; and does not remove the preceding structure. It effectively contributes an empty string.&lt;/p&gt;

&lt;p&gt;This distinction matters when generating WebForms Core commands.&lt;/p&gt;

&lt;p&gt;The PHP implementation initially treated a null value differently.&lt;/p&gt;

&lt;p&gt;For methods such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;deleteState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the generated command could therefore differ from the C# implementation.&lt;/p&gt;

&lt;p&gt;Qwen identified this difference and suggested explicitly normalizing the null value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DS'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$path&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result preserves the command structure expected from the C# implementation.&lt;/p&gt;

&lt;p&gt;This was not a syntax error.&lt;/p&gt;

&lt;p&gt;Both versions were valid PHP.&lt;/p&gt;

&lt;p&gt;It was a cross-language semantic difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Findings
&lt;/h2&gt;

&lt;p&gt;Qwen also identified several other areas that required attention during the conversion.&lt;/p&gt;

&lt;p&gt;These included handling overloaded methods using PHP Union Types, optional and nullable parameters, and type-based routing in helper methods.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;InputPlace::attribute&lt;/code&gt; implementation can use the PHP type system to distinguish different forms of the original overloaded API.&lt;/p&gt;

&lt;p&gt;Qwen also identified corrections related to specific converted values, including the &lt;code&gt;CPP&lt;/code&gt; value in &lt;code&gt;WasmLanguage&lt;/code&gt; and the prefix generated by &lt;code&gt;SetMaxLength&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These findings were reviewed against the intended WebForms Core behavior before being incorporated.&lt;/p&gt;

&lt;p&gt;The purpose of this process was not to assume that every suggestion from an AI evaluator was automatically correct.&lt;/p&gt;

&lt;p&gt;Each finding still had to be compared with the original implementation and the intended protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Did Not Replace Testing
&lt;/h2&gt;

&lt;p&gt;This is probably the most important part of this release.&lt;/p&gt;

&lt;p&gt;DeepSeek was useful for producing the initial PHP implementation.&lt;/p&gt;

&lt;p&gt;Qwen was useful as an independent reviewer.&lt;/p&gt;

&lt;p&gt;But neither replaced testing.&lt;/p&gt;

&lt;p&gt;The final implementation was reviewed against the original C# implementation and tested for compatibility with WebFormsJS.&lt;/p&gt;

&lt;p&gt;This distinction matters.&lt;/p&gt;

&lt;p&gt;AI can identify a large number of repetitive transformations very quickly.&lt;/p&gt;

&lt;p&gt;It can also identify subtle differences that are easy to miss during manual review.&lt;/p&gt;

&lt;p&gt;However, the final authority is still the actual behavior of the software.&lt;/p&gt;

&lt;p&gt;The workflow therefore became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C# Reference Implementation
          ↓
      DeepSeek
          ↓
   PHP Conversion
          ↓
    Manual Review
          ↓
        Qwen
          ↓
 Semantic Corrections
          ↓
       Testing
          ↓
   WebForms.php 2.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  PHP Conventions
&lt;/h2&gt;

&lt;p&gt;One of the goals of the conversion was to make WebForms.php feel like PHP code rather than C# code translated into PHP syntax.&lt;/p&gt;

&lt;p&gt;This includes method naming, parameter naming, type declarations, nullable parameters, Union Types, arrays, and other language-specific constructs.&lt;/p&gt;

&lt;p&gt;For example, PHP should use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$inputPlace&lt;/span&gt;
&lt;span class="nv"&gt;$width&lt;/span&gt;
&lt;span class="nv"&gt;$maxValue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than carrying C# naming conventions into the PHP API.&lt;/p&gt;

&lt;p&gt;At the same time, the generated WebForms Core commands must remain compatible with the existing WebFormsJS runtime.&lt;/p&gt;

&lt;p&gt;This creates an important separation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The implementation follows PHP conventions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The generated protocol follows WebForms Core conventions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That separation is fundamental to a multi-language implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using WebForms.php
&lt;/h2&gt;

&lt;p&gt;WebForms.php can be used directly by including the PHP class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'WebForms.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;WebFormsCore\WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;WebFormsCore\Fetch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Hello from PHP!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can also be installed as a Composer package.&lt;/p&gt;

&lt;p&gt;After installing the package, the Composer autoloader can be included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the WebForms Core classes can be used normally.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Small PHP Example
&lt;/h2&gt;

&lt;p&gt;A simple example can use WebForms.php to create an interactive game without writing JavaScript business logic.&lt;/p&gt;

&lt;p&gt;For example, a small "Flower or Empty" game can be implemented with HTML containing only the interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;win-with=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    🌹 Flower
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;win-with=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ✊ Empty
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"computer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Computer choice:&lt;span class="nt"&gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PHP code then defines the behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;WebFormsCore\WebForms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;WebFormsCore\Fetch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Gol Ya Pooch - WebForms Core&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;🌹 Gol Ya Pooch ✊&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Choose one:&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;win-with=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"flower"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        🌹 Flower
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;win-with=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"empty"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        ✊ Empty
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"computer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Computer choice:&lt;span class="nt"&gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
        Games:
        &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
        Wins:
        &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"win-counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="nv"&gt;$form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;button&amp;gt;*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"onclick"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"play"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;button&amp;gt;*?.&amp;lt;p&amp;gt;*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"play"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Increase game counter&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"counter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Generate and save computer choice&lt;/span&gt;
&lt;span class="c1"&gt;// 0 = Flower, 1 = Empty hand&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addSaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"random"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Player wins&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isEqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"win-with"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"random"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;startBracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"😀 You win!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"win-counter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;endBracket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Equal&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"😢 You lose!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Show computer choice&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isEqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"random"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"computer|&amp;lt;&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"🌹 Flower"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"computer|&amp;lt;&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"✊ Empty"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;exportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example demonstrates an important property of WebForms Core.&lt;/p&gt;

&lt;p&gt;The PHP code describes the behavior.&lt;/p&gt;

&lt;p&gt;The browser executes the resulting WebForms Core commands through WebFormsJS.&lt;/p&gt;

&lt;p&gt;No JavaScript business logic is required for the game.&lt;/p&gt;

&lt;p&gt;Game screenshot&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1mp6zzdyo5jnbjubc7g7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1mp6zzdyo5jnbjubc7g7.png" alt="Simple Game with WebForms Core" width="463" height="589"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  WebForms.php 2.1 and WebFormsJS 2.1
&lt;/h2&gt;

&lt;p&gt;WebForms.php 2.1 is designed for WebFormsJS 2.1.&lt;/p&gt;

&lt;p&gt;The two components work together as the server-side command generator and client-side executor.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.1 introduced a large number of new capabilities, including nested conditions, &lt;code&gt;Then&lt;/code&gt;, &lt;code&gt;Repeat&lt;/code&gt;, &lt;code&gt;ForEach&lt;/code&gt;, advanced element selection, WPC criteria, State improvements, template rendering, debugging, improved history management, and other runtime improvements.&lt;/p&gt;

&lt;p&gt;The PHP implementation exposes the corresponding server-side API for PHP applications.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.1 was also extensively tested for compatibility between its WebForms classes and WebFormsJS. The main 2.1 release went through more than three months of compatibility testing and reported a greater than 99% test success rate.&lt;/p&gt;
&lt;h2&gt;
  
  
  Package Distribution
&lt;/h2&gt;

&lt;p&gt;WebForms.php is distributed as a Composer package.&lt;/p&gt;

&lt;p&gt;The package name is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webforms-core/php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be installed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require webforms-core/php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package uses Composer autoloading so that the WebForms.php implementation is loaded through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes WebForms.php available through the standard PHP package ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;WebForms.php 2.1 is not simply a translation of C# code into PHP syntax.&lt;/p&gt;

&lt;p&gt;It is a PHP implementation of the WebForms Core 2.1 server-side programming model.&lt;/p&gt;

&lt;p&gt;The development process was also an experiment in AI-assisted multi-language development.&lt;/p&gt;

&lt;p&gt;DeepSeek performed the initial conversion.&lt;/p&gt;

&lt;p&gt;Manual review identified language-specific differences.&lt;/p&gt;

&lt;p&gt;Qwen independently evaluated the result and identified semantic compatibility problems that were not obvious from the syntax alone.&lt;/p&gt;

&lt;p&gt;The final implementation was then corrected and tested.&lt;/p&gt;

&lt;p&gt;The experience demonstrated something important about using AI for software porting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI can significantly accelerate a language conversion, but successful porting requires more than generating syntactically valid code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difficult part is preserving behavior across languages.&lt;/p&gt;

&lt;p&gt;C# and PHP have different type systems, different conventions, different overload mechanisms, and different runtime behavior.&lt;/p&gt;

&lt;p&gt;A reliable port therefore needs to preserve the protocol and semantics while allowing the implementation to become native to its destination language.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can use the PHP version with complete confidence. If there is any problem, it will be fixed very soon by &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the approach used for WebForms.php 2.1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DeepSeek converted it.&lt;br&gt;
Qwen evaluated it.&lt;br&gt;
Testing validated it.&lt;br&gt;
WebForms.php 2.1 is now released.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>ai</category>
      <category>deepseek</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Elanat WebForms Core 2.1 Released with a Major Update</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Fri, 04 Sep 2026 18:33:24 +0000</pubDate>
      <link>https://dev.to/elanatframework/elanat-webforms-core-21-released-with-a-major-update-3bm</link>
      <guid>https://dev.to/elanatframework/elanat-webforms-core-21-released-with-a-major-update-3bm</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F56v9m6lofkpb2xksae0l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F56v9m6lofkpb2xksae0l.jpg" alt="WebForms Core" width="256" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core&lt;/strong&gt;, or &lt;strong&gt;WFC&lt;/strong&gt;, is a new technology based on the Commander-Executor concept, developed by &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core Organizations in GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; is a DSL for defining commands for creating, modifying, and controlling the DOM and the execution flow of the user interface, running alongside a client-side Runtime. This DSL enables declarative and Model-driven abstractions, allowing data flow, UI generation and modification, user interactions, and operation ordering to be defined without directly implementing DOM-related logic on the client side. The Runtime then interprets and executes these commands and applies the requested changes to the user interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4s670zkhl53s7bhynds.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4s670zkhl53s7bhynds.jpg" alt="WebForms VS WebForms Core VS MVC" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core is not designed only for forms and CRUD operations. It can even be extended to the creation of an interactive browser game.&lt;/p&gt;

&lt;p&gt;Version 2.1 introduces high-level declarative capabilities. This version provides a higher abstraction over the WFC core, combining the advantages of declarative development through advanced methods and mechanisms with imperative development.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.1 supports JavaScript ES2020 and modern browsers based on common web standards from 2020–2021 and later versions. The previous version (2) supported ES2022, and in this version we committed to supporting some older browsers as well.&lt;/p&gt;

&lt;p&gt;Therefore, this version is fully compatible with up-to-date browsers on Windows 7 and mobile devices released from 2015 onward, including Android 6.0 (with the latest Chrome version available for it, Chrome 106 in 2022) and iOS 15 (with Safari 15 in 2021).&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure-centric UI Generation
&lt;/h2&gt;

&lt;p&gt;In WebForms Core, it is possible to go beyond the Component level and focus on &lt;strong&gt;automatically generating UI structures&lt;/strong&gt; instead of manually constructing individual UI components.&lt;/p&gt;

&lt;p&gt;In this approach, rather than defining every Input, Label, form, and table individually, the developer defines rules and data structures, and the system creates the UI based on them.&lt;/p&gt;

&lt;p&gt;For example, a Model or database table structure can be used as the basis for automatically generating Add and Edit forms, input fields, and even data presentation structures.&lt;/p&gt;

&lt;p&gt;The developer is therefore primarily specifying &lt;strong&gt;"what data exists and what structure should be generated"&lt;/strong&gt;, rather than &lt;strong&gt;"how every HTML element should be constructed."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compared with Blazor:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Blazor primarily provides a Component-centric UI Model, while WebForms Core can provide, in addition to reusable Components and structures, a Structure-centric or Metadata-driven UI Generation Model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcfz1y5p3u3u5l9saw4c2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcfz1y5p3u3u5l9saw4c2.jpg" alt="ASP.NET WebForms VS WebForms Core VS ASP.NET MVC" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other systems can also build such generators, and this is not an exclusive technological advantage. The important point is that the architecture and tools of WebForms Core are highly suitable for building systems that automatically generate DOM/UI structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compared with React&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;React is essentially a component and state-based UI library.&lt;br&gt;
WebForms Core offers something different: a DSL + Runtime to define and implement UI flow, Data Flow, and Execution Flow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Compatibility Between WebForms and WebFormsJS
&lt;/h2&gt;

&lt;p&gt;For example, WebFormsJS version 2.0.1 remains compatible with the WebForms class version 2.0 and 2.0.9.&lt;/p&gt;

&lt;p&gt;Likewise, the WebForms class version 2.0.1 remains compatible with WebFormsJS version 2.0 and 2.0.9.&lt;/p&gt;

&lt;p&gt;WFC is a continuously evolving technology, and using the latest versions of the technology is recommended.&lt;/p&gt;

&lt;h1&gt;
  
  
  WebForms Core 2.1
&lt;/h1&gt;

&lt;p&gt;Version 2.1 is another major update, just like the previous two versions.&lt;/p&gt;

&lt;p&gt;We spent more than three months writing tests for compatibility between the WebForms classes and the WebFormsJS library.&lt;/p&gt;

&lt;p&gt;At Elanat, WFC 2.1 achieved a &lt;strong&gt;more than 99% quality assurance rate for WFC 2.1&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This percentage represents the success rate of our tests: we continued testing until we could no longer find problems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The WebForms class is currently very stable. If a problem is reported in WebFormsJS in the coming days, we will fix it immediately and release version 2.1.1 and later. These patch versions remain fully compatible with the WebForms class version 2.1.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating HTML Comments for WebForms Responses
&lt;/h2&gt;

&lt;p&gt;WebForms Core uses HTML comments as one of its mechanisms for storing and executing WebForms Action Controls.&lt;/p&gt;

&lt;p&gt;When an HTML response contains the WebForms comment structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--[web-forms]
...
--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the WebForms response comment can be handled automatically.&lt;/p&gt;

&lt;p&gt;However, the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[web-forms]
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is not automatically converted into an HTML comment.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.1 provides the following option for this purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateCommentForWebFormsResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When enabled, WebFormsJS can create the required HTML comment structure for WebForms responses that use the &lt;code&gt;[web-forms]&lt;/code&gt; format.&lt;/p&gt;

&lt;p&gt;This provides additional flexibility when handling WebForms responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Improvements
&lt;/h2&gt;

&lt;p&gt;To improve security, any spaces in the HTML comment are ignored.&lt;br&gt;
Therefore, Action Controls must be placed directly after the string &lt;code&gt;&amp;lt;!--&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Acceptable Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!--[web-forms]
bc&amp;lt;main&amp;gt;=green--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ignored Examples&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- [web-forms]
bc&amp;lt;main&amp;gt;=green--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!--
[web-forms]
bc&amp;lt;main&amp;gt;=green--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The location of the response has been improved in the settings.&lt;/p&gt;

&lt;p&gt;A new &lt;code&gt;StateBodyLocation&lt;/code&gt; option has been added for storing the State body instead of using &lt;code&gt;ResponseLocation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;StateBodyLocation&lt;/code&gt; specifies where State changes are stored. By default, it is the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ResponseLocation&lt;/code&gt; specifies where a server response should be inserted when the response is not only an Action Control—for example, when the server returns an HTML section. Its default is also &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;, but using &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; is recommended:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ResponseLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both &lt;code&gt;StateBodyLocation&lt;/code&gt; and &lt;code&gt;ResponseLocation&lt;/code&gt; use the WebForms Place Criteria (WPC) DSL for their values.&lt;/p&gt;

&lt;h3&gt;
  
  
  External URL Security
&lt;/h3&gt;

&lt;p&gt;New security options have also been added for external URLs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DisableLoadExternalHost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UseLoadExternalHostOnlyInAcceptedList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LoadExternalHostOnlyInAcceptedList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;URLs are filtered using a list and wildcard rules.&lt;/p&gt;

&lt;p&gt;This restriction applies to external URL requests outside the current and primary server domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Security Control with DisablePassObject
&lt;/h3&gt;

&lt;p&gt;WebForms Core 2.1 also includes the following security-related option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DisablePassObject&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This option provides additional control over object passing behavior inside the WebFormsJS runtime.&lt;/p&gt;

&lt;p&gt;Like other WebFormsJS security options, it can be configured depending on the requirements and security model of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Action Control Values Are Now Arrays
&lt;/h2&gt;

&lt;p&gt;In this version, the string-based structure of Action Control values has been changed to an array-based structure.&lt;/p&gt;

&lt;p&gt;This provides complete control over Fetch results and value types.&lt;/p&gt;

&lt;p&gt;For example, when the result of a Fetch operation is an object, it is no longer automatically converted to a string.&lt;/p&gt;

&lt;p&gt;This allows Action Controls to work more naturally with different types of values, including numeric values and objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Form Submit Check Validity
&lt;/h2&gt;

&lt;p&gt;In this version, the ability to fully validate HTML forms in WebFormsJS has been added, and it is possible to change the Validation warning text for HTML inputs in the settings section.&lt;/p&gt;

&lt;p&gt;An option in the settings called &lt;code&gt;CheckValidityForFormSubmit&lt;/code&gt; has also been added, which is enabled by default.&lt;/p&gt;

&lt;p&gt;We will explain this section soon in a new article with an example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Append and Replace for Stored Data
&lt;/h2&gt;

&lt;p&gt;New capabilities have been added for appending to and replacing temporarily and permanently stored data.&lt;/p&gt;

&lt;p&gt;The following methods have been added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AppendCacheValue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReplaceCacheValue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AppendSaveValue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReplaceSaveValue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Cache&lt;/code&gt; refers to &lt;code&gt;localStorage&lt;/code&gt;, while &lt;code&gt;Save&lt;/code&gt; refers to &lt;code&gt;sessionStorage&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL Hash and Segment
&lt;/h2&gt;

&lt;p&gt;A new capability has been added to &lt;code&gt;SetMasterPage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is now possible to access the URL after &lt;code&gt;#&lt;/code&gt;, including its hash and Segment information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Segment
&lt;/h3&gt;

&lt;p&gt;A new Segment mechanism has been introduced for URLs and hashes.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;~&lt;/code&gt; character can be used after &lt;code&gt;#&lt;/code&gt;. Everything after &lt;code&gt;~&lt;/code&gt; is treated as a URL path/Segment.&lt;/p&gt;

&lt;p&gt;For example, a URL can contain a structure such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#~admin/users/edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This mechanism makes it possible to build more powerful SPA systems.&lt;/p&gt;

&lt;p&gt;The mechanism is also automatically enabled for internal links.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Fetch&lt;/code&gt; helper class can now access Segments in the URL.&lt;/p&gt;

&lt;p&gt;Negative indexes are supported as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HashSegment&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means the last Segment.&lt;/p&gt;

&lt;p&gt;Query access in the &lt;code&gt;Fetch&lt;/code&gt; helper has also been converted into a method, allowing a value to be retrieved from the query by its name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Separator Changes
&lt;/h2&gt;

&lt;p&gt;Version 2.1 contains a fundamental change to the internal separators.&lt;/p&gt;

&lt;p&gt;In version 2.1, the separators previously represented by the &lt;code&gt;|&lt;/code&gt; and &lt;code&gt;,&lt;/code&gt; characters have been replaced with ASCII control characters 28, 29, 30, and 31.&lt;/p&gt;

&lt;p&gt;Previously, the structure was effectively based on multiple character-level separators. For example, &lt;code&gt;|&lt;/code&gt; was used as a separator while &lt;code&gt;,&lt;/code&gt; was also used by Fetch. This could cause conflicts when a Fetch operation itself contained a list of arguments.&lt;/p&gt;

&lt;p&gt;The new structure eliminates these conflicts.&lt;/p&gt;

&lt;p&gt;There is now no longer even the smallest conflict caused by those common characters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Template Engine
&lt;/h2&gt;

&lt;p&gt;A new template rendering engine has been added to replace repeated manual Replace operations.&lt;/p&gt;

&lt;p&gt;The main method is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BindTemplate(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This performs a general replacement based on NameValue data from INI, JSON, and XML sources.&lt;/p&gt;

&lt;p&gt;The data is automatically inserted into the template according to the specified pattern.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BindXMLToTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"XMLTag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/xml_data.xml"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"contact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"{{value}}"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BindINIToTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"INITag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/ini_data.ini"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s"&gt;"contact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"{{value}}"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An XML source can be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;contact&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;John Doe&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;phone&amp;gt;&lt;/span&gt;+1-555-123-4567&lt;span class="nt"&gt;&amp;lt;/phone&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;email&amp;gt;&lt;/span&gt;john.doe@example.com&lt;span class="nt"&gt;&amp;lt;/email&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;address&amp;gt;&lt;/span&gt;123 Main Street, Springfield, IL 62701, USA&lt;span class="nt"&gt;&amp;lt;/address&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;postalCode&amp;gt;&lt;/span&gt;62701&lt;span class="nt"&gt;&amp;lt;/postalCode&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;birthDate&amp;gt;&lt;/span&gt;1990-05-15&lt;span class="nt"&gt;&amp;lt;/birthDate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/contact&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And an INI source can be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[contact]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Emma Wilson&lt;/span&gt;
&lt;span class="py"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;+44-7700-900-123&lt;/span&gt;
&lt;span class="py"&gt;email&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;emma.wilson@example.co.uk&lt;/span&gt;
&lt;span class="py"&gt;address&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;45 Baker Street, London, UK&lt;/span&gt;
&lt;span class="py"&gt;postalCode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;NW1 6XE&lt;/span&gt;
&lt;span class="py"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1988-12-03&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template engine can then use the same structure to generate the required UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML Before BindTemplate&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;BindXMLToTemplate&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;address&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"XMLTag"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"contact-info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Name:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; {{name}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Phone:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"tel:{{phone}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{phone}}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"mailto:{{email}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{email}}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Address:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; {{address}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Postal Code&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; {{postalcode}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Birth Date:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; {{birthdate}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/address&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;BindINIToTemplate&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;address&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"INITag"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"contact-info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Name:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; {{name}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Phone:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"tel:{{phone}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{phone}}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"mailto:{{email}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{email}}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Address:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; {{address}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Postal Code:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; {{postalCode}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Birth Date:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; {{birthDate}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/address&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;HTML After BindTemplate&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;h2&amp;gt;&lt;/span&gt;BindXMLToTemplate&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;address&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"XMLTag"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"contact-info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Name:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; John Doe&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Phone:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"tel:+1-555-123-4567"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+1-555-123-4567&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"mailto:john.doe@example.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;john.doe@example.com&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Address:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; 123 Main Street, Springfield, IL 62701, USA&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Postal Code&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; 62701&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Birth Date:&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; 1990-05-15&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/address&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;BindINIToTemplate&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;address&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"INITag"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"contact-info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Name:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; Emma Wilson&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Phone:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"tel:+44-7700-900-123"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+44-7700-900-123&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"mailto:emma.wilson@example.co.uk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;emma.wilson@example.co.uk&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Address:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; 45 Baker Street, London, UK&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Postal Code:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; NW1 6XE&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Birth Date:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; 1988-12-03&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/address&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  New Replace Capabilities
&lt;/h2&gt;

&lt;p&gt;Several new Replace mechanisms have been added.&lt;/p&gt;

&lt;h3&gt;
  
  
  ReplaceActionControl
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ReplaceActionControl&lt;/code&gt; replaces all Action Controls when executed.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReplaceActionControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{{segment}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;form&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/admin/update"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"put"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FormatStoreByJSONQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fs_json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"[{{segment}}].id"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(add)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Click to update content"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"update"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AssignReplace
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;AssignReplace&lt;/code&gt; replaces a value only in one line of Action Controls.&lt;/p&gt;

&lt;p&gt;Its default index is &lt;code&gt;-1&lt;/code&gt;, and it is usually written immediately after the Action Control that should be modified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My Message: Page Title is {{Value}}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AssignReplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"{{Value}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;title&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AppendFetchReplace
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;AppendFetchReplace&lt;/code&gt; operates directly on Fetch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{{Value}}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;AppendFetchReplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{{Value}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;title&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These mechanisms make it possible to dynamically modify Action Controls and Fetch results without manually reconstructing the entire command structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugger
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 introduces a new Debugger.&lt;/p&gt;

&lt;p&gt;The Debugger allows developers to control the execution of Action Controls with operations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;Pause&lt;/li&gt;
&lt;li&gt;Stop&lt;/li&gt;
&lt;li&gt;Step&lt;/li&gt;
&lt;li&gt;Close&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple server-side example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DebugerController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"many-action-controls"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Button_Click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"StartDebuger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"start-debuger"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetGetEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Button"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"?many-action-controls"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"start-debuger"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDebugger&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Button_Click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"help"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ElementExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt; element is exist"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Else&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt; element is not exist"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Continue Action Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"help"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;IgnoreAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want &lt;code&gt;CreateDebugger()&lt;/code&gt; to immediately pause code interpretation, pass &lt;code&gt;true&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDebugger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This starts the Debugger in the paused state.&lt;/p&gt;

&lt;p&gt;The Debugger is implemented inside WebFormsJS and provides a client-side control panel for controlling execution.&lt;/p&gt;

&lt;p&gt;Debugger screenshot&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2gad6luvxcwv0vjp2xc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2gad6luvxcwv0vjp2xc4.png" alt="Debugger screenshot" width="321" height="143"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Repeat
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Repeat&lt;/code&gt; is an extension over the &lt;code&gt;GoTo&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;It provides a higher-level mechanism for repeating a group of Action Controls.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="nf"&gt;Repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;newForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newForm&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;bodyData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetWebFormsData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bodyData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;startLine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bodyData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;AppendForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newForm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;GoTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startLine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repeat&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are also overloads that allow an index to be specified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Updated"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of explicitly working with &lt;code&gt;GoTo&lt;/code&gt;, developers can use &lt;code&gt;Repeat&lt;/code&gt; as a higher-level abstraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Then&lt;/code&gt; method was added to the &lt;code&gt;Condition&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;It allows conditional commands to be continued without requiring &lt;code&gt;StartBracket()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ElementExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The main element exists."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Updated"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes conditional code easier to compose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditions and Nested Execution
&lt;/h2&gt;

&lt;p&gt;Conditions and loops must be able to execute in a nested manner.&lt;/p&gt;

&lt;p&gt;In WebForms Core 2.1, the condition system has been completely rewritten in WebFormsJS.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;else&lt;/code&gt; support has also been added to conditions.&lt;/p&gt;

&lt;p&gt;This allows structures such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ElementExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Main exists"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Else&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Main does not exist"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new architecture allows conditions and loops to be nested and combined.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Repeat&lt;/code&gt; and &lt;code&gt;Then&lt;/code&gt; were added to the server-side &lt;code&gt;WebForms&lt;/code&gt; class, while the underlying condition execution has been completely rewritten in WebFormsJS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unfortunately, due to the length of the article, we cannot cover nested conditions in this article. However, we will introduce nested conditions in a new article soon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ForEach
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ForEach&lt;/code&gt; is a new feature introduced in WebForms Core 2.1.&lt;/p&gt;

&lt;p&gt;It provides a declarative way to iterate over stored data and execute a set of Action Controls for each item.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NotExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"series-data"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCacheValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"series-data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/series-data"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[0]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"series-data"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"foreach-data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{series-container}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/template.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SeriesAdmin"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BindJSONToTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{series-card}-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FormatStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foreach-data"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"[0]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"{{value}}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetDeleteEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{delete}-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{delete}-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because conditions and loops can now be nested, &lt;code&gt;ForEach&lt;/code&gt; can be combined with conditional logic and other execution mechanisms.&lt;/p&gt;

&lt;p&gt;This makes it possible to construct more complex server-defined UI workflows without manually implementing the corresponding client-side loop.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you leave the selection name blank, a point (&lt;code&gt;.&lt;/code&gt;) is chosen as the selection name. It is recommended to assign a unique identifier called ForEach to avoid conflicts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The loop count is also added to the selection name as the character &lt;code&gt;i&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FormatStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foreach-datai"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JSON Path Improvements
&lt;/h2&gt;

&lt;p&gt;The Add, Read, Delete, and Edit operations for JSON have been improved.&lt;/p&gt;

&lt;p&gt;Advanced JSON path operations are now possible using conditional queries and negative indexing.&lt;/p&gt;

&lt;p&gt;For example, negative indexes can be used to address items relative to the end of an array.&lt;/p&gt;

&lt;p&gt;This provides more flexibility when working with JSON data stored inside WebForms Core.&lt;/p&gt;

&lt;p&gt;This section will also be reviewed in detail soon as a new article.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebForms Place Criteria (WPC)
&lt;/h2&gt;

&lt;p&gt;WebForms Place Criteria is a lightweight query language for locating and filtering web contexts, including DOM elements, document objects, browser windows, and other client-side objects.&lt;/p&gt;

&lt;p&gt;WPC has been significantly expanded in this version.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML Tag Selection in InputPlace
&lt;/h3&gt;

&lt;p&gt;An HTML tag can now be selected in &lt;code&gt;InputPlace&lt;/code&gt; using the &lt;code&gt;.&lt;/code&gt; character.&lt;/p&gt;

&lt;p&gt;Attribute-based selection has also been added, allowing elements to be selected according to both an attribute name and its value.&lt;/p&gt;

&lt;p&gt;For example, attribute conditions can use operators such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^
$
*
~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These correspond to operations such as starts-with, ends-with, contains, and word matching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Child Selection
&lt;/h3&gt;

&lt;p&gt;A powerful child selector has been added.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UserBox|&amp;lt;&amp;gt;0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;&amp;lt;&amp;gt;0&lt;/code&gt; means the first child.&lt;/p&gt;

&lt;p&gt;The developer no longer needs to know the name of the first child.&lt;/p&gt;

&lt;p&gt;For example, instead of having to know whether the first child is a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the generic child selector can be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;&amp;gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also available as part of the &lt;code&gt;WebForms&lt;/code&gt; class.&lt;/p&gt;

&lt;h3&gt;
  
  
  All Selection
&lt;/h3&gt;

&lt;p&gt;All tags can be selected using the &lt;code&gt;All&lt;/code&gt; property or &lt;code&gt;*&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;All&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The DSL also supports selecting all matching names, tags, classes, attributes, and children.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criteria
&lt;/h3&gt;

&lt;p&gt;A new and powerful criteria mechanism has been added.&lt;/p&gt;

&lt;p&gt;For example, elements can be filtered by inner text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{my-class}*?t=abc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or by attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"data-id'*abc"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criteria can be chained together, allowing multiple filters and operations to be applied to the same result.&lt;/p&gt;

&lt;p&gt;The criteria system supports operations for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inner text&lt;/li&gt;
&lt;li&gt;All inner text&lt;/li&gt;
&lt;li&gt;Attribute values&lt;/li&gt;
&lt;li&gt;Tag names&lt;/li&gt;
&lt;li&gt;Visibility&lt;/li&gt;
&lt;li&gt;Enabled state&lt;/li&gt;
&lt;li&gt;Checked state&lt;/li&gt;
&lt;li&gt;Direct children&lt;/li&gt;
&lt;li&gt;Descendants&lt;/li&gt;
&lt;li&gt;Ranges&lt;/li&gt;
&lt;li&gt;Next siblings&lt;/li&gt;
&lt;li&gt;Previous siblings&lt;/li&gt;
&lt;li&gt;Intersection&lt;/li&gt;
&lt;li&gt;Union&lt;/li&gt;
&lt;li&gt;Difference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, visibility can be tested using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;?v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and enabled or checked elements can be filtered using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;?e
?c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ranges also support negative indexes.&lt;/p&gt;

&lt;p&gt;The criteria engine is implemented in WebFormsJS and provides a lightweight query language on top of the WFC element-selection system.&lt;/p&gt;

&lt;p&gt;The criteria section will be reviewed in detail soon as part of a new article.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Improvements
&lt;/h2&gt;

&lt;p&gt;SPA links now manage State and browser history more reliably.&lt;/p&gt;

&lt;p&gt;Synchronizing State with the browser's Back and Forward buttons was particularly complex when the user pressed these buttons before the configured State registration delay had elapsed.&lt;/p&gt;

&lt;p&gt;The default delay is 500 milliseconds and can be changed through configuration.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;SPALink&lt;/code&gt; system now handles State much more closely to the behavior of normal browser history.&lt;/p&gt;

&lt;h3&gt;
  
  
  StartState
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;StartState&lt;/code&gt; method has been added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;StartState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;StartIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core interprets Action Controls line by line until it reaches a &lt;code&gt;#&lt;/code&gt; character.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;#&lt;/code&gt; represents an index.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"RunMessage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"run-message"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetGetEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Button"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"?get-server-value"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"run-message"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first two lines are executed normally.&lt;/p&gt;

&lt;p&gt;When the &lt;code&gt;RunMessage&lt;/code&gt; button (any tags with &lt;code&gt;RunMessage&lt;/code&gt; ID) is clicked, the &lt;code&gt;run-message&lt;/code&gt; index is executed, causing the Action Control associated with &lt;code&gt;Message()&lt;/code&gt; to run.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;StartState&lt;/code&gt; is a special index that is executed when returning to a previously registered State, such as when the user navigates using the browser's Back or Forward buttons.&lt;/p&gt;

&lt;h3&gt;
  
  
  LoadState and HasState
&lt;/h3&gt;

&lt;p&gt;A new &lt;code&gt;LoadState&lt;/code&gt; method has been added.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Fetch&lt;/code&gt; helper also now includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fetch.HasState("/contact");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which can be used to determine whether a State exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  More Control Over Browser History and DOM Event Listeners
&lt;/h3&gt;

&lt;p&gt;WebForms Core 2.1 includes additional options for controlling SPA navigation and browser history behavior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IgnoreQueryAndHashInSPALink&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReloadOnMissingHistory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CloseAllFixedFeaturesAfterHistoryReview&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RestoreListenersAfterHistoryReview&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The previous sections discussed the improvements made to State management and the synchronization of WebForms Core with the browser's Back and Forward buttons.&lt;/p&gt;

&lt;p&gt;Version 2.1 also adds more control over situations that occur during history review.&lt;/p&gt;

&lt;p&gt;One particularly important option is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RestoreListenersAfterHistoryReview&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DOM replacement can create a common problem in SPA-style applications: elements may be replaced and previously attached event listeners may no longer be available.&lt;/p&gt;

&lt;p&gt;WebFormsJS 2.1 improves this process through the following runtime functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cb_RestoreListenersAfterDOMReplace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps WebFormsJS restore the required listeners after DOM replacement and during history-related operations.&lt;/p&gt;

&lt;p&gt;The new history options also provide additional control when a requested browser history state is missing and when fixed UI features need to be reviewed or closed during history navigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial State Loader
&lt;/h3&gt;

&lt;p&gt;A Loader has been added for registering the initial State.&lt;/p&gt;

&lt;p&gt;The new &lt;code&gt;WebFormsOptions.UseLoaderForFirstPageLoad&lt;/code&gt; option enables an animation Loader during the initial page load.&lt;/p&gt;

&lt;p&gt;The Loader is displayed while the initial data is being registered, preventing the user from interacting with the page before the initial State is ready.&lt;/p&gt;

&lt;p&gt;The default delay is 500 milliseconds and can be configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamically Changing WebFormsJS Options
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 also introduces the ability to dynamically change WebFormsJS options through Action Controls.&lt;/p&gt;

&lt;p&gt;This allows configuration to be changed during runtime instead of requiring all options to remain static.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ChangeOption&lt;/code&gt; method allows an individual WebFormsJS option to be changed during execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ChangeOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"QueueDebounceDelay"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"500"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;QueueDebounceDelay&lt;/code&gt; option is dynamically set to &lt;code&gt;500&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the developer later wants to restore the original value of that specific option, the &lt;code&gt;ResetOption&lt;/code&gt; method can be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ResetOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"QueueDebounceDelay"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is also possible to reset all dynamically changed WebFormsJS options at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ResetOption&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Reset all WebFormsJS options&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes WebFormsJS configuration more flexible. Instead of treating options as static configuration that must remain unchanged after the page loads, WebForms Core can modify individual runtime behaviors dynamically and later restore either a specific option or the entire configuration to its original state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better SSE and WebSocket Connection Management
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 provides more control over persistent connections and adds more methods for better SSE and WebSocket management.&lt;/p&gt;

&lt;p&gt;Developers can configure the maximum number of reconnection attempts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebSocketReconnectMaxRetries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SSEReconnectMaxRetries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core can also check the current connection state through the &lt;code&gt;Fetch&lt;/code&gt; helper class.&lt;/p&gt;

&lt;h3&gt;
  
  
  SSE Connection State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SSEIsConnected&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/events"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following methods are also available for managing SSE connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DisconnectSSE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/events"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DisconnectAllSSE&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  WebSocket Connection State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WebSocketsIsConnected&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/socket"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebSocket connections can also be explicitly removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeleteWebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/socket"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These additions provide better control over the complete lifecycle of persistent connections.&lt;/p&gt;

&lt;p&gt;Instead of only creating SSE and WebSocket connections, applications can now more easily monitor whether connections are active, configure reconnection behavior, disconnect SSE connections individually or collectively, and remove WebSocket connections when they are no longer needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retry Management for Requests
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 provides additional control over requests that do not produce the expected result.&lt;/p&gt;

&lt;p&gt;Developers can configure whether WebFormsJS should retry a request and define both the maximum number of retry attempts and the interval between them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IgnoreEmptyResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseRetryRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxRetryCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetryRequestInterval&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, WebFormsJS can retry a request up to three times, with a three-second interval between attempts.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;IgnoreEmptyResult&lt;/code&gt; option also provides control over how empty responses are handled.&lt;/p&gt;

&lt;p&gt;These options provide greater flexibility when dealing with temporary connection problems or situations where a request may need to be attempted again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Runtime Console Diagnostics
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 provides more detailed control over diagnostic messages generated by the WebFormsJS runtime.&lt;/p&gt;

&lt;p&gt;Developers can enable or disable general console output and individually control diagnostic messages for different parts of the runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddConsoleMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseConsoleStackTrace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddConsoleMessageForHTTP&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddConsoleMessageForURL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddConsoleMessageForWebSockets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddConsoleMessageForSSE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddConsoleMessageForModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows developers to control diagnostic output for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP requests&lt;/li&gt;
&lt;li&gt;URL processing&lt;/li&gt;
&lt;li&gt;WebSocket connections&lt;/li&gt;
&lt;li&gt;Server-Sent Events&lt;/li&gt;
&lt;li&gt;WebFormsJS modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;AddConsoleMessageForHTTP&lt;/code&gt; feature is disabled by default. When enabled, it logs XMLHttpRequest requests to the Console.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;UseConsoleStackTrace&lt;/code&gt; option can also be used to control whether stack trace information is included in diagnostic output. This feature is disabled by default and when enabled, errors are displayed with additional details, such as the error line in the Console.&lt;/p&gt;

&lt;p&gt;These options are particularly useful during development and debugging because developers can focus on specific parts of the WebFormsJS runtime instead of enabling unnecessary diagnostic output for everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Message, Confirm, and Alert
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;message&lt;/code&gt;, &lt;code&gt;confirm&lt;/code&gt;, and &lt;code&gt;alert&lt;/code&gt; features have been rewritten.&lt;/p&gt;

&lt;p&gt;They are now fully synchronized with the current page State.&lt;/p&gt;

&lt;p&gt;This makes these UI interactions behave consistently with State changes and SPA navigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP Methods
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;TRACE&lt;/code&gt; and &lt;code&gt;CONNECT&lt;/code&gt; methods have been removed.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;PUT&lt;/code&gt; method can now also send requests outside a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;This is useful because some servers may not handle the PUT method correctly with &lt;code&gt;enctype="multipart/form-data"&lt;/code&gt; and may require POST or additional server-side configuration.&lt;/p&gt;

&lt;p&gt;In practice, public servers have introduced non-standard limitations around this behavior.&lt;/p&gt;

&lt;p&gt;The new PUT methods are similar to other common methods such as GET, DELETE, and PATCH.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SetPutEvent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SetPutEventListener&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RemovePutEvent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RemovePutEventListener&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CallPutBack&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Removal of &lt;code&gt;&amp;lt;web-forms&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;web-forms&amp;gt;&lt;/code&gt; tag has been permanently removed.&lt;/p&gt;

&lt;p&gt;Previously, this tag stored Action Control values inside the HTML itself and allowed the tag to be executed offline.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.1 removes this mechanism and retains HTML comments as the offline Action Control mechanism.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CommentBackController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"run_ac_in_comment"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Button1_OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetGetEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HtmlEventListener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Click&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"?run_ac_in_comment"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetCommentEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Button2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;main&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"silver"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 2"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartIndex&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 3"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 4"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartIndex&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 5"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 6"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message7-8"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 7"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message 8"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Button1_OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CallCommentBack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message7-8"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;IgnoreAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Action Controls remain inside HTML comments and can therefore be executed offline without the old &lt;code&gt;&amp;lt;web-forms&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Access with &lt;code&gt;$&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;$&lt;/code&gt; character can now be used to access WebFormsJS and JavaScript data.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMethodEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"EventListenerDblQuot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEventListener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Click&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"$document.getElementsByTagName('button')[1].outerHTML"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;$&lt;/code&gt; mechanism can be used anywhere except where an &lt;code&gt;InputPlace&lt;/code&gt; is expected.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;$@&lt;/code&gt; is used, the object itself is passed rather than its output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMethodEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"EventDblQuot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"$@document"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to escape &lt;code&gt;$&lt;/code&gt;, use two &lt;code&gt;$&lt;/code&gt; characters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, &lt;code&gt;$$&lt;/code&gt; represents an escaped &lt;code&gt;$&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatic Number Conversion
&lt;/h2&gt;

&lt;p&gt;In the new structure, data that can be converted to numbers is automatically added as Number.&lt;br&gt;
If the output is of numeric type and you do not want it to be converted to a number, enclose the number between two single quotes (&lt;code&gt;'&lt;/code&gt;) or double quotes (&lt;code&gt;"&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMethodEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Event"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"'10'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"'24'"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The output of the above example is the string &lt;code&gt;1024&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Memory Management
&lt;/h2&gt;

&lt;p&gt;Several improvements have been made to memory management.&lt;/p&gt;

&lt;p&gt;A Garbage Collector-like structure has been added that now removes and manages previously allocated data more efficiently.&lt;/p&gt;

&lt;p&gt;The new code has also been reviewed to avoid introducing memory leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  InputPlace and Naming Changes
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;AppendPlace&lt;/code&gt; extension function has been renamed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Child
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This better reflects its purpose within the InputPlace DSL.&lt;/p&gt;

&lt;p&gt;Session, Session Cache, and Saved naming have also been removed.&lt;/p&gt;

&lt;p&gt;From now on, only the name &lt;code&gt;Save&lt;/code&gt; is used for &lt;code&gt;sessionStorage&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Numeric Comparisons
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;IsGreaterThan&lt;/code&gt; and &lt;code&gt;IsLessThan&lt;/code&gt; conditions have been improved.&lt;/p&gt;

&lt;p&gt;Numbers and strings are now correctly distinguished, allowing numerical comparisons to work properly.&lt;/p&gt;

&lt;p&gt;For example, numeric values are no longer incorrectly compared as strings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query and Hash State
&lt;/h2&gt;

&lt;p&gt;A new option prevents query and hash links from creating a new browser State:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;WebFormsOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IgnoreQueryAndHashInSPALink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default value is &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When enabled, SPA links containing query strings or hashes can be excluded from automatic State creation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Features
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;We have already described a number of new features in version 2.1:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added WASM Mediator support for C# programming language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/elanatframework/net-webcil-container-meets-webforms-core-21-39f5"&gt;https://dev.to/elanatframework/net-webcil-container-meets-webforms-core-21-39f5&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New Morph feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/elanatframework/morphing-feature-in-webforms-core-21-5d6o"&gt;https://dev.to/elanatframework/morphing-feature-in-webforms-core-21-5d6o&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Fixes and Improvements
&lt;/h3&gt;

&lt;p&gt;This release also contains many smaller improvements and fixes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improved performance.&lt;/li&gt;
&lt;li&gt;Improved existing methods.&lt;/li&gt;
&lt;li&gt;Added several new minor capabilities.&lt;/li&gt;
&lt;li&gt;Improved Garbage Collection and data cleanup.&lt;/li&gt;
&lt;li&gt;Fixed selection of multiple tags when only one matching tag exists.&lt;/li&gt;
&lt;li&gt;Prevented SSE from running inside Service Workers because of an interaction conflict.&lt;/li&gt;
&lt;li&gt;Improved &lt;code&gt;IncreaseHeight&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Improved &lt;code&gt;IncreaseWidth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Fixed scrolling after clicking SPA links.&lt;/li&gt;
&lt;li&gt;Fixed an issue where &lt;code&gt;AddState&lt;/code&gt; could not change the title at the same time.&lt;/li&gt;
&lt;li&gt;Fixed event registration issues in &lt;code&gt;CommentBack&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Fixed changing Action Controls for InputPlace lists such as &lt;code&gt;&amp;lt;button&amp;gt;*&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Fixed State support for attributes of selected tags.&lt;/li&gt;
&lt;li&gt;Fixed State support for &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;, and &lt;code&gt;textarea&lt;/code&gt; values.&lt;/li&gt;
&lt;li&gt;Fixed additional requests being generated in conditional states.&lt;/li&gt;
&lt;li&gt;Support for PATCH and DELETE when submitting a form&lt;/li&gt;
&lt;li&gt;Better detection of browser support for compression&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  WebForms and WebFormsJS Patch-Version Compatibility
&lt;/h2&gt;

&lt;p&gt;WebForms Core maintains compatibility across patch versions.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;WebForms.cs&lt;/code&gt; version 2.1.5 remains compatible with WebFormsJS 2.1.&lt;/p&gt;

&lt;p&gt;The same compatibility principle applies to the other WebForms classes.&lt;/p&gt;

&lt;p&gt;Patch versions such as 2.1.1, 2.1.2, 2.1.5, and later can contain bug fixes and improvements while remaining compatible with the WebFormsJS 2.1 core version.&lt;/p&gt;

&lt;p&gt;It is recommended to always use the latest patch versions available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Package Size
&lt;/h2&gt;

&lt;p&gt;We used ASP.NET 10 for testing.&lt;/p&gt;

&lt;p&gt;Because .NET 9 introduced a planned replacement of the older zlib dependency with zlib-ng, and we are using .NET 10, comparing package sizes directly with previous versions is more difficult.&lt;/p&gt;

&lt;p&gt;The .NET team also discussed a similar issue in its official .NET 9 performance evaluation: with the compression infrastructure changing to zlib-ng, &lt;code&gt;Fastest&lt;/code&gt; can produce noticeably larger output than the previous implementation while providing significantly faster compression. The .NET team specifically recommends reevaluating the balance between compression speed and compression ratio when using &lt;code&gt;Fastest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, while WebFormsJS 2.0 previously showed 39.59 KB with GZip + Minify under .NET 7.0 using &lt;code&gt;Fastest&lt;/code&gt;, our new test under .NET 10 shows 47.84 KB.&lt;/p&gt;

&lt;h3&gt;
  
  
  CompressionLevel.SmallestSize
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RAW:             411.73 kB
RAW + GZip:       63.22 kB
Minify:          179.24 kB
Minify + GZip:    43.37 kB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CompressionLevel.Fastest
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RAW:             411.73 kB
RAW + GZip:      101.14 kB
Minify:          179.24 kB
Minify + GZip:    61.26 kB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, WebFormsJS 2.1 is approximately &lt;strong&gt;60 KB&lt;/strong&gt; under the ideal server-side compression configuration.&lt;/p&gt;

&lt;p&gt;There is still a long way to go before reaching 100 KB! 😄&lt;/p&gt;

&lt;p&gt;The Settings section is intentionally left readable.&lt;/p&gt;

&lt;p&gt;Please note that starting with version 2.1, the Settings section is not included in Minify.&lt;/p&gt;

&lt;p&gt;This is intentional so that developers can configure the settings more easily and have an easier time transferring and applying their configuration when upgrading to newer versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;WebForms Core 2.1 is a major expansion of the technology's declarative capabilities.&lt;/p&gt;

&lt;p&gt;The new version goes beyond basic server-driven DOM manipulation by introducing higher-level mechanisms for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declarative UI generation&lt;/li&gt;
&lt;li&gt;Template rendering&lt;/li&gt;
&lt;li&gt;URL Segments&lt;/li&gt;
&lt;li&gt;Advanced State management&lt;/li&gt;
&lt;li&gt;Nested conditions&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Then&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Repeat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ForEach&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;WPC criteria&lt;/li&gt;
&lt;li&gt;Advanced element selection&lt;/li&gt;
&lt;li&gt;Runtime option management&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;Improved JSON path operations&lt;/li&gt;
&lt;li&gt;Dynamic Action Control replacement&lt;/li&gt;
&lt;li&gt;Improved JavaScript interoperability&lt;/li&gt;
&lt;li&gt;Better browser history integration&lt;/li&gt;
&lt;li&gt;Improved memory management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to eliminate imperative development.&lt;/p&gt;

&lt;p&gt;Instead, WebForms Core 2.1 provides higher-level abstractions where they are useful while preserving the direct, imperative capabilities of the WFC core.&lt;/p&gt;

&lt;p&gt;This makes it possible to move between low-level DOM instructions, reusable Components, declarative conditions and loops, metadata-driven UI generation, and more advanced server-driven application architectures—all within the same technology.&lt;/p&gt;

</description>
      <category>news</category>
      <category>serverdriven</category>
      <category>webdev</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>CodeBehind 4.7 Released</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Thu, 03 Sep 2026 18:45:37 +0000</pubDate>
      <link>https://dev.to/elanatframework/codebehind-47-released-4p3c</link>
      <guid>https://dev.to/elanatframework/codebehind-47-released-4p3c</guid>
      <description>&lt;p&gt;After continued development and a strong focus on improving the integration between CodeBehind and WebForms Core, Elanat has released CodeBehind version 4.7.&lt;/p&gt;

&lt;p&gt;This release introduces several important architectural and structural improvements designed to provide better support for WebForms Core technology, simplify MVC development, improve request processing, and increase overall framework stability.&lt;/p&gt;

&lt;p&gt;CodeBehind 4.7 also includes an upgrade to WebForms Core version 2.1. WebForms Core 2.1 is a major update that introduces high-level capabilities and advanced features, representing another important step in the evolution of WebForms Core technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features of Version 4.7
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CodeBehindConstructor Merged into the PageLoad Method
&lt;/h3&gt;

&lt;p&gt;In CodeBehind version 4.7, the CodeBehindConstructor method has been completely removed and its functionality has been integrated into the PageLoad method.&lt;/p&gt;

&lt;p&gt;This change has been made to simplify the MVC development pattern and provide a more unified structure for Controllers and Models.&lt;/p&gt;

&lt;p&gt;With the new structure, a standard Controller uses PageLoad without parentheses when it is invoked with the context.&lt;/p&gt;

&lt;p&gt;For Models, when the Abstract option is enabled, omitting parentheses after the Model name automatically causes the context to be passed to the Model.&lt;/p&gt;

&lt;p&gt;For non-Abstract Models defined inside triple braces, parentheses are taken into consideration when determining the method invocation. If parentheses are not specified, the PageLoad method will not be executed.&lt;/p&gt;

&lt;p&gt;This change simplifies the MVC structure and makes initialization behavior more consistent across Controllers and Models.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write Output Added After the View
&lt;/h3&gt;

&lt;p&gt;Starting with CodeBehind version 4.7, data added to the response through the Write method in Controllers and Models is placed after the View output.&lt;/p&gt;

&lt;p&gt;This change has been introduced to improve compliance with HTML standards. A standard HTML document begins with the &lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/code&gt; declaration, and placing additional output before the View can result in content being written before the expected HTML document structure.&lt;/p&gt;

&lt;p&gt;The new behavior also provides better compatibility with WebForms Core in situations where HTML is sent together with Action Control data.&lt;/p&gt;

&lt;p&gt;By placing Write output after the View, CodeBehind provides a cleaner response structure and better coordination between View rendering and WebForms Core processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Content-Type for PostBack Requests
&lt;/h3&gt;

&lt;p&gt;A new configuration option named &lt;code&gt;SetTextHtmlContentTypeForPostBack&lt;/code&gt; has been introduced to automatically set the response Content-Type header for PostBack requests.&lt;/p&gt;

&lt;p&gt;When enabled, the response Content-Type is set to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;text/html; charset=utf-8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This provides more consistent response handling for PostBack requests and improves compatibility with WebForms Core responses that contain HTML content.&lt;/p&gt;

&lt;p&gt;The corresponding configuration option is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;set_text_html_content_type_for_post_back=true&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate DLL and View Paths
&lt;/h3&gt;

&lt;p&gt;CodeBehind 4.7 introduces a new structure that separates the path used for DLL files from the path used for View files.&lt;/p&gt;

&lt;p&gt;DLL files can now be stored in a location independent of the View directory. This provides greater flexibility when organizing application files and makes it possible to keep View files inside the &lt;code&gt;wwwroot&lt;/code&gt; directory while storing compiled DLL files in a separate and more secure location.&lt;/p&gt;

&lt;p&gt;Two new configuration options have been added to manage DLL paths.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;dll_path&lt;/code&gt; option specifies the directory used for DLL files.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;move_dll_from_wwwroot_bin&lt;/code&gt; option determines whether DLL files generated in the &lt;code&gt;wwwroot/bin&lt;/code&gt; directory should automatically be moved to the configured DLL directory after View files are recompiled.&lt;/p&gt;

&lt;p&gt;This separation improves application structure and provides a better distinction between publicly accessible web resources and compiled application components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixed Concurrent Initial View Compilation Requests
&lt;/h3&gt;

&lt;p&gt;An issue related to concurrent initial requests during the creation and compilation of View files has been resolved.&lt;/p&gt;

&lt;p&gt;Previously, multiple requests arriving while View files were being created or compiled could result in concurrency-related problems.&lt;/p&gt;

&lt;p&gt;The internal handling of this process has been improved to provide more reliable behavior when multiple requests reach the application during initial View compilation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improved Form Data Handling
&lt;/h3&gt;

&lt;p&gt;CodeBehind 4.7 introduces an improvement to the way Form data is accessed from incoming requests.&lt;/p&gt;

&lt;p&gt;Form data should now be accessed only after verifying that the request contains Form content through &lt;code&gt;HasFormContentType&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This change improves request processing and prevents unnecessary attempts to read Form data from requests that do not contain Form content.&lt;/p&gt;

&lt;p&gt;For easier and safer access, CodeBehind also provides the &lt;code&gt;IfForm&lt;/code&gt; extension method, allowing Form data to be conditionally accessed through a simplified structure.&lt;/p&gt;

&lt;p&gt;This provides a more convenient approach for applications that need to handle different types of incoming requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improved Request Management and Framework Stability
&lt;/h3&gt;

&lt;p&gt;The request management system has been improved through the use of more advanced internal mechanisms designed to prevent unexpected framework failures.&lt;/p&gt;

&lt;p&gt;These improvements strengthen the handling of concurrent and complex requests and reduce the possibility of framework crashes caused by problematic request conditions.&lt;/p&gt;

&lt;p&gt;The changes provide a more stable execution environment and improve the overall reliability of CodeBehind applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete Rewrite of WebSocket and SSE Middleware
&lt;/h3&gt;

&lt;p&gt;The middleware and related classes responsible for WebSocket and Server-Sent Events (SSE) have been completely rewritten.&lt;/p&gt;

&lt;p&gt;This is a significant internal improvement to the real-time communication infrastructure of CodeBehind.&lt;/p&gt;

&lt;p&gt;The rewritten implementation provides better internal coordination, improved request and connection management, and a stronger foundation for WebSocket and SSE communication.&lt;/p&gt;

&lt;p&gt;This change also improves the compatibility and integration of real-time communication with the latest WebForms Core architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebForms Core Technology Upgraded to Version 2.1
&lt;/h3&gt;

&lt;p&gt;CodeBehind 4.7 includes an upgrade to WebForms Core version 2.1.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.1 is a major update that introduces advanced capabilities and high-level features, continuing the architectural evolution introduced with WebForms Core version 2.&lt;/p&gt;

&lt;p&gt;This upgrade provides closer coordination between CodeBehind and WebForms Core and expands the capabilities available when building applications using the two technologies together.&lt;/p&gt;

&lt;p&gt;WebForms Core 2.1 further develops the client-side execution architecture and provides new capabilities for building complex interactive web applications while maintaining the command-driven approach of WebForms Core.&lt;/p&gt;

&lt;p&gt;Additional information about the features and capabilities introduced in WebForms Core version 2.1 will be published separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Improvements
&lt;/h3&gt;

&lt;p&gt;CodeBehind 4.7 also includes several additional internal improvements focused on performance, stability, request processing, and compatibility with WebForms Core.&lt;/p&gt;

&lt;p&gt;Together, these changes improve the overall architecture of the framework and provide a more reliable foundation for applications built with CodeBehind.&lt;/p&gt;

&lt;p&gt;CodeBehind 4.7 represents an important step in the continued development of the framework, with a particular focus on simplifying MVC development, improving HTML standards compliance, strengthening request handling, separating application components, and providing deeper integration with WebForms Core.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;p&gt;CodeBehind on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elanatframework/Code_behind" rel="noopener noreferrer"&gt;https://github.com/elanatframework/Code_behind&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get CodeBehind from NuGet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nuget.org/packages/CodeBehind/" rel="noopener noreferrer"&gt;https://www.nuget.org/packages/CodeBehind/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeBehind page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elanat.net/page_content/code_behind" rel="noopener noreferrer"&gt;https://elanat.net/page_content/code_behind&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>codebehind</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>storage_size.js Module in WebForms Core</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Fri, 28 Aug 2026 14:27:36 +0000</pubDate>
      <link>https://dev.to/elanatframework/storagesizejs-module-in-webforms-core-241b</link>
      <guid>https://dev.to/elanatframework/storagesizejs-module-in-webforms-core-241b</guid>
      <description>&lt;h2&gt;
  
  
  What is WebForms Core?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; is a modern technology from &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;, introduced in 2024, that provides a two-way communication model between server-side code and the client-side WebFormsJS library. Its main purpose is to allow the server to control HTML elements and execute client-side operations without requiring extensive frontend code.&lt;/p&gt;

&lt;p&gt;In this architecture, instead of sending large amounts of data or complete page structures, the server sends compact commands to the client. WebFormsJS executes these commands in the browser and can also return the result of client-side operations back to the server.&lt;/p&gt;

&lt;p&gt;One of the important capabilities of WebForms Core is its support for &lt;strong&gt;JavaScript modules&lt;/strong&gt;. Server-side code can dynamically load a JavaScript module, call its exported methods, and retrieve their return values.&lt;/p&gt;

&lt;p&gt;This article demonstrates this capability using the &lt;code&gt;storage_size.js&lt;/code&gt; module.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to use WebForms Core technology?
&lt;/h2&gt;

&lt;p&gt;Two steps are required.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. On the client side
&lt;/h3&gt;

&lt;p&gt;Add WebFormsJS to the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFormsJS is responsible for receiving WebForms Core commands and executing them in the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. On the server side
&lt;/h3&gt;

&lt;p&gt;Import the WebForms class for your server-side programming language.&lt;/p&gt;

&lt;p&gt;For this example, we use C# with the &lt;a href="https://github.com/elanatframework/Code_behind" rel="noopener noreferrer"&gt;CodeBehind&lt;/a&gt; framework.&lt;/p&gt;




&lt;h1&gt;
  
  
  Server-side JavaScript Module Loading
&lt;/h1&gt;

&lt;p&gt;WebForms Core allows server-side code to dynamically load JavaScript modules on the client.&lt;/p&gt;

&lt;p&gt;The server can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"/script/module/storage_size.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command loads the &lt;code&gt;storage_size.js&lt;/code&gt; module and makes the &lt;code&gt;sz_GetStorageSize&lt;/code&gt; method available for server-side invocation.&lt;/p&gt;

&lt;p&gt;After loading the module, the server can call the method using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it possible to request information from browser APIs and return the result to the server.&lt;/p&gt;




&lt;h1&gt;
  
  
  Introducing the Storage Size Module
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;storage_size.js&lt;/code&gt; module provides a simple interface for obtaining the size of different browser storage mechanisms.&lt;/p&gt;

&lt;p&gt;The module exposes the following method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sz_GetStorageSize(type, unit)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first parameter specifies the storage type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cache
cookie
indexeddb
localstorage
sessionstorage
origin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second parameter specifies the output unit.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;B
KB
MB
GB
TB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no unit is specified, the result is returned in bytes.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sz_GetStorageSize("cache")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns the size in bytes.&lt;/p&gt;

&lt;p&gt;While:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sz_GetStorageSize("origin", "MB")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns the result in megabytes.&lt;/p&gt;




&lt;h1&gt;
  
  
  Storage Types
&lt;/h1&gt;

&lt;p&gt;The module supports several browser storage mechanisms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cache
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;cache&lt;/code&gt; option calculates the size of responses stored through the Cache Storage API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cookie
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;cookie&lt;/code&gt; option calculates the size of the cookies accessible through JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  IndexedDB
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;indexeddb&lt;/code&gt; option calculates an &lt;strong&gt;approximate logical size&lt;/strong&gt; of the data stored in IndexedDB.&lt;/p&gt;

&lt;p&gt;Because browsers do not provide a standard API for obtaining the exact physical disk usage of IndexedDB, this value is an estimation based on the stored records.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Storage
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;localstorage&lt;/code&gt; option calculates the size of the key/value data stored in &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Session Storage
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;sessionstorage&lt;/code&gt; option calculates the size of the key/value data stored in &lt;code&gt;sessionStorage&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Origin
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;origin&lt;/code&gt; option uses the browser's Storage API to obtain the storage usage reported for the current Origin.&lt;/p&gt;

&lt;p&gt;This value represents the browser-reported storage usage for the Origin and should not be considered the sum of the individual values returned by the other options.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example Project
&lt;/h1&gt;

&lt;p&gt;The example project contains the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project Root
├── WebForms.cs
├── Controller.cs
└── wwwroot
    ├── page.aspx
    ├── layout.aspx
    ├── script
    │   ├── web-forms.js
    │   └── module
    │       └── storage_size.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  View (&lt;code&gt;page.aspx&lt;/code&gt;)
&lt;/h1&gt;

&lt;p&gt;The page contains a button that triggers the server-side operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller ModuleStorageSizeController
@layout "/layout.aspx"
@{
    ViewData.Add("title", "Module Storage Size");
}

&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;WebForms Core - Storage Size Module&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the button is clicked, a request is sent to the server and the server executes the module-related operation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Server-side Controller (&lt;code&gt;Controller.cs&lt;/code&gt;)
&lt;/h1&gt;

&lt;p&gt;The controller contains the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ModuleStorageSizeController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"load"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Button1_OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetGetEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"?load"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Button1_OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"0123456789"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="m"&gt;3600&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateFormatStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"0123456789"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCacheValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"0123456789"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"0123456789"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"/script/module/storage_size.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"@: Cache: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"B"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"@: Cookie: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cookie"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"B"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"@: Indexed DB: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"indexeddb"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"B"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"@: Local Storage: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"localstorage"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"B"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"@: Session Storage: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"sessionstorage"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"B"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"@: Origin: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MB"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"MB"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;IgnoreAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Page Request
&lt;/h1&gt;

&lt;p&gt;When &lt;code&gt;page.aspx&lt;/code&gt; is initially requested, a new instance of &lt;code&gt;ModuleStorageSizeController&lt;/code&gt; is created and the &lt;code&gt;PageLoad&lt;/code&gt; method is executed.&lt;/p&gt;

&lt;p&gt;The controller first checks whether the &lt;code&gt;load&lt;/code&gt; query exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"load"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Button1_OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the query does not exist, the server registers a GET event for the button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetGetEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"Button1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"?load"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting WebForms Core command is added to the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--[web-forms
EgButton1=onclick|?load
]--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, clicking the button causes a request to the server with the &lt;code&gt;load&lt;/code&gt; query.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;code&gt;Button1_OnClick&lt;/code&gt; Method
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;Button1_OnClick&lt;/code&gt; method performs the main operation.&lt;/p&gt;

&lt;p&gt;Its purpose is to create some browser-side storage data, load the JavaScript module, request storage sizes from the client, and display the results.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Create a WebForms Object
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;WebForms&lt;/code&gt; object is used to create the commands that will be sent between the server and client.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Create Test Storage Data
&lt;/h2&gt;

&lt;p&gt;The example first creates data in several storage mechanisms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cookie
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"0123456789"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a cookie containing the value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0123456789
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a lifetime of 3600 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  IndexedDB
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateFormatStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"0123456789"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates test data in the Format Storage implementation backed by IndexedDB.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Storage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCacheValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"0123456789"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a value in Local Storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Session Storage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"0123456789"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a value in Session Storage.&lt;/p&gt;

&lt;p&gt;These operations provide sample data so that the storage size module has data to inspect.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Load the JavaScript Module
&lt;/h1&gt;

&lt;p&gt;The module is loaded using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LoadModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"/script/module/storage_size.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells WebForms Core to load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/script/module/storage_size.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and expose its:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sz_GetStorageSize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;method.&lt;/p&gt;

&lt;p&gt;The important point is that the server does not need to implement browser storage APIs itself. Instead, it requests the browser to execute the JavaScript module.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Call the Module Method
&lt;/h1&gt;

&lt;p&gt;The server calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first parameter is the module method name.&lt;/p&gt;

&lt;p&gt;The second parameter contains the arguments that will be passed to the JavaScript method.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"localstorage"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;corresponds conceptually to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;sz_GetStorageSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localstorage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;on the client.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Injecting the Module Method Result
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;Fetch.ModuleMethod()&lt;/code&gt; function creates a command for executing a method of the loaded JavaScript module on the client side.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;corresponds to calling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;sz_GetStorageSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the browser.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Inject()&lt;/code&gt; method can be used together with &lt;code&gt;Fetch.ModuleMethod()&lt;/code&gt; to insert the result of the client-side method execution into the generated WebForms Core command.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"@: Cache: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
    &lt;span class="s"&gt;"B"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the storage size is calculated &lt;strong&gt;on the client side&lt;/strong&gt; by &lt;code&gt;storage_size.js&lt;/code&gt;. The result is then injected into the client-side command generated by WebForms Core and used as part of the message displayed by WebFormsJS.&lt;/p&gt;

&lt;p&gt;Therefore, no value is sent back to the server. The server only defines the module method call and constructs the command; the JavaScript module executes the operation in the browser and the result is used on the client side.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Getting Different Storage Sizes
&lt;/h1&gt;

&lt;p&gt;The controller requests the size of Cache Storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cookie:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cookie"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IndexedDB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"indexeddb"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Local Storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"localstorage"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Session Storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"sessionstorage"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, the total Origin storage usage is requested in megabytes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ModuleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sz_GetStorageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MB"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second argument changes the unit returned by the module.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Sending the Response
&lt;/h1&gt;

&lt;p&gt;The example uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nf"&gt;IgnoreAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;IgnoreAll()&lt;/code&gt; prevents the View and Layout from being sent again.&lt;/p&gt;

&lt;p&gt;Only the generated WebForms Core response is returned to the client.&lt;/p&gt;

&lt;p&gt;The response contains the commands required to execute the module method calls and display their results.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Output
&lt;/h1&gt;

&lt;p&gt;After clicking the button, the browser executes the requested module methods and the resulting values are displayed as messages.&lt;/p&gt;

&lt;p&gt;The output is conceptually similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache: 10B
Cookie: 14B
Indexed DB: 10B
Local Storage: 14B
Session Storage: 14B
Origin: 0.01MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact values depend on the browser and the storage implementation.&lt;/p&gt;

&lt;p&gt;In particular, the IndexedDB value is an approximation, while the Origin value is reported by the browser's Storage API.&lt;/p&gt;




&lt;h1&gt;
  
  
  Execution Flow
&lt;/h1&gt;

&lt;p&gt;The complete execution flow can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   │
   │ Click Button
   ▼
Server
   │
   │ LoadModule()
   │ Fetch.ModuleMethod()
   │ Inject()
   ▼
WebForms Core Response
   │
   │ Sends module commands
   ▼
WebFormsJS
   │
   │ Load storage_size.js
   │
   │ Execute sz_GetStorageSize()
   ▼
Browser Storage APIs
   │
   │ Calculate storage size
   ▼
WebFormsJS
   │
   │ Use the returned value
   │ │
   │ └── Display through Message
   ▼
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this flow, the storage size is calculated entirely on the client side. The server does not receive the calculated value. Instead, the server creates the WebForms Core commands using &lt;code&gt;LoadModule()&lt;/code&gt;, &lt;code&gt;Fetch.ModuleMethod()&lt;/code&gt;, and &lt;code&gt;Inject()&lt;/code&gt;. These commands are sent to WebFormsJS, which loads the module, executes &lt;code&gt;sz_GetStorageSize()&lt;/code&gt;, obtains the value from the browser's storage APIs, and uses the returned value directly on the client side.&lt;/p&gt;

&lt;p&gt;This demonstrates that a WebForms Core module method can perform a client-side operation and use its return value within the client-side execution of the generated WebForms Core commands, without requiring another request to the server.&lt;/p&gt;




&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;storage_size.js&lt;/code&gt; module demonstrates how &lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; can use reusable JavaScript modules to perform browser-side operations under server-side control.&lt;/p&gt;

&lt;p&gt;The server dynamically loads the module with &lt;code&gt;LoadModule()&lt;/code&gt; and defines calls to &lt;code&gt;sz_GetStorageSize()&lt;/code&gt; using &lt;code&gt;Fetch.ModuleMethod()&lt;/code&gt;. When the WebForms Core response is processed by WebFormsJS, the module is loaded in the browser and the requested method is executed using the browser's Storage APIs.&lt;/p&gt;

&lt;p&gt;The result of the module method is used directly on the client side through the generated WebForms Core commands. No additional request is required to send the calculated storage size back to the server.&lt;/p&gt;

&lt;p&gt;This architecture allows browser-specific functionality to remain inside reusable JavaScript modules while the server controls when the module is loaded, which methods are invoked, and how their results are used in the client-side response.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;storage_size.js&lt;/code&gt; example demonstrates how this approach can be used to work with Cache Storage, Cookies, IndexedDB, Local Storage, Session Storage, and Origin storage usage without requiring a large client-side framework.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>frontend</category>
      <category>dotnet</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Morphing Feature in WebForms Core 2.1</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Wed, 26 Aug 2026 18:31:27 +0000</pubDate>
      <link>https://dev.to/elanatframework/morphing-feature-in-webforms-core-21-5d6o</link>
      <guid>https://dev.to/elanatframework/morphing-feature-in-webforms-core-21-5d6o</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; 2.1 is coming soon from &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;.&lt;/strong&gt; The new version introduces a collection of capabilities designed to further expand the server-driven approach of WebForms Core. One of these new capabilities is &lt;strong&gt;Morphing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Morphing provides a way to synchronize an existing DOM element with a new HTML structure &lt;strong&gt;without necessarily replacing the existing element itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This makes it possible to update HTML structures while preserving the identity of existing DOM elements.&lt;/p&gt;




&lt;h2&gt;
  
  
  Morphing
&lt;/h2&gt;

&lt;p&gt;Morphing is a DOM synchronization mechanism that compares an existing HTML element with a new HTML structure and applies the required changes to the existing DOM.&lt;/p&gt;

&lt;p&gt;Unlike a traditional replacement operation such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Morphing does not simply discard the existing element and create another one.&lt;/p&gt;

&lt;p&gt;Instead, it analyzes the existing element and the new element and performs the necessary operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add new attributes&lt;/li&gt;
&lt;li&gt;Update existing attributes&lt;/li&gt;
&lt;li&gt;Remove attributes that no longer exist&lt;/li&gt;
&lt;li&gt;Add new child elements&lt;/li&gt;
&lt;li&gt;Update existing child elements&lt;/li&gt;
&lt;li&gt;Remove obsolete child elements&lt;/li&gt;
&lt;li&gt;Match elements using &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;cb-data-id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Preserve existing DOM element identity whenever possible&lt;/li&gt;
&lt;li&gt;Preserve registered event listeners when new Nodes have to be created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make the smallest necessary changes to the DOM.&lt;/p&gt;




&lt;h1&gt;
  
  
  Reflection vs Morphing
&lt;/h1&gt;

&lt;p&gt;WebForms Core 2.1 contains both &lt;strong&gt;Reflection&lt;/strong&gt; and &lt;strong&gt;Morphing&lt;/strong&gt;, but they serve different purposes.&lt;/p&gt;

&lt;p&gt;Reflection is primarily a &lt;strong&gt;merge operation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, if the target contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;User&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the source contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"premium"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;VIP&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reflection can merge the source into the target, adding the class and child without treating the source as a complete replacement definition.&lt;/p&gt;

&lt;p&gt;Morphing has a different philosophy.&lt;/p&gt;

&lt;p&gt;The source represents the &lt;strong&gt;desired structure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the source does not contain an element or attribute that exists in the target, Morphing can remove it.&lt;/p&gt;

&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reflection
    Target + Source
         ↓
       Merge

Morphing
    Target → Source
         ↓
      Synchronize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction makes both mechanisms useful for different types of server-driven UI operations.&lt;/p&gt;




&lt;h1&gt;
  
  
  The WebForms Core API
&lt;/h1&gt;

&lt;p&gt;Morphing can be invoked from the WebForms class.&lt;/p&gt;

&lt;p&gt;The first method accepts HTML directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nf"&gt;SetMorph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second method uses an existing element as the source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nf"&gt;SetMorphByOutputPlace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;OutputPlace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMorphByOutputPlace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"userCard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"userCardTemplate"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;userCard&lt;/code&gt; is the destination element.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;userCardTemplate&lt;/code&gt; is the source element.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The developer does not need to manually write JavaScript to perform the DOM synchronization.&lt;/p&gt;




&lt;h1&gt;
  
  
  A Complete Example
&lt;/h1&gt;

&lt;p&gt;Consider the following page.&lt;/p&gt;

&lt;p&gt;Initially, the page contains a user card:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;
     &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;
     &lt;span class="na"&gt;data-user=&lt;/span&gt;&lt;span class="s"&gt;"123"&lt;/span&gt;
     &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"border: 1px solid #ccc; padding: 10px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;User&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userEmail"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Email: user@example.com
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"editButton"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-edit"&lt;/span&gt;
            &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"editUser()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Edit
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"oldTag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Old tag
    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A template describes the new state of this element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCardTemplate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card premium"&lt;/span&gt;
         &lt;span class="na"&gt;data-user=&lt;/span&gt;&lt;span class="s"&gt;"456"&lt;/span&gt;
         &lt;span class="na"&gt;data-role=&lt;/span&gt;&lt;span class="s"&gt;"admin"&lt;/span&gt;
         &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background-color: #f0f8ff; border: 2px solid blue; margin: 5px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;User&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"editButton"&lt;/span&gt;
                &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-vip"&lt;/span&gt;
                &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"VIP()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            VIP
        &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"newTag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            New tag
        &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The controller can perform the Morph operation with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MorphController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Checking "Post-Back" in Request Headers for Maintain Interactive mode when Refreshing the Page in the Browser.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"set-morph"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Post-Back"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;SetMorph_OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetMorph_OnClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMorphByOutputPlace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"userCardTemplate"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;IgnoreAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The page can trigger the operation with a normal WebForms Core request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"?set-morph"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click to Link for Morph&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  What happens during Morphing?
&lt;/h1&gt;

&lt;p&gt;Before Morphing, the target is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;
     &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;
     &lt;span class="na"&gt;data-user=&lt;/span&gt;&lt;span class="s"&gt;"123"&lt;/span&gt;
     &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"border: 1px solid #ccc; padding: 10px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;User&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userEmail"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Email: user@example.com
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"editButton"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-edit"&lt;/span&gt;
            &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"editUser()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Edit
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"oldTag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Old tag
    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The source describes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;
     &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card premium"&lt;/span&gt;
     &lt;span class="na"&gt;data-user=&lt;/span&gt;&lt;span class="s"&gt;"456"&lt;/span&gt;
     &lt;span class="na"&gt;data-role=&lt;/span&gt;&lt;span class="s"&gt;"admin"&lt;/span&gt;
     &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background-color: #f0f8ff; border: 2px solid blue; margin: 5px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;User&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"editButton"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-vip"&lt;/span&gt;
            &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"VIP()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        VIP
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"newTag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        New tag
    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Morphing compares these two structures and applies the necessary changes.&lt;/p&gt;

&lt;p&gt;The resulting DOM becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;
     &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card premium"&lt;/span&gt;
     &lt;span class="na"&gt;data-user=&lt;/span&gt;&lt;span class="s"&gt;"456"&lt;/span&gt;
     &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background-color: #f0f8ff; border: 2px solid blue; margin: 5px;"&lt;/span&gt;
     &lt;span class="na"&gt;data-role=&lt;/span&gt;&lt;span class="s"&gt;"admin"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;User&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"editButton"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-vip"&lt;/span&gt;
            &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"VIP()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        VIP
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"newTag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        New tag
    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Attribute Morphing
&lt;/h1&gt;

&lt;p&gt;Attributes are synchronized between the target and source.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-user="123"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-user="456"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;data-role="admin"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is added.&lt;/p&gt;

&lt;p&gt;The class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;class="card"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;class="card premium"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the style is updated according to the source.&lt;/p&gt;

&lt;p&gt;Attributes that exist in the target but no longer exist in the source are removed.&lt;/p&gt;

&lt;p&gt;Therefore Morphing effectively synchronizes the attribute set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target attributes
        ↓
     Compare
        ↓
Source attributes
        ↓
Add / Update / Remove
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Child Element Morphing
&lt;/h1&gt;

&lt;p&gt;Morphing also operates recursively on child Nodes.&lt;/p&gt;

&lt;p&gt;In the example, this element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userEmail"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Email: user@example.com
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not exist in the new structure.&lt;/p&gt;

&lt;p&gt;Therefore it is removed.&lt;/p&gt;

&lt;p&gt;Likewise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"oldTag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Old tag
&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is removed.&lt;/p&gt;

&lt;p&gt;At the same time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"newTag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    New tag
&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is added.&lt;/p&gt;

&lt;p&gt;The existing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;User&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is retained and synchronized.&lt;/p&gt;




&lt;h1&gt;
  
  
  Element Matching
&lt;/h1&gt;

&lt;p&gt;One of the important parts of Morphing is determining whether a new element corresponds to an existing element.&lt;/p&gt;

&lt;p&gt;WebForms Core uses identifiers such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;id="editButton"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;cb-data-id="..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for this purpose.&lt;/p&gt;

&lt;p&gt;For example, both the old and new structures contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"editButton"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore Morphing can recognize that they represent the same DOM element.&lt;/p&gt;

&lt;p&gt;The existing Node can consequently be retained while its attributes and contents are updated.&lt;/p&gt;

&lt;p&gt;This is different from simply deleting the old button and creating a completely new button.&lt;/p&gt;




&lt;h1&gt;
  
  
  Event Listeners
&lt;/h1&gt;

&lt;p&gt;DOM cloning has an important limitation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;cloneNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not copy event listeners registered through &lt;code&gt;addEventListener&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;WebForms Core Morphing therefore integrates with the WebForms Core event registry.&lt;/p&gt;

&lt;p&gt;When Morphing needs to create a new Node, registered event listeners can be transferred to the new Node.&lt;/p&gt;

&lt;p&gt;This is particularly important for applications that dynamically update their interface while maintaining interactive behavior.&lt;/p&gt;

&lt;p&gt;The principle is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Existing Node
      ↓
Keep Node
      ↓
Keep its event listeners

New Node
      ↓
Create Node
      ↓
Transfer registered listeners
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows Morphing to modify the DOM without unnecessarily destroying its interactive state.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why use &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;?
&lt;/h1&gt;

&lt;p&gt;A &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; element is particularly convenient as the source of a Morph operation.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCardTemplate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"userCard"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        ...
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template provides a declarative representation of the desired HTML structure without displaying that structure directly on the page.&lt;/p&gt;

&lt;p&gt;This makes it possible to separate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Visible DOM
     +
Desired DOM structure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while keeping the desired structure inside the HTML document.&lt;/p&gt;

&lt;p&gt;WebForms Core can use the internal content of the &lt;code&gt;template&lt;/code&gt; as the source of the Morph operation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Morphing is not DOM Replacement
&lt;/h1&gt;

&lt;p&gt;A conventional replacement might effectively perform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The consequence is that the original DOM element is destroyed.&lt;/p&gt;

&lt;p&gt;Morphing instead attempts to preserve the existing element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Replace:

OLD NODE
   ↓
destroy
   ↓
NEW NODE


Morph:

OLD NODE
   ↓
compare
   ↓
modify
   ↓
same NODE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction becomes particularly useful for interactive interfaces.&lt;/p&gt;

&lt;p&gt;An element can have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;browser state&lt;/li&gt;
&lt;li&gt;registered event listeners&lt;/li&gt;
&lt;li&gt;references from application code&lt;/li&gt;
&lt;li&gt;associated DOM state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and Morphing can update its structure without necessarily discarding the element itself.&lt;/p&gt;




&lt;h1&gt;
  
  
  Server-Driven UI
&lt;/h1&gt;

&lt;p&gt;Morphing fits naturally into the architecture of WebForms Core.&lt;/p&gt;

&lt;p&gt;The server does not need to send an entire page.&lt;/p&gt;

&lt;p&gt;Instead, it can describe the desired UI operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMorphByOutputPlace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"userCard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"userCardTemplate"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core then performs the DOM synchronization on the client.&lt;/p&gt;

&lt;p&gt;This follows the broader WebForms Core philosophy of treating communication between server and browser as an &lt;strong&gt;instruction stream&lt;/strong&gt; rather than simply transferring complete HTML documents.&lt;/p&gt;

&lt;p&gt;The server determines &lt;strong&gt;what operation should happen&lt;/strong&gt;, while WebForms Core performs that operation in the browser.&lt;/p&gt;




&lt;h1&gt;
  
  
  Morphing vs Reflection
&lt;/h1&gt;

&lt;p&gt;The two capabilities can be summarized as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Reflection&lt;/th&gt;
&lt;th&gt;Morphing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Preserve target element&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add attributes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update attributes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove obsolete attributes&lt;/td&gt;
&lt;td&gt;No, merge-oriented&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add children&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update children&lt;/td&gt;
&lt;td&gt;Limited/merge-oriented&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove obsolete children&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recursive synchronization&lt;/td&gt;
&lt;td&gt;No/limited&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Match by &lt;code&gt;id&lt;/code&gt; / &lt;code&gt;cb-data-id&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preserve DOM identity&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intended purpose&lt;/td&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;Synchronize&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Reflection merges. Morphing synchronizes.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Morphing in WebForms Core 2.1 provides a declarative way to transform an existing DOM structure into a new structure while minimizing unnecessary DOM replacement.&lt;/p&gt;

&lt;p&gt;Instead of manually writing JavaScript to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;find element
→ compare attributes
→ remove attributes
→ update attributes
→ find children
→ remove children
→ create children
→ preserve events
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the server can simply describe the desired operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetMorphByOutputPlace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"userCard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"userCardTemplate"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core performs the synchronization on the client.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Reflection&lt;/strong&gt; for merging and &lt;strong&gt;Morphing&lt;/strong&gt; for structural synchronization, WebForms Core 2.1 adds two complementary mechanisms for declaratively manipulating the DOM from server-side code—without requiring a conventional front-end framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;WebForms Core in GitHub:&lt;br&gt;
&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;https://github.com/webforms-core&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>opensource</category>
      <category>frontend</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>.NET WebCIL Container Meets WebForms Core 2.1</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Wed, 26 Aug 2026 14:02:10 +0000</pubDate>
      <link>https://dev.to/elanatframework/net-webcil-container-meets-webforms-core-21-39f5</link>
      <guid>https://dev.to/elanatframework/net-webcil-container-meets-webforms-core-21-39f5</guid>
      <description>&lt;h2&gt;
  
  
  What is WebForms Core?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; is a modern multi-platform web technology from &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt; designed to build interactive web applications without requiring traditional client-side business logic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core uses a server-centric architecture in which the server defines UI behavior through commands, while a lightweight client engine executes those commands in the browser.&lt;/p&gt;

&lt;p&gt;With the upcoming &lt;strong&gt;WebForms Core 2.1 (WFC)&lt;/strong&gt;, this architecture is being extended with another interesting capability: &lt;strong&gt;C# code running inside a .NET WebAssembly environment can use WebForms Core itself to generate UI commands.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This makes it possible to combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C#&lt;/li&gt;
&lt;li&gt;.NET WebAssembly&lt;/li&gt;
&lt;li&gt;WebForms Core&lt;/li&gt;
&lt;li&gt;WebForms Core's declarative UI commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;inside the same WebAssembly application.&lt;/p&gt;




&lt;h1&gt;
  
  
  .NET WebCIL Container
&lt;/h1&gt;

&lt;p&gt;One of the new possibilities demonstrated with WFC 2.1 is the use of a &lt;strong&gt;.NET WebCIL Container&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of compiling C# into a standalone native-style WASM function such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add(10000, 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the application can load the .NET WebAssembly runtime and execute exported C# methods through &lt;code&gt;dotnet.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Runtime.InteropServices.JavaScript&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebFormsCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SetData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetHtml&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is that &lt;strong&gt;&lt;code&gt;WebForms.cs&lt;/code&gt; from WebForms Core is included in the WebAssembly project&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, C# code running inside the WebAssembly environment can directly create WebForms Core commands.&lt;/p&gt;




&lt;h1&gt;
  
  
  Creating the .NET WebCIL Project
&lt;/h1&gt;

&lt;p&gt;Create a new .NET 10 WebAssembly console project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new wasmconsole &lt;span class="nt"&gt;-n&lt;/span&gt; NativeWasmModule &lt;span class="nt"&gt;-f&lt;/span&gt; net10.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then enter the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;NativeWasmModule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project can use the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net10.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;WasmEnableExceptionHandling&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/WasmEnableExceptionHandling&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;RuntimeIdentifier&amp;gt;&lt;/span&gt;browser-wasm&lt;span class="nt"&gt;&amp;lt;/RuntimeIdentifier&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;OutputType&amp;gt;&lt;/span&gt;Exe&lt;span class="nt"&gt;&amp;lt;/OutputType&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AllowUnsafeBlocks&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/AllowUnsafeBlocks&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;WasmMainJSPath&amp;gt;&lt;/span&gt;main.mjs&lt;span class="nt"&gt;&amp;lt;/WasmMainJSPath&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project targets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net10.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;RuntimeIdentifier&amp;gt;&lt;/span&gt;browser-wasm&lt;span class="nt"&gt;&amp;lt;/RuntimeIdentifier&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;main.mjs&lt;/code&gt; file is specified as the JavaScript entry point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;WasmMainJSPath&amp;gt;&lt;/span&gt;main.mjs&lt;span class="nt"&gt;&amp;lt;/WasmMainJSPath&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Adding WebForms Core
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;WebForms.cs&lt;/code&gt; class from WebForms Core is added to this project.&lt;/p&gt;

&lt;p&gt;This is important because the WebAssembly C# code is now capable of using WebForms Core's API.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The C# method doesn't directly manipulate the browser DOM.&lt;/p&gt;

&lt;p&gt;Instead, it generates a &lt;strong&gt;WebForms Core response&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This keeps the same philosophy used throughout WebForms Core.&lt;/p&gt;




&lt;h1&gt;
  
  
  Exporting C# Methods
&lt;/h1&gt;

&lt;p&gt;Methods that should be accessible from JavaScript are marked with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method can then be accessed through the .NET WebAssembly runtime.&lt;/p&gt;

&lt;p&gt;A method can also return a WebForms Core response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SetData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the combination becomes particularly interesting.&lt;/p&gt;

&lt;p&gt;The WASM code isn't merely calculating a value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It can generate WebForms Core UI behavior.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Using C# WebAssembly from WebForms Core
&lt;/h1&gt;

&lt;p&gt;A WebForms Core controller can invoke the C# WebAssembly runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CsharpMediatorWasmController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/web-assembly/csharp-publish/_framework/dotnet.js"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;b&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WasmMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CSharpMediator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyClass.Add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CSharpMediator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyClass.SetData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CSharpMediator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyClass.GetHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the method names:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MyClass.Add
MyClass.SetData
MyClass.GetHtml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The class name can be specified before the method name.&lt;/p&gt;

&lt;p&gt;This makes it possible to address exported methods belonging to different C# types.&lt;/p&gt;




&lt;h1&gt;
  
  
  HTML
&lt;/h1&gt;

&lt;p&gt;The HTML remains simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller CsharpMediatorWasmController
@layout "/layout.aspx"

@{
    ViewData.Add("title", "C# Mediator Wasm");
}

&lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;.NET WebCIL Container&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;C# Mediator WASM Result: &lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Event
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Tag Changing!
&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Event With Output
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Html Output
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no custom WebAssembly element.&lt;/p&gt;

&lt;p&gt;There is no special DOM component.&lt;/p&gt;

&lt;p&gt;There is no C# component syntax.&lt;/p&gt;

&lt;p&gt;The HTML remains standard HTML.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Interesting Part
&lt;/h1&gt;

&lt;p&gt;Consider this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CSharpMediator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyClass.SetData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"h3Tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Text From Wasm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"lightgreen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"30px"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server declares:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When this button is clicked, execute &lt;code&gt;MyClass.SetData&lt;/code&gt; inside the C# WebAssembly runtime.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The method executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPlace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is then handled by WebForms Core.&lt;/p&gt;

&lt;p&gt;The C# WebAssembly method therefore becomes another source of WebForms Core commands.&lt;/p&gt;




&lt;h1&gt;
  
  
  WASM Event With Output
&lt;/h1&gt;

&lt;p&gt;The same mechanism can return HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetHtml&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;marquee&amp;gt;Tag From Wasm!&amp;lt;/marquee&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WasmEventWithOutput"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CSharpMediator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyClass.GetHtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned value is placed into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmHtmlOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates that the WASM method can be used not only for calculations, but also as a source of dynamic UI output.&lt;/p&gt;




&lt;p&gt;The screenshot below shows the HTML page after clicking the buttons.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj2w4z6i238yfwrx5skoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj2w4z6i238yfwrx5skoc.png" alt="WASM in WebForms Core" width="460" height="380"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  What Makes This Different?
&lt;/h1&gt;

&lt;p&gt;This is not simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run C# in the browser."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That capability already exists.&lt;/p&gt;

&lt;p&gt;The interesting part is the &lt;strong&gt;combination of C# WebAssembly and WebForms Core&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A C# method running inside WebAssembly can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebForms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and produce WebForms Core commands.&lt;/p&gt;

&lt;p&gt;That creates a pipeline like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C# WebAssembly
      ↓
  WebForms.cs
      ↓
WebForms Core Response
      ↓
WebForms Core Client Engine
      ↓
     DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WebAssembly code does not need to know how the browser DOM is implemented.&lt;/p&gt;

&lt;p&gt;It can describe the desired UI behavior through WebForms Core.&lt;/p&gt;




&lt;h1&gt;
  
  
  Native WASM and .NET WebCIL Are Different
&lt;/h1&gt;

&lt;p&gt;WebForms Core can work with different types of WebAssembly environments.&lt;/p&gt;

&lt;p&gt;For example, a native WASM module may expose a function such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and can be loaded directly as a &lt;code&gt;.wasm&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;The .NET approach is different.&lt;/p&gt;

&lt;p&gt;With the .NET WebCIL environment, the entry point is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the .NET runtime loads the necessary WebAssembly components.&lt;/p&gt;

&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Native WASM
     ↓
module.wasm
     ↓
WebAssembly.instantiate()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is conceptually different from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.NET WebAssembly
     ↓
dotnet.js
     ↓
.NET runtime
     ↓
C# exported method
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebForms Core can provide an abstraction over these different execution models.&lt;/p&gt;




&lt;h1&gt;
  
  
  No JavaScript Business Logic
&lt;/h1&gt;

&lt;p&gt;One of the most interesting properties of this example is that the application does not require custom JavaScript business logic.&lt;/p&gt;

&lt;p&gt;The C# code contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SetData&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTML contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Wasm Event
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the WebForms Core server code connects them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetWasmEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WasmEvent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CSharpMediator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WasmPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyClass.SetData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[...]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application logic remains in C#.&lt;/p&gt;




&lt;h1&gt;
  
  
  WebForms Core 2.1
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core 2.1, or simply WFC, is coming soon.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This release expands the possibilities of WebForms Core by allowing WebAssembly methods to participate more deeply in the WebForms Core execution model.&lt;/p&gt;

&lt;p&gt;The .NET WebCIL scenario is particularly interesting because developers can write C# methods such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;JSExport&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SetData&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and use the existing WebForms Core API inside those methods.&lt;/p&gt;

&lt;p&gt;This means that the same WebForms Core command model can be used from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server-side C#&lt;/li&gt;
&lt;li&gt;C# WebAssembly&lt;/li&gt;
&lt;li&gt;Native WebAssembly modules&lt;/li&gt;
&lt;li&gt;Other WASM-capable languages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;while the browser continues to use the WebForms Core client engine (&lt;a href="https://elanat.net/page_content/web_forms_js" rel="noopener noreferrer"&gt;WebFormsJS&lt;/a&gt;).&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Result
&lt;/h1&gt;

&lt;p&gt;This example demonstrates a new direction for WebForms Core:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C# WebAssembly can become an execution layer for WebForms Core rather than simply a replacement for JavaScript.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The architecture can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              WebForms Core
                    │
        ┌───────────┴───────────┐
        │                       │
     Server                 WebAssembly
        │                       │
   WebForms.cs               C# / WASM
        │                       │
        └───────────┬───────────┘
                    ↓
          WebForms Core Commands
                    ↓
               Browser DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And perhaps the most interesting point is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WebAssembly does not have to replace the WebForms Core model. It can become another execution environment for it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That opens the door to using high-performance compiled languages and .NET WebAssembly together with the declarative command architecture of WebForms Core.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebForms Core 2.1 is coming soon!&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  WebForms Core vs Blazor WebAssembly
&lt;/h1&gt;

&lt;p&gt;Compared with &lt;strong&gt;Blazor WebAssembly&lt;/strong&gt;, this approach in WebForms Core is not intended to run a complete .NET application in the browser. Instead, it can &lt;strong&gt;invoke a specific C# method as a WASM capability&lt;/strong&gt; and return its result to WebForms Core. In the example above, &lt;code&gt;MyClass.Add&lt;/code&gt;, &lt;code&gt;MyClass.SetData&lt;/code&gt;, and &lt;code&gt;MyClass.GetHtml&lt;/code&gt; are executed only when they are actually needed. Therefore, the architecture is much closer to a &lt;strong&gt;WASM Function Runtime&lt;/strong&gt; than to a WASM-based SPA. Furthermore, by using &lt;code&gt;WebForms&lt;/code&gt; within the C# code, even UI modification logic can be defined directly inside the C# method, with its output then passed to the WebForms Core engine.&lt;/p&gt;

&lt;p&gt;In contrast, &lt;strong&gt;Blazor WASM&lt;/strong&gt; provides a complete programming model for building .NET user interfaces in the browser, with a significant portion of the application logic and required runtime running on the client. WebForms Core can take a different approach: &lt;strong&gt;HTML remains standard HTML, WebForms Core manages UI behavior, and WASM is used only when specific capabilities need to be executed.&lt;/strong&gt; Therefore, the two are not necessarily direct competitors. Blazor WASM primarily focuses on running .NET applications in the browser through WebAssembly, whereas WebForms Core is &lt;strong&gt;not limited to WebAssembly and provides a broader architecture for developing and executing web behavior.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;WebForms Core in GitHub:&lt;br&gt;
&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;https://github.com/webforms-core&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>dotnet</category>
      <category>tutorial</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>CodeBehind 4.7 Coming Soon</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Mon, 06 Jul 2026 05:50:11 +0000</pubDate>
      <link>https://dev.to/elanatframework/codebehind-47-coming-soon-9od</link>
      <guid>https://dev.to/elanatframework/codebehind-47-coming-soon-9od</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/elanatframework/Code_behind" rel="noopener noreferrer"&gt;CodeBehind&lt;/a&gt; 4.7 will be released by &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt; in the coming days. This release introduces several important improvements that enhance support for and integration with WebForms Core (WFC). &lt;strong&gt;It also upgrades&lt;/strong&gt; WebForms Core to version 2.1. WFC 2.1 is a major update that introduces many new features and improvements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foscdaqu9cak3sqq0f5p6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foscdaqu9cak3sqq0f5p6.jpg" alt="CodeBehind 4.7" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CodeBehindConstructor has been removed
&lt;/h2&gt;

&lt;p&gt;In CodeBehind 4.7, the &lt;code&gt;CodeBehindConstructor&lt;/code&gt; method has been completely removed and merged into the &lt;code&gt;PageLoad&lt;/code&gt; method. This change simplifies the MVC programming model.&lt;/p&gt;

&lt;p&gt;In the new syntax, when the controller name is specified without parentheses, &lt;code&gt;HttpContext&lt;/code&gt; is automatically passed to &lt;code&gt;PageLoad&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Controller Examples
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller MyController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Controller&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller MyController()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Controller&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller MyController(123, "value")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Controller&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For abstract models, specifying the model name without parentheses automatically passes &lt;code&gt;HttpContext&lt;/code&gt; to &lt;code&gt;PageLoad&lt;/code&gt;. For non-abstract models declared inside curly braces (&lt;code&gt;{}&lt;/code&gt;), &lt;code&gt;PageLoad&lt;/code&gt; is invoked only when parentheses are specified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model Examples
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@model MyModel
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;@Value1&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;@Value2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindModel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@model MyModel()
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;@Value1&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;@Value2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindModel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@model MyModel("ABC")
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;@Value1&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;@Value2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindModel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@model {MyModel}
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;@Value1&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;@Value2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@model {MyModel()}
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;@Value1&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;@Value2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@model {MyModel(123, 'c')}
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;@Value1&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;@Value2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Value2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Constructor Behavior
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Controller Behavior&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@controller MyController&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates the controller and automatically passes &lt;code&gt;HttpContext&lt;/code&gt; to &lt;code&gt;PageLoad(HttpContext context)&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@controller MyController()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates the controller and calls &lt;code&gt;PageLoad()&lt;/code&gt; with no arguments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@controller MyController(args)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates the controller and calls &lt;code&gt;PageLoad(args)&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Abstract Model Behavior&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@model MyModel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates an abstract model and automatically passes &lt;code&gt;HttpContext&lt;/code&gt; to &lt;code&gt;PageLoad(HttpContext context)&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@model MyModel()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates an abstract model and calls &lt;code&gt;PageLoad()&lt;/code&gt; with no arguments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@model MyModel(args)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates an abstract model and calls &lt;code&gt;PageLoad(args)&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Model Behavior&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@model {MyModel}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a plain model only. &lt;code&gt;PageLoad&lt;/code&gt; is not called.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@model {MyModel()}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a plain model and calls &lt;code&gt;PageLoad()&lt;/code&gt; with no arguments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@model {MyModel(args)}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a plain model and calls &lt;code&gt;PageLoad(args)&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Write Output at the End of the Page
&lt;/h2&gt;

&lt;p&gt;Beginning with CodeBehind 4.7, data written by calling the &lt;code&gt;Write&lt;/code&gt; method from the Controller or Model is appended to the end of the View instead of being inserted at the beginning.&lt;/p&gt;

&lt;p&gt;This change ensures compliance with HTML standards, as an HTML document is expected to begin with &lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It also improves compatibility with &lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;WFC technology&lt;/a&gt; when HTML is sent together with Action Control data.&lt;/p&gt;

&lt;p&gt;The following example shows the difference between the behavior of &lt;code&gt;Write&lt;/code&gt; in CodeBehind 4.7 and earlier versions.&lt;/p&gt;

&lt;p&gt;View&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@page
@controller TextBoxController
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;CodeBehind Framework - Using WFC Technology&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"TextBox1"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Write Color"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Controller&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TextBoxController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;       
        &lt;span class="n"&gt;WebForms&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebForms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetGetEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TextBox1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnKeyUp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/keyup"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportToHtmlComment&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTML output in CodeBehind 4.7&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;CodeBehind Framework - Using WFC Technology&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"TextBox1"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Write Color"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--[web-forms]
EgTextBox1=onkeyup?keyup--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTML output in CodeBehind version 4.6 and earlier&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--[web-forms]
EgTextBox1=onkeyup?keyup--&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;CodeBehind Framework - Using WFC Technology&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/script/web-forms.js"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"TextBox1"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Write Color"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automatic Content-Type
&lt;/h2&gt;

&lt;p&gt;A new option automatically sets the response &lt;code&gt;Content-Type&lt;/code&gt; header to &lt;code&gt;text/html; charset=utf-8&lt;/code&gt; for PostBack requests.&lt;/p&gt;

&lt;p&gt;In some cases, when the server response is not valid XML, the browser attempts to parse it as XML and logs the following error in the console:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;XML Parsing Error: no root element found&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This error typically occurs when the response is empty or when it does not contain a valid XML document.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnv1fg26gqfys6acx34v2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnv1fg26gqfys6acx34v2.jpg" alt="Response header error fixing" width="441" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To prevent this, enable the following option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;...
&lt;span class="p"&gt;ignore_layout_for_post_back=false
&lt;/span&gt;&lt;span class="gi"&gt;+set_text_html_content_type_for_post_back=true
&lt;/span&gt;&lt;span class="p"&gt;sse_interval=1000
&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When enabled, the framework sets the response &lt;code&gt;Content-Type&lt;/code&gt; header to &lt;code&gt;text/html; charset=utf-8&lt;/code&gt;, preventing the browser from attempting to parse the response as XML and eliminating the parsing error.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;set_text_html_content_type_for_post_back&lt;/code&gt; option is enabled by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate DLL Paths
&lt;/h2&gt;

&lt;p&gt;DLL and View paths can now be configured independently.&lt;br&gt;
This allows View files to remain under &lt;code&gt;wwwroot&lt;/code&gt; while DLLs are stored in a secure directory.&lt;/p&gt;

&lt;p&gt;Two new options have been added to the Options file (&lt;code&gt;options.ini&lt;/code&gt;) to manage the DLL path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;[CodeBehind-options]
&lt;span class="p"&gt;view_path=wwwroot
move_view_from_wwwroot=true
&lt;/span&gt;&lt;span class="gi"&gt;+dll_path=wwwroot/bin
+move_dll_from_wwwroot_bin=true
&lt;/span&gt;&lt;span class="p"&gt;rewrite_aspx_file_to_directory=false
access_aspx_file_after_rewrite=false
&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;move_dll_from_wwwroot_bin&lt;/code&gt; is enabled, DLL files are automatically moved from &lt;code&gt;wwwroot/bin&lt;/code&gt; to the directory specified by &lt;code&gt;dll_path&lt;/code&gt; after the View files are recompiled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;CodeBehind 4.7 is a significant step forward in refining the framework. Rather than focusing solely on new features, this release improves the overall developer experience by simplifying the API, making framework behavior more consistent, introducing a cleaner MVC programming model, improving integration with WebForms Core (WFC), and providing more flexible project deployment options.&lt;/p&gt;

&lt;p&gt;These improvements make CodeBehind more intuitive, maintainable, and better suited for building modern web applications.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>backend</category>
      <category>news</category>
      <category>codebehind</category>
    </item>
    <item>
      <title>WebForms Core 2.1 - Coming Soon!</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Wed, 10 Jun 2026 21:56:47 +0000</pubDate>
      <link>https://dev.to/elanatframework/webforms-core-21-coming-soon-mbc</link>
      <guid>https://dev.to/elanatframework/webforms-core-21-coming-soon-mbc</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/elanatframework" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt; Development Team&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;We are proud to announce that version &lt;strong&gt;2.1&lt;/strong&gt; of the &lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;WebForms Core&lt;/a&gt; technology will be released soon. This is a major update, built after 4 months of hard work by the Elanat team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update Strategy
&lt;/h2&gt;

&lt;p&gt;Updates in WebForms Core technology are performed sequentially in increments of one-tenth (0.1). We started with version 1.0, the next version was 1.1, and each time we added one-tenth to the version number. The update of the WebForms class on the server side (C# programming language) is performed simultaneously with the update of the WebFormsJS library on the client side. Currently, version 2.1 has been released for both, and they are in complete harmony.&lt;/p&gt;

&lt;p&gt;One-hundredth updates (such as 2.0.1) are considered minor updates; these updates do not add new features that require changes in the other part, and they will remain compatible with the same major version.&lt;/p&gt;

&lt;p&gt;Please note that the WFC technology is first released for the WebForms class in the C# programming language, and then it will be ported to popular web programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 2.1; Another Major Update
&lt;/h2&gt;

&lt;p&gt;Version 2.1, like the previous two versions, is a major and foundational update. This release includes significant changes and improvements that elevate the development experience with WebForms Core to a higher level. Using advanced methods in this version significantly reduces the number of required instructions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25qym86xjmne7ilnt9u5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25qym86xjmne7ilnt9u5.jpg" alt="WebForms Core 2.1" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Most Important Innovations in Version 2.1
&lt;/h2&gt;

&lt;h3&gt;
  
  
  High-Level Declarative Features
&lt;/h3&gt;

&lt;p&gt;This version creates a higher abstraction over the WFC core. Developers can now benefit from declarative development alongside imperative development.&lt;/p&gt;

&lt;h3&gt;
  
  
  New ForEach Capability
&lt;/h3&gt;

&lt;p&gt;In version 2.1, the powerful ForEach feature has been added to WFC technology. There is no longer any need to use GoTo statements or manually create and delete data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fundamental Change in Separator
&lt;/h3&gt;

&lt;p&gt;One of the most important changes in this version concerns the Separator. In version 2.1, the Vertical bar character (|) along with the comma character (,) have been removed as separators, replaced by characters number 28, 29, 30, and 31 in ASCII codes 128. From now on, there will be no conflicts or disruptions in this area.&lt;/p&gt;

&lt;h3&gt;
  
  
  New Template Engine
&lt;/h3&gt;

&lt;p&gt;The template rendering system is a new declarative structure that replaces repetitive, imperative Replace operations. This engine automatically and intelligently places data into HTML templates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Storage Capabilities
&lt;/h3&gt;

&lt;p&gt;New capabilities have been added for managing stored JSON data, providing great flexibility in all four CRUD operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Significant State Management Improvements
&lt;/h3&gt;

&lt;p&gt;State in version 2.1 works more stably. SPA links now automatically control browser history in a manner completely consistent with regular links. The performance of the browser's Back and Forward buttons has also been optimized.&lt;/p&gt;

&lt;h3&gt;
  
  
  Segment Capability for URL and Hash
&lt;/h3&gt;

&lt;p&gt;A new feature that helps you create much more powerful SPA systems. This mechanism is also automatically activated for links.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dedicated Debugger
&lt;/h3&gt;

&lt;p&gt;A powerful debugging tool has been added to this release, providing step-through debugging for Action Controls code. You will experience Step, Go, Start, Stop, and Pause directly in your browser!&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced JSON Operations
&lt;/h3&gt;

&lt;p&gt;In version 2.1, working with JSON data has become much more professional. Conditional queries and negative indexing for JSON paths are now possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  New Replace Capabilities
&lt;/h3&gt;

&lt;p&gt;Several new Replace methods have been added in this version to give you greater control over Action Controls instructions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security and Performance Improvements
&lt;/h2&gt;

&lt;p&gt;This release includes numerous security and performance improvements. WebForms responses have been optimized, and issues related to events and Action Controls have been resolved. Additionally, the ability to display animations during initial page load has been added to the settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Growing Technology
&lt;/h2&gt;

&lt;p&gt;WebForms Core is a living and dynamic technology. The Elanat team is constantly improving and adding new features to this powerful technology. For this reason, it is always recommended to use the latest versions of this technology.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Version 2.1 is coming soon. Stay tuned!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>news</category>
      <category>backend</category>
      <category>opensource</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>Using the Segment Feature</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Fri, 27 Feb 2026 21:28:20 +0000</pubDate>
      <link>https://dev.to/elanatframework/using-the-segment-feature-5bp5</link>
      <guid>https://dev.to/elanatframework/using-the-segment-feature-5bp5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Segment&lt;/strong&gt; is an attribute that can be applied to ASPX pages. When this feature is enabled, all path parts that appear after the aspx file path are treated as segments and routed to the same executing page. Segment is one of the innovative ideas of the &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt; team. By enabling Segment, you gain full control over URL paths.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enabling Segment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Razor Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;@page
&lt;span class="gi"&gt;+@segment
&lt;/span&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Standard ASPX Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%@&lt;/span&gt; &lt;span class="na"&gt;Page&lt;/span&gt; &lt;span class="na"&gt;Segment=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How Segment Works
&lt;/h2&gt;

&lt;p&gt;If you enable Segment on the following path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about.aspx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any additional path parts after this address will be considered segments, and the executable file &lt;code&gt;/page/about.aspx&lt;/code&gt; will still be executed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about.aspx/segment1/segment2/.../segmentN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Segment is enabled on a file such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about/Default.aspx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can still access it using both of the following formats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about/Default.aspx/segment1/segment2/.../segmentN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about/segment1/segment2/.../segmentN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Accessing Segment Values
&lt;/h2&gt;

&lt;p&gt;You can access Segment values in all three layers: &lt;strong&gt;View, Controller, and Model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Segments are zero-based indexed.&lt;/p&gt;

&lt;p&gt;Given the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about/segment1/segment2/segment3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Segment.GetValue(0)&lt;/code&gt; returns &lt;code&gt;"segment1"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Segment.GetValue(1)&lt;/code&gt; returns &lt;code&gt;"segment2"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Segment.GetValue(2)&lt;/code&gt; returns &lt;code&gt;"segment3"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Segment.GetValue(n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns the segment at index &lt;code&gt;n&lt;/code&gt; (starting from 0).&lt;/p&gt;




&lt;h3&gt;
  
  
  Example in View (Razor)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;b&amp;gt;segment 1 is: @Segment.GetValue(0)&amp;lt;/b&amp;gt;
&amp;lt;b&amp;gt;segment 2 is: @Segment.GetValue(1)&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example in View (Standard ASPX)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;b&amp;gt;segment 1 is: &amp;lt;%= Segment.GetValue(0) %&amp;gt;&amp;lt;/b&amp;gt;
&amp;lt;b&amp;gt;segment 2 is: &amp;lt;%= Segment.GetValue(1) %&amp;gt;&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example in Controller
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;using CodeBehind;
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;namespace YourProjectName
&lt;/span&gt;{
    public partial class DefaultController : CodeBehindController
    {
        public void PageLoad(HttpContext context)
        {
&lt;span class="gi"&gt;+           Write(Segment.GetValue(0));
+           Write(Segment.GetValue(1));
&lt;/span&gt;        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By activating Segment, you no longer need to use query strings to pass parameters through the URL.&lt;/p&gt;




&lt;h2&gt;
  
  
  Important Behavior
&lt;/h2&gt;

&lt;p&gt;If you enable Segment on a specific path, ASPX view files located in its subdirectories will not be executed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;If Segment is enabled on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about/Default.aspx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the following path will no longer be accessible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/about/license/Default.aspx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Checking Segment Existence
&lt;/h2&gt;

&lt;p&gt;You can use the &lt;code&gt;Exist&lt;/code&gt; method to check whether a segment value exists before accessing it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@if (!Segment.Exist(0))
{
    &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;Value does not exist&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Segment in Default MVC Configuration
&lt;/h2&gt;

&lt;p&gt;In the default MVC configuration, the Segment feature is enabled automatically in controller routing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;CodeBehind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;user&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeBehindController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;   
        &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Segment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// path: /user/{id}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Rewrite ASPX Path as Directory
&lt;/h2&gt;

&lt;p&gt;One of the interesting ideas introduced by the Elanat team in the CodeBehind framework is the ability to rewrite an aspx file path as a directory name.&lt;/p&gt;

&lt;p&gt;When this option is enabled, routes leading to an aspx file without the &lt;code&gt;.aspx&lt;/code&gt; extension will be treated as directory paths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[CodeBehind options]&lt;/span&gt;&lt;span class="c"&gt;; do not change order
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="py"&gt;rewrite_aspx_file_to_directory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="err"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can safely enable this option because this rewrite does not introduce any additional processing load.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/contact.aspx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/contact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And also:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/page/contact/segment1/segment2/.../segmentN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;CodeBehind on GitHub:&lt;br&gt;
&lt;a href="https://github.com/elanatframework/Code_behind" rel="noopener noreferrer"&gt;https://github.com/elanatframework/Code_behind&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeBehind in NuGet:&lt;br&gt;
&lt;a href="https://www.nuget.org/packages/CodeBehind/" rel="noopener noreferrer"&gt;https://www.nuget.org/packages/CodeBehind/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeBehind page:&lt;br&gt;
&lt;a href="https://elanat.net/page_content/code_behind" rel="noopener noreferrer"&gt;https://elanat.net/page_content/code_behind&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>dotnet</category>
      <category>beginners</category>
      <category>backend</category>
    </item>
    <item>
      <title>🎬 Video - Using WebForms Core in ASP.NET MVC</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Fri, 27 Feb 2026 12:47:45 +0000</pubDate>
      <link>https://dev.to/elanatframework/video-using-webforms-core-in-aspnet-mvc-2kio</link>
      <guid>https://dev.to/elanatframework/video-using-webforms-core-in-aspnet-mvc-2kio</guid>
      <description>&lt;p&gt;In this video, we will teach you how to configure and use Elanat's WebForms Core technology in ASP.NET MVC.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/T0bTzUmX7BU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;




&lt;h2&gt;
  
  
  Is Blazor a Replacement for WebForms?
&lt;/h2&gt;

&lt;p&gt;Microsoft officially presents it as such, but the technical reality is more nuanced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Blazor = Component-Based Framework&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebForms = Event-Driven Page Model&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These two are built on fundamentally different architectural philosophies.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Blazor is not a technical replacement for WebForms; it is a strategic replacement.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Blazor is designed around a component-based architecture, whereas WebForms was built on a page-centric, event-driven model. Therefore, they cannot be considered equivalent.&lt;/p&gt;




&lt;h2&gt;
  
  
  The WebForms Core Perspective on Modern Architecture
&lt;/h2&gt;

&lt;p&gt;WebForms Core does not “destroy” the separation between front-end and back-end;&lt;br&gt;
it &lt;strong&gt;abstracts&lt;/strong&gt; it.&lt;/p&gt;

&lt;p&gt;Instead of forcing developers to build and maintain two separate projects using two different languages, this architecture turns the front-end into an execution layer that is controlled entirely from the server-side language.&lt;/p&gt;

&lt;p&gt;In this approach, user interactions remain modern, dynamic, and refresh-free, while the complexity of managing front-end code is removed or hidden from the developer.&lt;/p&gt;




&lt;h2&gt;
  
  
  From AJAX to WebForms Core
&lt;/h2&gt;

&lt;p&gt;Technologies like AJAX in 2005 created a major shift in web development by enabling data exchange without requiring a full page refresh.&lt;/p&gt;

&lt;p&gt;WebForms Core can be seen as the most evolved continuation of that path — a transition from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Interaction without page refresh”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Interaction without direct front-end coding.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not merely a tooling change;&lt;br&gt;
it represents a shift in development philosophy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;Get WFC Package from NuGet:&lt;br&gt;
&lt;a href="https://www.nuget.org/packages/WFC" rel="noopener noreferrer"&gt;https://www.nuget.org/packages/WFC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get ResponseWrite Package from NuGet:&lt;br&gt;
&lt;a href="https://www.nuget.org/packages/ResponseWrite" rel="noopener noreferrer"&gt;https://www.nuget.org/packages/ResponseWrite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebFormsJS on GitHub:&lt;br&gt;
&lt;a href="https://github.com/elanatframework/Web_forms" rel="noopener noreferrer"&gt;https://github.com/elanatframework/Web_forms&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebFormsJS page:&lt;br&gt;
&lt;a href="https://elanat.net/page_content/web_forms_js" rel="noopener noreferrer"&gt;https://elanat.net/page_content/web_forms_js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebForms Classes on GitHub:&lt;br&gt;
&lt;a href="https://github.com/elanatframework/Web_forms_classes" rel="noopener noreferrer"&gt;https://github.com/elanatframework/Web_forms_classes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core Organizations on GitHub:&lt;br&gt;
&lt;a href="https://github.com/webforms-core" rel="noopener noreferrer"&gt;https://github.com/webforms-core&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WebForms Core page:&lt;br&gt;
&lt;a href="https://elanat.net/page_content/web_forms_core" rel="noopener noreferrer"&gt;https://elanat.net/page_content/web_forms_core&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>tutorial</category>
      <category>fullstack</category>
      <category>webformscore</category>
    </item>
    <item>
      <title>ViewData in CodeBehind: Data Transfer Across MVC Components</title>
      <dc:creator>Elanat Framework</dc:creator>
      <pubDate>Fri, 27 Feb 2026 09:33:28 +0000</pubDate>
      <link>https://dev.to/elanatframework/viewdata-in-codebehind-data-transfer-across-mvc-components-1j3l</link>
      <guid>https://dev.to/elanatframework/viewdata-in-codebehind-data-transfer-across-mvc-components-1j3l</guid>
      <description>&lt;p&gt;The &lt;strong&gt;ViewData&lt;/strong&gt; feature in the CodeBehind framework, developed by &lt;a href="https://elanat.net" rel="noopener noreferrer"&gt;Elanat&lt;/a&gt;, is a simple and practical mechanism for transferring data between different components of the MVC architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is ViewData?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ViewData&lt;/code&gt; is a data list of type &lt;strong&gt;NameValue (Key-Value)&lt;/strong&gt;.&lt;br&gt;
This structure allows you to store data with a specific key and retrieve it in other parts of the same request.&lt;/p&gt;

&lt;p&gt;ViewData is used to transfer data between MVC components and supports &lt;strong&gt;both reading and writing&lt;/strong&gt; in the following sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Controller&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;View&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Layout&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ViewData Lifetime
&lt;/h2&gt;

&lt;p&gt;An important point to consider is that the data stored in ViewData is &lt;strong&gt;valid only during the current HTTP request&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This means that once the request is completed and the response is sent to the client, the ViewData values are cleared and will not be available in subsequent requests.&lt;/p&gt;


&lt;h2&gt;
  
  
  Comparison with ASP.NET
&lt;/h2&gt;

&lt;p&gt;The overall behavior of ViewData in CodeBehind is very similar to ViewData in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET MVC&lt;/li&gt;
&lt;li&gt;ASP.NET Razor Pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have previously worked with these technologies, using ViewData in CodeBehind will feel familiar and intuitive.&lt;/p&gt;


&lt;h2&gt;
  
  
  Writing Priority in ViewData
&lt;/h2&gt;

&lt;p&gt;The writing priority order in ViewData is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Controller&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;View&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This reflects the execution flow of the MVC pattern.&lt;/p&gt;

&lt;p&gt;If a new ViewData value is created inside the View, it cannot be read in the Controller, because the Controller executes before the View.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example: Using ViewData in a View
&lt;/h2&gt;

&lt;p&gt;In the following example, the &lt;code&gt;title&lt;/code&gt; value is set inside the View:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt;
&lt;span class="n"&gt;@controller&lt;/span&gt; &lt;span class="n"&gt;CacheThemeController&lt;/span&gt;
&lt;span class="n"&gt;@layout&lt;/span&gt; &lt;span class="s"&gt;"/layout.aspx"&lt;/span&gt;
&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;ViewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Cache Theme"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the value &lt;code&gt;"Cache Theme"&lt;/code&gt; is stored with the key &lt;code&gt;"title"&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Accessing ViewData in a Layout
&lt;/h2&gt;

&lt;p&gt;The stored value can be retrieved inside the Layout file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt;
&lt;span class="n"&gt;@islayout&lt;/span&gt;
&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;WelcomeText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Welcome to the CodeBehind Framework!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="n"&gt;DOCTYPE&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;CodeBehind&lt;/span&gt; &lt;span class="n"&gt;Framework&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;@ViewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;title&lt;/code&gt; value defined in the View is accessed in the Layout and displayed inside the &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using ViewData in a Controller
&lt;/h2&gt;

&lt;p&gt;You can also assign values inside a Controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PageLoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;   
    &lt;span class="n"&gt;ViewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Adriano"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the value &lt;code&gt;"Adriano"&lt;/code&gt; is stored in ViewData and becomes accessible in the View.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reading ViewData in a View
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt;
&lt;span class="n"&gt;@controller&lt;/span&gt; &lt;span class="n"&gt;ChangeListController&lt;/span&gt;

&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;@ViewData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the value associated with the specified key is retrieved from ViewData and rendered in the View.&lt;/p&gt;




&lt;h2&gt;
  
  
  Advantages of ViewData
&lt;/h2&gt;

&lt;p&gt;Using ViewData in CodeBehind offers several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple Key-Value structure&lt;/strong&gt; for lightweight data transfer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No need to create additional models&lt;/strong&gt; for small or temporary data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accessible across Controller, Model, View, and Layout&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request-scoped lifetime&lt;/strong&gt;, ensuring clean and predictable data handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight and fast&lt;/strong&gt;, with minimal overhead&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Familiar pattern&lt;/strong&gt; for developers coming from ASP.NET MVC or Razor Pages&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;ViewData in CodeBehind is a lightweight, flexible, and efficient mechanism for transferring data between MVC components within a single request.&lt;/p&gt;

&lt;p&gt;It is especially suitable for passing small pieces of data such as page titles, UI settings, temporary messages, or configuration values—without introducing unnecessary complexity into your application architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;p&gt;CodeBehind on GitHub:&lt;br&gt;
&lt;a href="https://github.com/elanatframework/Code_behind" rel="noopener noreferrer"&gt;https://github.com/elanatframework/Code_behind&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeBehind in NuGet:&lt;br&gt;
&lt;a href="https://www.nuget.org/packages/CodeBehind/" rel="noopener noreferrer"&gt;https://www.nuget.org/packages/CodeBehind/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeBehind page:&lt;br&gt;
&lt;a href="https://elanat.net/page_content/code_behind" rel="noopener noreferrer"&gt;https://elanat.net/page_content/code_behind&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>dotnet</category>
      <category>beginners</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
