{"id":235,"date":"2025-09-01T12:50:25","date_gmt":"2025-09-01T16:50:25","guid":{"rendered":"http:\/\/wordpress.home.internal\/?p=235"},"modified":"2025-09-01T20:34:31","modified_gmt":"2025-09-01T20:34:31","slug":"using-php-with-blazor","status":"publish","type":"post","link":"https:\/\/lcigaming.ca\/articles\/using-php-with-blazor\/","title":{"rendered":"Using PHP with Blazor"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">My previous posts focused on running Blazor apps in a Linux environment where you had administrative rights, including the ability to update the Apache configuration and to use <em>systemctl <\/em>to run Blazor server components. Running Blazor apps in a shared host environment is somewhat more challenging, as you do not have this ability to directly host your server. Many shared hosting environments, however, do support <a href=\"https:\/\/en.wikipedia.org\/wiki\/PHP\">PHP<\/a> for server-side scripting. This post will show how Blazor apps can work with PHP on the server.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Environment<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">My server environment has not changed since my previous posts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ubuntu 22.04.1 (LTS)<\/li>\n\n\n\n<li>Apache 2.4.52 (Ubuntu)<\/li>\n\n\n\n<li>PHP 8.1.2-1ubuntu2.22<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The version of dotnet installed is not relevant as we will not be using it for this exercise.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Source Code<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The source code for this post is available on <a href=\"https:\/\/github.com\/BarryALay\/blog0901-source\" title=\"\">GitHub<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Connected App<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Blazor Standalone WebAssembly apps do not need a dotnet server component to work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a Blazor WebAssembly Standalone app called PHPTest.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Authentication Type &#8211; none,<\/li>\n\n\n\n<li>Include sample pages.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1014\" height=\"673\" src=\"https:\/\/lcigaming.ca\/articles\/wp-content\/uploads\/2025\/07\/BlazorWebAssemblyStandaloneAppCreate.png\" alt=\"\" class=\"wp-image-63\" srcset=\"https:\/\/lcigaming.ca\/articles\/wp-content\/uploads\/2025\/07\/BlazorWebAssemblyStandaloneAppCreate.png 1014w, https:\/\/lcigaming.ca\/articles\/wp-content\/uploads\/2025\/07\/BlazorWebAssemblyStandaloneAppCreate-300x199.png 300w, https:\/\/lcigaming.ca\/articles\/wp-content\/uploads\/2025\/07\/BlazorWebAssemblyStandaloneAppCreate-768x510.png 768w, https:\/\/lcigaming.ca\/articles\/wp-content\/uploads\/2025\/07\/BlazorWebAssemblyStandaloneAppCreate-360x240.png 360w\" sizes=\"auto, (max-width: 1014px) 100vw, 1014px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Apply the same base URL fix as in previous posts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Remove the <em>base <\/em>element in <em>wwwroot\\index.html<\/em>.<\/li>\n\n\n\n<li>Add <code>@page \"\/home\"<\/code> to <em>Pages\\Home.razor<\/em>.<\/li>\n\n\n\n<li>Modify the first <em>NavLink <\/em>element in <em>Layout\\NavMenu.razor<\/em> to use <code>href=\"home\"<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy to the Linux server by copying the contents of <em>&#8230;\\publish\\wwwroot<\/em> to the application root folder on the server.  If you have set up a server such as I have for my previous posts, this could be to <em>\/var\/www\/html\/apps\/PHPTest<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Weather Sample Page<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The sample page <em>Pages\\Weather.razor<\/em> demonstrates the display of tabular data.  The file <em>wwwroot\\sample-data\\weather.json<\/em> is processed to create an array of objects which are rendered in a simple loop.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>weather.json<\/em> file is actually loaded from the server, using the <em>GetFromJsonAsync <\/em>function:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-highlight-color:rgba(16, 41, 67, 0.2);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">Razor<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@page \"\/weather\"\n@inject HttpClient Http\n\n&lt;PageTitle>Weather&lt;\/PageTitle>\n\n&lt;h1>Weather&lt;\/h1>\n\n&lt;p>This component demonstrates fetching data from the server.&lt;\/p>\n\n...\n\n@code {\n    private WeatherForecast[]? forecasts;\n\n    protected override async Task OnInitializedAsync()\n    {\n        forecasts = await Http.GetFromJsonAsync&lt;WeatherForecast[]>(\"sample-data\/weather.json\");\n    }\n\n    public class WeatherForecast\n    {\n        public DateOnly Date { get; set; }\n\n        public int TemperatureC { get; set; }\n\n        public string? Summary { get; set; }\n\n        public int TemperatureF => 32 + (int)(TemperatureC \/ 0.5556);\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">@page<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;\/weather&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@inject<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Http<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;Weather&lt;\/<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;Weather&lt;\/<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\">&gt;This component demonstrates fetching data from the server.&lt;\/<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">...<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@code<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]? <\/span><span style=\"color: #6F42C1\">forecasts<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">protected<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">OnInitializedAsync<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">        forecasts <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> Http.<\/span><span style=\"color: #6F42C1\">GetFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]&gt;(<\/span><span style=\"color: #032F62\">&quot;sample-data\/weather.json&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DateOnly<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Date<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TemperatureC<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #6F42C1\">Summary<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TemperatureF<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">32<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> (<\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\">)(TemperatureC <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">0.5556<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The action can be seen in the Apache log:<\/p>\n\n\n\n<pre class=\"wp-block-code has-24292-e-color has-text-color has-875-rem-font-size\"><code>... \"GET \/PHPTest\/sample-data\/weather.json HTTP\/1.1\" 200 501 ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This may be contrasted with the operation of <em>Components\\Pages\\Weather.razor<\/em> from the Blazor Web App template, which doesn&#8217;t fetch data from the server at all &#8211; it generates random data locally in the client and uses a timed delay to make it appear as if it is fetching data from the server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We could create a PHP page <em>wwwroot\\sample-data\\weather.php<\/em> to return the same results for the standalone app:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">PHP<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;?php\n\n\/\/ data to return\n$data = [\n\t&#91;\n        \"date\" => \"2022-01-06\",\n        \"temperatureC\" => 1,\n        \"summary\" => \"Freezing\"\n\t&#93;,\n\t&#91;\n        \"date\" => \"2022-01-07\",\n        \"temperatureC\" => 14,\n        \"summary\" => \"Bracing\"\n\t&#93;,\n\t&#91;\n        \"date\" => \"2022-01-08\",\n        \"temperatureC\" => -13,\n        \"summary\" => \"Freezing\"\n\t&#93;,\n\t&#91;\n        \"date\" => \"2022-01-09\",\n        \"temperatureC\" => -16,\n        \"summary\" => \"Balmy\"\n\t&#93;,\n\t&#91;\n        \"date\" => \"2022-01-10\",\n        \"temperatureC\" => -2,\n        \"summary\" => \"Chilly\"\n\t&#93;\n];\n\n\/\/ set the content type\nheader(\"Content-Type: application\/json\");\n\n\/\/ return as JSON\necho json_encode($data);\n\n?><\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">&lt;?<\/span><span style=\"color: #005CC5\">php<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/\/ data to return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">$data <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-06&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Freezing&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-07&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">14<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Bracing&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-08&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">13<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Freezing&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-09&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">16<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Balmy&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-10&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Chilly&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/\/ set the content type<\/span><\/span>\n<span class=\"line\"><span style=\"color: #005CC5\">header<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;Content-Type: application\/json&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/\/ return as JSON<\/span><\/span>\n<span class=\"line\"><span style=\"color: #005CC5\">echo<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">json_encode<\/span><span style=\"color: #24292E\">($data);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">?&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Modifying <em>Pages\\Weather.razor<\/em> to fetch this file accomplishes the same result when the app is published to Linux:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-highlight-color:rgba(16, 41, 67, 0.2);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">Razor<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@page \"\/weather\"\n@inject HttpClient Http\n\n&lt;PageTitle>Weather&lt;\/PageTitle>\n\n&lt;h1>Weather&lt;\/h1>\n\n&lt;p>This component demonstrates fetching data from the server.&lt;\/p>\n\n...\n\n@code {\n    private WeatherForecast[]? forecasts;\n\n    protected override async Task OnInitializedAsync()\n    {\n        forecasts = await Http.GetFromJsonAsync&lt;WeatherForecast[]>(\"sample-data\/weather.php\");\n    }\n\n    public class WeatherForecast\n    {\n        public DateOnly Date { get; set; }\n\n        public int TemperatureC { get; set; }\n\n        public string? Summary { get; set; }\n\n        public int TemperatureF => 32 + (int)(TemperatureC \/ 0.5556);\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">@page<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;\/weather&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@inject<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Http<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;Weather&lt;\/<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;Weather&lt;\/<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\">&gt;This component demonstrates fetching data from the server.&lt;\/<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">...<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@code<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]? <\/span><span style=\"color: #6F42C1\">forecasts<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">protected<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">OnInitializedAsync<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">        forecasts <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> Http.<\/span><span style=\"color: #6F42C1\">GetFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]&gt;(<\/span><span style=\"color: #032F62\">&quot;sample-data\/weather.php&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DateOnly<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Date<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TemperatureC<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #6F42C1\">Summary<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TemperatureF<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">32<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> (<\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\">)(TemperatureC <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">0.5556<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now the HTTP GET request executes the PHP code in weather.php to generate the JSON response. It could even access another service on the server to obtain live sensor data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unfortunately, this does not work well in the development environment, as Visual Studio does not have native support for PHP.  You could install a VS plugin such as <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=DEVSENSE.PHPToolsforVisualStudio2022\">DevSense<\/a> to add such support.  We will show an alternative approach shortly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Counter Sample Page<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The sample page <em>Pages\\Counter.razor<\/em> is quite simple. It merely updates a local counter when a button is pressed. It does not even maintain the state of the counter across pages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This last weakness is easily corrected through the use of a non-transient service within the app.  It might be more interesting, however, to solve this using PHP on the server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a server page <em>wwwroot\\counter.php<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">PHP<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;?php\n\nsession_start();\n\n$_SESSION&#91;\"action\"&#93; = \"none\";\n\n\/\/ initialize counter if necessary\nif (!isset($_SESSION&#91;\"count\"&#93;)) {\n\t$_SESSION&#91;\"count\"&#93; = 0;\n\t$_SESSION&#91;\"action\"&#93; = \"initialize\";\n}\n\nif ($_GET&#91;\"action\"&#93; == \"increment\") {\n\t$_SESSION&#91;\"count\"&#93; = $_SESSION&#91;\"count\"&#93; + 1;\n\t$_SESSION&#91;\"action\"&#93; = \"increment\";\n}\n\nif ($_GET&#91;\"action\"&#93; == \"decrement\") {\n\t$_SESSION&#91;\"count\"&#93; = $_SESSION&#91;\"count\"&#93; - 1;\n\t$_SESSION&#91;\"action\"&#93; = \"decrement\";\n}\n\n\/\/ package the state\n$result = [\n\t\"count\" => $_SESSION&#91;\"count\"&#93;,\n\t\"action\" => $_SESSION&#91;\"action\"&#93;\n];\n\n\/\/ set the content type\nheader(\"Content-Type: application\/json\");\n\n\/\/ return as JSON\necho json_encode($result);\n\n?><\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">&lt;?<\/span><span style=\"color: #005CC5\">php<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #005CC5\">session_start<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;none&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/\/ initialize counter if necessary<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #005CC5\">isset<\/span><span style=\"color: #24292E\">($_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93;)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">0<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;initialize&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> ($_GET&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;increment&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;increment&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> ($_GET&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;decrement&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;decrement&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/\/ package the state<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">$result <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/\/ set the content type<\/span><\/span>\n<span class=\"line\"><span style=\"color: #005CC5\">header<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;Content-Type: application\/json&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A737D\">\/\/ return as JSON<\/span><\/span>\n<span class=\"line\"><span style=\"color: #005CC5\">echo<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">json_encode<\/span><span style=\"color: #24292E\">($result);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">?&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modify <em>Pages\\Counter.razor<\/em> to use this page:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">Razor<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@page \"\/counter\"\n@inject HttpClient Http\n\n&lt;PageTitle>Counter&lt;\/PageTitle>\n\n&lt;h1>Counter&lt;\/h1>\n\n&lt;p role=\"status\">Current count: @currentCount, last action: @lastAction&lt;\/p>\n\n&lt;button class=\"btn btn-primary\" @onclick=\"IncrementCount\">Click me to increment&lt;\/button>\n&lt;button class=\"btn btn-primary\" @onclick=\"DecrementCount\">Click me to decrement&lt;\/button>\n\n@code {\n    private CounterData? data;\n    private int currentCount;\n    private string lastAction = \"unknown\";\n\n    protected override async Task OnInitializedAsync()\n    {\n        data = await Http.GetFromJsonAsync&lt;CounterData>(\"counter.php\");\n        currentCount = data?.Count ?? -1;\n        lastAction = data?.Action ?? \"unknown\";\n    }\n\n    private async void IncrementCount()\n    {\n        var response = await Http.PostAsync(\"counter.php?action=increment\", null);\n        data = await response.Content.ReadFromJsonAsync&lt;CounterData>();\n        currentCount = data?.Count ?? -1;\n        lastAction = data?.Action ?? \"failed to increment\";\n        await InvokeAsync(StateHasChanged);\n    }\n\n    private async void DecrementCount()\n    {\n        var response = await Http.PostAsync(\"counter.php?action=decrement\", null);\n        data = await response.Content.ReadFromJsonAsync&lt;CounterData>();\n        currentCount = data?.Count ?? -1;\n        lastAction = data?.Action ?? \"failed to decrement\";\n        await InvokeAsync(StateHasChanged);\n    }\n\n    public class CounterData\n    {\n        public int Count { get; set; }\n        public string? Action { get; set; }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">@page<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;\/counter&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@inject<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Http<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;Counter&lt;\/<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;Counter&lt;\/<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">role<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;status&quot;<\/span><span style=\"color: #24292E\">&gt;Current count: <\/span><span style=\"color: #D73A49\">@<\/span><span style=\"color: #24292E\">currentCount, last action: <\/span><span style=\"color: #D73A49\">@<\/span><span style=\"color: #24292E\">lastAction&lt;\/<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">class<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;btn btn-primary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">@onclick<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;IncrementCount&quot;<\/span><span style=\"color: #24292E\">&gt;Click me to increment&lt;\/<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">class<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;btn btn-primary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">@onclick<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;DecrementCount&quot;<\/span><span style=\"color: #24292E\">&gt;Click me to decrement&lt;\/<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@code<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #6F42C1\">data<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">currentCount<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">lastAction<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;unknown&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">protected<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">OnInitializedAsync<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        data <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> Http.<\/span><span style=\"color: #6F42C1\">GetFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">&gt;(<\/span><span style=\"color: #032F62\">&quot;counter.php&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        currentCount <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Count <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        lastAction <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Action <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;unknown&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">void<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">IncrementCount<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">response<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> Http.<\/span><span style=\"color: #6F42C1\">PostAsync<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;counter.php?action=increment&quot;<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        data <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> response.Content.<\/span><span style=\"color: #6F42C1\">ReadFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        currentCount <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Count <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        lastAction <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Action <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;failed to increment&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">InvokeAsync<\/span><span style=\"color: #24292E\">(StateHasChanged);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">void<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DecrementCount<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">response<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> Http.<\/span><span style=\"color: #6F42C1\">PostAsync<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;counter.php?action=decrement&quot;<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        data <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> response.Content.<\/span><span style=\"color: #6F42C1\">ReadFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        currentCount <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Count <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        lastAction <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Action <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;failed to decrement&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">InvokeAsync<\/span><span style=\"color: #24292E\">(StateHasChanged);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">CounterData<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Count<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #6F42C1\">Action<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Deploying this to Linux will provide an improved Counter page.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This example demonstrates how to use the query string to indicate to the server which action is requested.   It also saves the current count state across requests, so that when switching pages within the app the count is preserved. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We could build a more complex application following this approach, with each requirement for server-based resources being satisfied by a separate PHP page and appropriate linkage. These pages could even have shared state through PHP session data. This has the advantage of simplicity but lacks cohesion &#8211; shared PHP state could lead to inadvertent overlaps and the core communication logic is replicated widely within the app.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Centralized Routing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A consolidated request service centralizes the details of the server calls so that API changes can be made in one place. It also allows for a different mechanism to be used in the development environment where PHP is not supported. We can use Blazor service injection to provide this flexibility.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create the folder <em>Services <\/em>at the project root, and add it to <em>_imports.razor<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-highlight-color:rgba(16, 41, 67, 0.2);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">Razor<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@using System.Net.Http\n@using System.Net.Http.Json\n@using Microsoft.AspNetCore.Components.Forms\n@using Microsoft.AspNetCore.Components.Routing\n@using Microsoft.AspNetCore.Components.Web\n@using Microsoft.AspNetCore.Components.Web.Virtualization\n@using Microsoft.AspNetCore.Components.WebAssembly.Http\n@using Microsoft.JSInterop\n@using PHPTest\n@using PHPTest.Layout\n@using PHPTest.Services<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">System<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Net<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Http<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">System<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Net<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Http<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Json<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">AspNetCore<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Components<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Forms<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">AspNetCore<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Components<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Routing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">AspNetCore<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Components<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Web<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">AspNetCore<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Components<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Web<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Virtualization<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">AspNetCore<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Components<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">WebAssembly<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Http<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">JSInterop<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Layout<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D73A49\">@using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Services<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Create <em>Services\\ServerRequestService.cs<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">C#<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>namespace PHPTest.Services\n{\n    public class WeatherForecast\n    {\n        public DateOnly Date { get; set; }\n\n        public int TemperatureC { get; set; }\n\n        public string? Summary { get; set; }\n\n        public int TemperatureF => 32 + (int)(TemperatureC \/ 0.5556);\n    }\n\n    public class CounterData\n    {\n        public int Count { get; set; }\n        public string? Action { get; set; }\n    }\n\n    public abstract class ServerRequestService\n    {\n        public abstract Task&lt;WeatherForecast[]?> GetWeatherForecasts();\n        public abstract Task&lt;CounterData?> GetCounterData();\n        public abstract Task&lt;CounterData?> IncrementCounter();\n        public abstract Task&lt;CounterData?> DecrementCounter();\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">namespace<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Services<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DateOnly<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Date<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TemperatureC<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #6F42C1\">Summary<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">TemperatureF<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">32<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> (<\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\">)(TemperatureC <\/span><span style=\"color: #D73A49\">\/<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">0.5556<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">CounterData<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Count<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #6F42C1\">Action<\/span><span style=\"color: #24292E\"> { <\/span><span style=\"color: #D73A49\">get<\/span><span style=\"color: #24292E\">; <\/span><span style=\"color: #D73A49\">set<\/span><span style=\"color: #24292E\">; }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">abstract<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ServerRequestService<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">abstract<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]?&gt; <\/span><span style=\"color: #6F42C1\">GetWeatherForecasts<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">abstract<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">GetCounterData<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">abstract<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">IncrementCounter<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">abstract<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">DecrementCounter<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Create concrete implementation <em>Services\\PHPRequestService.cs<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">C#<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>using System.Net.Http.Json;\n\nnamespace PHPTest.Services\n{\n    public class PHPRequestService(HttpClient httpClient) : ServerRequestService\n    {\n        readonly HttpClient client = httpClient;\n\n        public async override Task&lt;WeatherForecast[]?> GetWeatherForecasts()\n        {\n            return await client.GetFromJsonAsync&lt;WeatherForecast[]>(\"boundary.php?group=weather\");\n        }\n\n        public async override Task&lt;CounterData?> GetCounterData()\n        {\n            return await client.GetFromJsonAsync&lt;CounterData>(\"boundary.php?group=counter\");\n        }\n\n        public async override Task&lt;CounterData?> IncrementCounter()\n        {\n            var response = await client.PostAsync(\"boundary.php?group=counter&amp;action=increment\", null);\n            return await response.Content.ReadFromJsonAsync&lt;CounterData>();\n        }\n\n        public async override Task&lt;CounterData?> DecrementCounter()\n        {\n            var response = await client.PostAsync(\"boundary.php?group=counter&amp;action=decrement\", null);\n            return await response.Content.ReadFromJsonAsync&lt;CounterData>();\n        }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">System<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Net<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Http<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Json<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">namespace<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Services<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPRequestService<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">httpClient<\/span><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ServerRequestService<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">readonly<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">client<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> httpClient;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]?&gt; <\/span><span style=\"color: #6F42C1\">GetWeatherForecasts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> client.<\/span><span style=\"color: #6F42C1\">GetFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]&gt;(<\/span><span style=\"color: #032F62\">&quot;boundary.php?group=weather&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">GetCounterData<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> client.<\/span><span style=\"color: #6F42C1\">GetFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">&gt;(<\/span><span style=\"color: #032F62\">&quot;boundary.php?group=counter&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">IncrementCounter<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">response<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> client.<\/span><span style=\"color: #6F42C1\">PostAsync<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;boundary.php?group=counter&amp;action=increment&quot;<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> response.Content.<\/span><span style=\"color: #6F42C1\">ReadFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">DecrementCounter<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">response<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> client.<\/span><span style=\"color: #6F42C1\">PostAsync<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;boundary.php?group=counter&amp;action=decrement&quot;<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #005CC5\">null<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> response.Content.<\/span><span style=\"color: #6F42C1\">ReadFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This version of the server request service will direct requests to a server-based PHP page.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create concrete implementation <em>Services\\DebugRequestService.cs<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">C#<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>using System.Net.Http.Json;\n\nnamespace PHPTest.Services\n{\n    public class DebugRequestService(HttpClient httpClient) : ServerRequestService\n    {\n        readonly HttpClient client = httpClient;\n\n        public override async Task&lt;WeatherForecast[]?> GetWeatherForecasts()\n        {\n            return await client.GetFromJsonAsync&lt;WeatherForecast[]>(\"sample-data\/weather.json\");\n        }\n\n        private int counter = 0;\n\n        public override Task&lt;CounterData?> GetCounterData()\n        {\n            CounterData data = new()\n            {\n                Count = counter,\n                Action = \"none\"\n            };\n            return Task.FromResult((CounterData?)data);\n        }\n\n        public override Task&lt;CounterData?> IncrementCounter()\n        {\n            CounterData data = new()\n            {\n                Count = ++counter,\n                Action = \"increment\"\n            };\n            return Task.FromResult((CounterData?)data);\n        }\n\n        public override Task&lt;CounterData?> DecrementCounter()\n        {\n            CounterData data = new()\n            {\n                Count = --counter,\n                Action = \"decrement\"\n            };\n            return Task.FromResult((CounterData?)data);\n        }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">System<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Net<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Http<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Json<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">namespace<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Services<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DebugRequestService<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">httpClient<\/span><span style=\"color: #24292E\">) : <\/span><span style=\"color: #6F42C1\">ServerRequestService<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">readonly<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">client<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> httpClient;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]?&gt; <\/span><span style=\"color: #6F42C1\">GetWeatherForecasts<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> client.<\/span><span style=\"color: #6F42C1\">GetFromJsonAsync<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]&gt;(<\/span><span style=\"color: #032F62\">&quot;sample-data\/weather.json&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">counter<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">0<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">GetCounterData<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">new<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Count <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> counter,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Action <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;none&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            };<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Task.<\/span><span style=\"color: #6F42C1\">FromResult<\/span><span style=\"color: #24292E\">((<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?)data);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">IncrementCounter<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">new<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Count <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">++<\/span><span style=\"color: #24292E\">counter,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Action <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;increment&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            };<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Task.<\/span><span style=\"color: #6F42C1\">FromResult<\/span><span style=\"color: #24292E\">((<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?)data);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?&gt; <\/span><span style=\"color: #6F42C1\">DecrementCounter<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">data<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">new<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Count <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">--<\/span><span style=\"color: #24292E\">counter,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                Action <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;decrement&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            };<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">return<\/span><span style=\"color: #24292E\"> Task.<\/span><span style=\"color: #6F42C1\">FromResult<\/span><span style=\"color: #24292E\">((<\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">?)data);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This version of the server request service will provide functionality similar to what the original app did.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Register the appropriate service in <em>Program.cs<\/em> based on the execution environment:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-highlight-color:rgba(16, 41, 67, 0.2);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">C#<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>using Microsoft.AspNetCore.Components.Web;\nusing Microsoft.AspNetCore.Components.WebAssembly.Hosting;\nusing PHPTest.Services;\n\nnamespace PHPTest\n{\n    public class Program\n    {\n        public static async Task Main(string[] args)\n        {\n            var builder = WebAssemblyHostBuilder.CreateDefault(args);\n            builder.RootComponents.Add&lt;App>(\"#app\");\n            builder.RootComponents.Add&lt;HeadOutlet>(\"head::after\");\n\n            builder.Services.AddScoped(sp => new HttpClient { \n                BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) \n                });\n\n            if (builder.HostEnvironment.IsDevelopment())\n            {\n                builder.Services.AddScoped&lt;ServerRequestService, DebugRequestService>();\n            }\n            else\n            {\n                builder.Services.AddScoped&lt;ServerRequestService, PHPRequestService>();\n            }\n\n            await builder.Build().RunAsync();\n        }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">AspNetCore<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Components<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Web<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Microsoft<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">AspNetCore<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Components<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">WebAssembly<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Hosting<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">using<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><span style=\"color: #24292E\">.<\/span><span style=\"color: #6F42C1\">Services<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">namespace<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">PHPTest<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">class<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Program<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">public<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">static<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Main<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\">[] <\/span><span style=\"color: #6F42C1\">args<\/span><span style=\"color: #24292E\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">var<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">builder<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> WebAssemblyHostBuilder.<\/span><span style=\"color: #6F42C1\">CreateDefault<\/span><span style=\"color: #24292E\">(args);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            builder.RootComponents.<\/span><span style=\"color: #6F42C1\">Add<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">App<\/span><span style=\"color: #24292E\">&gt;(<\/span><span style=\"color: #032F62\">&quot;#app&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            builder.RootComponents.<\/span><span style=\"color: #6F42C1\">Add<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">HeadOutlet<\/span><span style=\"color: #24292E\">&gt;(<\/span><span style=\"color: #032F62\">&quot;head::after&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            builder.Services.<\/span><span style=\"color: #6F42C1\">AddScoped<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #6F42C1\">sp<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">new<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                BaseAddress <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">new<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Uri<\/span><span style=\"color: #24292E\">(builder.HostEnvironment.BaseAddress) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">                });<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (builder.HostEnvironment.<\/span><span style=\"color: #6F42C1\">IsDevelopment<\/span><span style=\"color: #24292E\">())<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">            {<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">                builder.Services.<\/span><span style=\"color: #6F42C1\">AddScoped<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">ServerRequestService<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">DebugRequestService<\/span><span style=\"color: #24292E\">&gt;();<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">else<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">            {<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">                builder.Services.<\/span><span style=\"color: #6F42C1\">AddScoped<\/span><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #6F42C1\">ServerRequestService<\/span><span style=\"color: #24292E\">, <\/span><span style=\"color: #6F42C1\">PHPRequestService<\/span><span style=\"color: #24292E\">&gt;();<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #24292E\">            }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">            <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> builder.<\/span><span style=\"color: #6F42C1\">Build<\/span><span style=\"color: #24292E\">().<\/span><span style=\"color: #6F42C1\">RunAsync<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modify <em>Pages\\Weather.razor<\/em> to use the new service:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">Razor<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@page \"\/weather\"\n@inject HttpClient Http\n@inject ServerRequestService ServerRequest\n\n&lt;PageTitle>Weather&lt;\/PageTitle>\n\n...\n\n@code {\n    private WeatherForecast[]? forecasts;\n\n    protected override async Task OnInitializedAsync()\n    {\n        forecasts = await ServerRequest.GetWeatherForecasts();\n    }\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">@page<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;\/weather&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@inject<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Http<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@inject<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ServerRequestService<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ServerRequest<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;Weather&lt;\/<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">...<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@code<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">WeatherForecast<\/span><span style=\"color: #24292E\">[]? <\/span><span style=\"color: #6F42C1\">forecasts<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">protected<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">OnInitializedAsync<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        forecasts <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> ServerRequest.<\/span><span style=\"color: #6F42C1\">GetWeatherForecasts<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Modify <em>Pages\\Counter.razor<\/em> to use the new service:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">Razor<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>@page \"\/counter\"\n@inject HttpClient Http\n@inject ServerRequestService ServerRequest\n\n&lt;PageTitle>Counter&lt;\/PageTitle>\n\n&lt;h1>Counter&lt;\/h1>\n\n&lt;p role=\"status\">Current count: @currentCount, last action: @lastAction&lt;\/p>\n\n&lt;button class=\"btn btn-primary\" @onclick=\"IncrementCount\">Click me to increment&lt;\/button>\n&lt;button class=\"btn btn-primary\" @onclick=\"DecrementCount\">Click me to decrement&lt;\/button>\n\n@code {\n    private CounterData? data;\n    private int currentCount;\n    private string lastAction = \"unknown\";\n\n    protected override async Task OnInitializedAsync()\n    {\n        data = await ServerRequest.GetCounterData();\n        currentCount = data?.Count ?? -1;\n        lastAction = data?.Action ?? \"unknown\";\n    }\n\n    private async void IncrementCount()\n    {\n        data = await ServerRequest.IncrementCounter();\n        currentCount = data?.Count ?? -1;\n        lastAction = data?.Action ?? \"failed to increment\";\n        await InvokeAsync(StateHasChanged);\n    }\n\n    private async void DecrementCount()\n    {\n        data = await ServerRequest.DecrementCounter();\n        currentCount = data?.Count ?? -1;\n        lastAction = data?.Action ?? \"failed to decrement\";\n        await InvokeAsync(StateHasChanged);\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">@page<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;\/counter&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@inject<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">HttpClient<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Http<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@inject<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ServerRequestService<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">ServerRequest<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;Counter&lt;\/<\/span><span style=\"color: #B31D28; font-style: italic\">PageTitle<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;Counter&lt;\/<\/span><span style=\"color: #22863A\">h1<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">role<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;status&quot;<\/span><span style=\"color: #24292E\">&gt;Current count: <\/span><span style=\"color: #D73A49\">@<\/span><span style=\"color: #24292E\">currentCount, last action: <\/span><span style=\"color: #D73A49\">@<\/span><span style=\"color: #24292E\">lastAction&lt;\/<\/span><span style=\"color: #22863A\">p<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">class<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;btn btn-primary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">@onclick<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;IncrementCount&quot;<\/span><span style=\"color: #24292E\">&gt;Click me to increment&lt;\/<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">&lt;<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">class<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;btn btn-primary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">@onclick<\/span><span style=\"color: #24292E\">=<\/span><span style=\"color: #032F62\">&quot;DecrementCount&quot;<\/span><span style=\"color: #24292E\">&gt;Click me to decrement&lt;\/<\/span><span style=\"color: #22863A\">button<\/span><span style=\"color: #24292E\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">@code<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">CounterData<\/span><span style=\"color: #24292E\">? <\/span><span style=\"color: #6F42C1\">data<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">int<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">currentCount<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">string<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">lastAction<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;unknown&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">protected<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">override<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">Task<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">OnInitializedAsync<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        data <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> ServerRequest.<\/span><span style=\"color: #6F42C1\">GetCounterData<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        currentCount <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Count <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        lastAction <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Action <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;unknown&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">void<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">IncrementCount<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        data <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> ServerRequest.<\/span><span style=\"color: #6F42C1\">IncrementCounter<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        currentCount <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Count <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        lastAction <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Action <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;failed to increment&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">InvokeAsync<\/span><span style=\"color: #24292E\">(StateHasChanged);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    <\/span><span style=\"color: #D73A49\">private<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">async<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">void<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">DecrementCount<\/span><span style=\"color: #24292E\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        data <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> ServerRequest.<\/span><span style=\"color: #6F42C1\">DecrementCounter<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        currentCount <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Count <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        lastAction <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> data<\/span><span style=\"color: #D73A49\">?<\/span><span style=\"color: #24292E\">.Action <\/span><span style=\"color: #D73A49\">??<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;failed to decrement&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">        <\/span><span style=\"color: #D73A49\">await<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #6F42C1\">InvokeAsync<\/span><span style=\"color: #24292E\">(StateHasChanged);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A consolidated PHP page for satisfying requests has the advantage of putting the API logic in one place and can be developed in sync with the request service it is intended to respond to.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a combined service page <em>wwwroot\\boundary.php<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#f2f2f2;color:#2f363c\">PHP<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#24292e;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;?php\n\nsession_start();\n\nif ($_GET&#91;\"group\"&#93; == \"counter\") {\n\n\t$_SESSION&#91;\"action\"&#93; = \"none\";\n\n\tif (!isset($_SESSION&#91;\"count\"&#93;)) {\n\t\t$_SESSION&#91;\"count\"&#93; = 0;\n\t\t$_SESSION&#91;\"group\"&#93; = \"counter\";\n\t\t$_SESSION&#91;\"action\"&#93; = \"initialize\";\n\t}\n\n\tif ($_GET&#91;\"action\"&#93; == \"increment\") {\n\t\t$_SESSION&#91;\"count\"&#93; = $_SESSION&#91;\"count\"&#93; + 1;\n\t\t$_SESSION&#91;\"action\"&#93; = \"increment\";\n\t}\n\n\tif ($_GET&#91;\"action\"&#93; == \"decrement\") {\n\t\t$_SESSION&#91;\"count\"&#93; = $_SESSION&#91;\"count\"&#93; - 1;\n\t\t$_SESSION&#91;\"action\"&#93; = \"decrement\";\n\t}\n\n\t$result = [\n\t\t\"count\" => $_SESSION&#91;\"count\"&#93;,\n\t\t\"action\" => $_SESSION&#91;\"action\"&#93;\n\t];\n\n\theader(\"Content-Type: application\/json\");\n\n\techo json_encode($result);\n\n} elseif ($_GET&#91;\"group\"&#93; == \"weather\") {\n\t\n\t$result = [\n\t\t&#91;\n\t\t\t\"date\" => \"2022-01-06\",\n\t\t\t\"temperatureC\" => 1,\n\t\t\t\"summary\" => \"Freezing\"\n\t\t&#93;,\n\t\t&#91;\n\t\t\t\"date\" => \"2022-01-07\",\n\t\t\t\"temperatureC\" => 14,\n\t\t\t\"summary\" => \"Bracing\"\n\t\t&#93;,\n\t\t&#91;\n\t\t\t\"date\" => \"2022-01-08\",\n\t\t\t\"temperatureC\" => -13,\n\t\t\t\"summary\" => \"Freezing\"\n\t\t&#93;,\n\t\t&#91;\n\t\t\t\"date\" => \"2022-01-09\",\n\t\t\t\"temperatureC\" => -16,\n\t\t\t\"summary\" => \"Balmy\"\n\t\t&#93;,\n\t\t&#91;\n\t\t\t\"date\" => \"2022-01-10\",\n\t\t\t\"temperatureC\" => -2,\n\t\t\t\"summary\" => \"Chilly\"\n\t\t&#93;\n\t];\n\n\theader(\"Content-Type: application\/json\");\n\n\techo json_encode($result);\n\n} else {\n\thttp_response_code(400);\n}\n\n?><\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki github-light\" style=\"background-color: #fff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D73A49\">&lt;?<\/span><span style=\"color: #005CC5\">php<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #005CC5\">session_start<\/span><span style=\"color: #24292E\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> ($_GET&#91;<\/span><span style=\"color: #032F62\">&quot;group&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;counter&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;none&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> (<\/span><span style=\"color: #D73A49\">!<\/span><span style=\"color: #005CC5\">isset<\/span><span style=\"color: #24292E\">($_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93;)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">0<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;group&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;counter&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;initialize&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> ($_GET&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;increment&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">+<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;increment&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #D73A49\">if<\/span><span style=\"color: #24292E\"> ($_GET&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;decrement&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t$_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;decrement&quot;<\/span><span style=\"color: #24292E\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$result <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;count&quot;<\/span><span style=\"color: #24292E\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> $_SESSION&#91;<\/span><span style=\"color: #032F62\">&quot;action&quot;<\/span><span style=\"color: #24292E\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #005CC5\">header<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;Content-Type: application\/json&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #005CC5\">echo<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">json_encode<\/span><span style=\"color: #24292E\">($result);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} <\/span><span style=\"color: #D73A49\">elseif<\/span><span style=\"color: #24292E\"> ($_GET&#91;<\/span><span style=\"color: #032F62\">&quot;group&quot;<\/span><span style=\"color: #24292E\">&#93; <\/span><span style=\"color: #D73A49\">==<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;weather&quot;<\/span><span style=\"color: #24292E\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t$result <\/span><span style=\"color: #D73A49\">=<\/span><span style=\"color: #24292E\"> [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-06&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">1<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Freezing&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-07&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">14<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Bracing&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-08&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">13<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Freezing&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-09&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">16<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Balmy&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;date&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;2022-01-10&quot;<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;temperatureC&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">-<\/span><span style=\"color: #005CC5\">2<\/span><span style=\"color: #24292E\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t\t<\/span><span style=\"color: #032F62\">&quot;summary&quot;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #D73A49\">=&gt;<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #032F62\">&quot;Chilly&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t\t&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #005CC5\">header<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #032F62\">&quot;Content-Type: application\/json&quot;<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #005CC5\">echo<\/span><span style=\"color: #24292E\"> <\/span><span style=\"color: #005CC5\">json_encode<\/span><span style=\"color: #24292E\">($result);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">} <\/span><span style=\"color: #D73A49\">else<\/span><span style=\"color: #24292E\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">\t<\/span><span style=\"color: #005CC5\">http_response_code<\/span><span style=\"color: #24292E\">(<\/span><span style=\"color: #005CC5\">400<\/span><span style=\"color: #24292E\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #24292E\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D73A49\">?&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The app should now run in both the debugging environment and when deployed to the Linux server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>boundary.php<\/em> page above could be improved by using PHP classes to mirror the <em>WeatherForecast <\/em>and <em>CounterData <\/em>classes in the C# code.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The solution above shows how a Blazor standalone app can communicate with the server using PHP.  This approach has a number of weaknesses:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>There is no consideration for application security.<\/li>\n\n\n\n<li>PHP uses a similar programming language to C# but there are important differences.  <\/li>\n\n\n\n<li>Even if matching concepts such as classes are used in the PHP and C# components, there is no mechanism for detecting mismatches at design time.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you wish to pursue PHP for server-side support you may consider a more comprehensive package such as <a href=\"https:\/\/laravel.com\/\">Laravel <\/a>or <a href=\"https:\/\/symfony.com\/\">Symfony<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My next post will explore improving on some of the weaknesses noted by combining PHP with C# for server-side coding.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Supporting Blazor apps on a shared host requires some effort.  This post shows how to interact with PHP from a Blazor client app.<\/p>\n","protected":false},"author":2,"featured_media":180,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_themeisle_gutenberg_block_has_review":false,"footnotes":""},"categories":[10],"tags":[],"class_list":["post-235","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/posts\/235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/comments?post=235"}],"version-history":[{"count":3,"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/posts\/235\/revisions"}],"predecessor-version":[{"id":242,"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/posts\/235\/revisions\/242"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/media\/180"}],"wp:attachment":[{"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/media?parent=235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/categories?post=235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lcigaming.ca\/articles\/wp-json\/wp\/v2\/tags?post=235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}