WebExpress is a lightweight web server optimized for use in low-performance environments (e.g. Rasperry PI). By providing a powerful plugin system and a comprehensive API, web applications can be easily and quickly integrated into a .net language (e.g. C#). Some advantages of WebExpress are:
- It is easy to use.
- It offers a variety of features and tools that can help you build and manage your website.
- It is fast and efficient and can help you save time and money.
- It is flexible and can be customized to meet your specific requirements.
The WebExpress family includes the following projects:
- WebExpress - The web server for
WebExpressapplications and the documentation. - WebExpress.WebCore - The core for
WebExpressapplications. - WebExpress.WebUI - Common templates and controls for
WebExpressapplications. - WebExpress.WebIndex - Reverse index for
WebExpressapplications. - WebExpress.WebApp - Business application template for
WebExpressapplications.
WebExpress is part of the WebExpress family. The project provides a web server for WebExpress applications.
To get started with WebExpress, use the following links.
How to tutorial to demonstrate a simple WebExpress application. The application includes the creation of a home page that displays this tutorial and an info page with information about the application.
-
Install .NET 9.0. You can download and install .NET 9.0 from the official .NET website. Follow the instructions on the website to complete the installation.
-
Verify the installation. Open the command line or terminal and run the following command:
dotnet --version
This command outputs the installed .NET version. Make sure the outputted version matches the version you installed (in this case 9.0).
After fulfilling these prerequisites, you can proceed with the tutorial.
-
Open the command line or terminal.
- On Windows, you can open the command line by typing cmd into the search box of the Start menu and pressing Enter.
- On MacOS or Linux, you can open the terminal by typing terminal into the Spotlight search and pressing Enter.
-
Navigate to the desired directory.
-
Use the command cd
path/to/directoryto navigate to the desired directory. -
Create a new solution. Enter the following command and press Enter:
# create a new folder for your solution mkdir WebExpress.Tutorial.WebApp cd WebExpress.Tutorial.WebApp # create a new solution dotnet new sln -n WebExpress.Tutorial.WebApp # create a new console application dotnet new console -n WebApp.App -f net9.0 # create a new class library dotnet new classlib -n WebApp -f net9.0 # add the projects to the solution dotnet sln add ./WebApp.App/WebApp.App.csproj dotnet sln add ./WebApp/WebApp.csproj
This command creates a new .NET solution named WebExpress.Tutorial.WebApp and uses .NET 9.0 as the framework.
- Check the newly created solution. There should now be a new directory named
WebExpress.Tutorial.WebAppin the current directory. You can view the contents of this directory with the command ls (Linux/Mac) or dir (Windows). - Open the solution in your preferred development environment.
- If you are using Visual Studio Code, you can open the solution with the command
code .in the solution directory.
- If you are using Visual Studio Code, you can open the solution with the command
Now you have created a new solution and are ready to proceed with the next steps in your tutorial.
-
Add the necessary dependencies in the
WebAppproject file.<PropertyGroup> ... <EnableDynamicLoading>true</EnableDynamicLoading> </PropertyGroup> <ItemGroup> <PackageReference Include="WebExpress.WebIndex" Version="0.0.9-alpha"> <Private>false</Private> <ExcludeAssets>runtime</ExcludeAssets> </PackageReference> <PackageReference Include="WebExpress.WebApp" Version="0.0.9-alpha"> <Private>false</Private> <ExcludeAssets>runtime</ExcludeAssets> </PackageReference> </ItemGroup>
-
Add the necessary dependencies in the
WebApp.Appproject file.<ItemGroup> <PackageReference Include="WebExpress.WebIndex" Version="0.0.9-alpha" /> <PackageReference Include="WebExpress.WebApp" Version="0.0.9-alpha" /> </ItemGroup> <ItemGroup> <ProjectReference Include="../WebApp/WebApp.csproj" /> </ItemGroup>
-
Adjust the project file to your requirements.
-
Add a file named
WebExpress.Tutorial.WebApp.specin the solution folder.<?xml version="1.0" encoding="utf-8"?> <package> <id>WebExpress.Tutorial.WebApp</id> <version>0.0.9-alpha</version> <title>WebApp</title> <authors>webexpress-framework@outlook.com</authors> <license>MIT</license> <icon>icon.png</icon> <readme>README.md</readme> <privacypolicy>PrivacyPolicy.md</privacypolicy> <description>A Tutorial how to demonstrate a simple WebExpress application.</description> <tags>webexpress tutorial</tags> <plugin>WebApp</plugin> </package>
-
Adjust the spec file to your requirements.
-
Add the spec file in the
WebApp.Appproject file.<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'"> <Exec Command="$(SolutionDir)$(AssemblyName)/bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).exe -s $(SolutionDir)/$(SolutionName).spec -c $(Configuration) -t $(TargetFramework) -o $(SolutionDir)/pkg/$(Configuration)" /> </Target>
-
Create a new class
Pluginin theWebAppproject that implements theIPlugininterface.using WebExpress.WebCore.WebAttribute; using WebExpress.WebCore.WebPlugin; namespace WebExpress.Tutorial.WebApp { [Name("webexpress.tutorial.webapp:plugin.name")] [Description("webexpress.tutorial.webapp:plugin.description")] [Icon("/assets/img/webapp.svg")] [Application<Application>()] public sealed class Plugin : IPlugin { public void Run() {} } }
-
Adjust the class to your requirements.
-
Create a new class
Applicationin theWebAppproject that implements theIApplicationinterface.using WebExpress.WebCore.WebApplication; using WebExpress.WebCore.WebAttribute; namespace WebExpress.Tutorial.WebApp { [Name("webexpress.tutorial.webapp:app.name")] [Description("webexpress.tutorial.webapp:app.description")] [Icon("/assets/img/webapp.svg")] [ContextPath("/webapp")] public sealed class Application : IApplication { public void Run() {} } }
-
Adjust the class to your requirements.
-
Create a new view for the home page in the
WebAppproject.using WebExpress.WebApp.WebPage; using WebExpress.WebCore.WebAttribute; using WebExpress.WebCore.WebResource; using WebExpress.WebCore.WebScope; using WebExpress.WebUI.WebControl; namespace WebExpress.Tutorial.WebApp.WWW { [Title("webexpress.tutorial.webapp:homepage.label")] [Scope<IScopeGeneral>] public sealed class Index : IPage<VisualTreeWebApp>, IScopeGeneral { public void Process(IRenderContext renderContext, VisualTreeWebApp visualTree) {} } }
-
Adjust the homepage to your requirements.
-
Copy this radme file in the solution directory and add the in the
WebAppproject file.<ItemGroup> <EmbeddedResource Include="../README.md" /> </ItemGroup>
-
Create a new view for the info page in the
WebAppproject.using System.Linq; using WebExpress.WebApp.WebPage; using WebExpress.WebApp.WebScope; using WebExpress.WebCore; using WebExpress.WebCore.Internationalization; using WebExpress.WebCore.WebAttribute; using WebExpress.WebCore.WebPage; using WebExpress.WebUI.WebControl; namespace WebExpress.Tutorial.WebApp.WWWW { [Title("webexpress.tutorial.webapp:infopage.label")] [Scope<IScopeGeneral>] public sealed class Info : IPage<VisualTreeWebApp>, IScopeGeneral { public void Process(IRenderContext renderContext, VisualTreeWebApp visualTree) { var webexpress = WebEx.ComponentHub.PluginManager.Plugins.Where(x => x.PluginId.ToString() == "webexpress.webapp").FirstOrDefault(); var webapp = WebEx.ComponentHub.PluginManager.Plugins.Where(x => x.Assembly == GetType().Assembly).FirstOrDefault(); visualTree.Content.MainPanel.AddPrimary(new ControlImage() { Uri = renderContext.PageContext.ApplicationContext.Route.Concat("assets/img/webapp.svg").ToUri(), Width = 200, Height = 200, HorizontalAlignment = TypeHorizontalAlignment.Right }); var card = new ControlPanelCard() { Margin = new PropertySpacingMargin(PropertySpacing.Space.Null, PropertySpacing.Space.Two) }; card.Add(new ControlText() { Text = I18N.Translate(renderContext.Request?.Culture, "webexpress.tutorial.webapp:app.name"), Format = TypeFormatText.H3 }); card.Add(new ControlText() { Text = I18N.Translate(renderContext.Request?.Culture, "webexpress.tutorial.webapp:app.description"), Format = TypeFormatText.Paragraph }); card.Add(new ControlText() { Text = I18N.Translate(renderContext.Request?.Culture, "webexpress.tutorial.webapp:app.about"), Format = TypeFormatText.H3 }); card.Add(new ControlText() { Text = string.Format ( I18N.Translate(renderContext.Request?.Culture, "webexpress.tutorial.webapp:app.version.label"), I18N.Translate(renderContext.Request?.Culture, webapp?.PluginName), webapp?.Version, webexpress?.PluginName, webexpress?.Version ), TextColor = new PropertyColorText(TypeColorText.Primary) }); visualTree.Content.MainPanel.AddPrimary(card); } } }
-
Create a new fragment to view the content in the
WebAppproject.using System.IO; using WebApp.WebPage; using WebExpress.WebApp.WebSection; using WebExpress.WebCore.WebAttribute; using WebExpress.WebCore.WebHtml; using WebExpress.WebCore.WebPage; using WebExpress.WebUI.WebAttribute; using WebExpress.WebUI.WebControl; using WebExpress.WebUI.WebFragment; namespace WebExpress.Tutorial.WebApp.WebFragment { [Section<SectionContentPrimary>] [Scope<HomePage>] [Cache] public sealed class HomeContentFragment : FragmentControlPanel { public HomeContentFragment(IFragmentContext fragmentContext) : base(fragmentContext) { using var stream = GetType().Assembly.GetManifestResourceStream("WebApp.README.md"); using var reader = new StreamReader(stream); Add(new ControlText() { Format = TypeFormatText.Markdown, Text = reader.ReadToEnd() }); } } }
-
Adjust the fragment to your requirements.
-
Create a new fragment to link the home page in the
WebAppproject.using WebApp.WebPage; using WebExpress.WebApp.WebSection; using WebExpress.WebCore.WebAttribute; using WebExpress.WebCore.WebComponent; using WebExpress.WebCore.WebHtml; using WebExpress.WebCore.WebPage; using WebExpress.WebUI.WebAttribute; using WebExpress.WebUI.WebControl; using WebExpress.WebUI.WebFragment; namespace WebExpress.Tutorial.WebApp.WebFragment { [Section<SectionAppNavigationPrimary>] [Scope<IScopeGeneral>] [Cache] public sealed class HomeLinkFragment : FragmentControlNavigationItemLink { public HomeFragment(IComponentHub componentHub, IFragmentContext fragmentContext) : base(fragmentContext) { Text = "webexpress.tutorial.webapp:homepage.label"; Uri = componentHub.SitemapManager.GetUri<HomePage>(fragmentContext.ApplicationContext); Icon = new IconHome(); } public override IHtmlNode Render(IRenderControlContext renderContext, IVisualTreeControl visualTree) { Active = renderContext.Endpoint is HomePage ? TypeActive.Active : TypeActive.None; return base.Render(renderContext, visualTree); } } }
-
Adjust the fragment to your requirements.
-
Create a new fragment to link the info page in the
WebAppproject.using WebApp.WebPage; using WebExpress.WebApp.WebSection; using WebExpress.WebCore.WebAttribute; using WebExpress.WebCore.WebComponent; using WebExpress.WebCore.WebHtml; using WebExpress.WebCore.WebPage; using WebExpress.WebUI.WebAttribute; using WebExpress.WebUI.WebControl; using WebExpress.WebUI.WebFragment; namespace WebExpress.Tutorial.WebApp.WebFragment { [Section<SectionAppNavigationSecondary>] [Scope<IScopeGeneral>] [Cache] public sealed class InfoLinkFragment : FragmentControlNavigationItemLink { public InfoFragment(IComponentHub componentHub, IFragmentContext fragmentContext) : base(fragmentContext) { Text = "webexpress.tutorial.webapp:infopage.label"; Uri = componentHub.SitemapManager.GetUri<InfoPage>(fragmentContext.ApplicationContext); Icon = new IconInfoCircle(); } public override IHtmlNode Render(IRenderControlContext renderContext, IVisualTreeControl visualTree) { Active = renderContext.Endpoint is InfoPage ? TypeActive.Active : TypeActive.None; return base.Render(renderContext, visualTree); } } }
-
Adjust the fragment to your requirements.
-
Create a new fragment to view the footer in the
WebAppproject.using WebExpress.WebApp.WebScope; using WebExpress.WebApp.WebSection; using WebExpress.WebCore.Internationalization; using WebExpress.WebCore.WebAttribute; using WebExpress.WebCore.WebFragment; using WebExpress.WebCore.WebHtml; using WebExpress.WebCore.WebUri; using WebExpress.WebUI.WebControl; using WebExpress.WebUI.WebFragment; using WebExpress.WebUI.WebPage; namespace WebExpress.Tutorial.WebApp.WebFragment { [Section<SectionFooterPrimary>] [Scope<IScopeGeneral>] public sealed class FooterFragment : FragmentControlPanel { private ControlLink LicenceLink { get; } = new ControlLink() { TextColor = new PropertyColorText(TypeColorText.Muted), Size = new PropertySizeText(TypeSizeText.Small) }; public FooterFragment(IFragmentContext fragmentContext) : base(fragmentContext) { Classes = ["text-center"]; Add(LicenceLink); } public override IHtmlNode Render(IRenderControlContext renderContext, IVisualTreeControl visualTree) { LicenceLink.Text = "webexpress.tutorial.webapp:app.license.label"; LicenceLink.Uri = new UriEndpoint(I18N.Translate(renderContext.Request?.Culture, "webexpress.tutorial.webapp:app.license.uri")); return base.Render(renderContext, visualTree); } } }
-
Adjust the fragment to your requirements.
-
Change the program class of the
WebApp.Appproject as follows:using System.Reflection; namespace WebExpress.Tutorial.WebApp.App { internal class Program { static void Main(string[] args) { var app = new WebExpress.WebCore.WebEx() { Name = Assembly.GetExecutingAssembly().GetName().Name }; app.Execution(args); } } }
- Add support for multiple languages. This can be achieved by using i18n files. Each resource file contains the translations for all strings in your application. Name your resource files according to the culture they represent. For example, the file for German translations should be called `de``. In the following, we use the english language.
plugin.name=WebApp
plugin.description=A Tutorial how to demonstrate a simple WebExpress application.
app.name=WebApp Tutorial
app.label=WebExprss Application
app.description=A Tutorial how to demonstrate a simple WebExpress application.
app.license.label=License MIT
app.license.uri=https://github.com/webexpress-framework/WebExpress.Tutorial.WebApp/blob/main/LICENSE
app.about=About WebApp Tutorial
app.version.label={0} version {1} created with {2} version {3}.
homepage.label=Home page
infopage.label=Info
- Add the en file in the
WebAppproject file.
<ItemGroup>
<EmbeddedResource Include="Internationalization/en" />
</ItemGroup>-
Add assets to the
WebAppproject. You can get the assets for this tutorial here: https://github.com/webexpress-framework/WebExpress.Tutorial.WebApp/tree/main/WebApp/Assets/img -
Add the assets in the
WebAppproject file.<ItemGroup> <EmbeddedResource Include="Assets/**/*.*"> <LogicalName>$(MSBuildProjectName).Assets.%(RecursiveDir)%(Filename)%(Extension)</LogicalName> </EmbeddedResource> </ItemGroup>
-
The application must be configured. A standard configuration must be delivered for this purpose. Add the configuration file
config/webexpress.config.xmlto theWebApp.Appproject.<?xml version="1.0" encoding="utf-8" ?> <config version = "1"> <log modus="Off" debug="false" path="/var/log/" encoding="utf-8" filename="webexpress.log" timepattern="dd.MM.yyyy HH:mm:ss" /> <uri>http://localhost/</uri> <endpoint uri="http://localhost/"/> <limit> <connectionlimit>300</connectionlimit> <uploadlimit>3000000000</uploadlimit> </limit> <culture>en</culture> <packages>./packages</packages> <assets>./assets</assets> <data>./data</data> <contextpath></contextpath> </config>
-
Include the configuration file in the
WebApp.Appproject file.<ItemGroup> <None Update="config/webexpress.config.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
-
Compile the solution as a release. To do this, open the command line or terminal in the solution directory and run the following command:
dotnet build --configuration Release
This command compiles the solution in release mode. You can find the compiled files in the
bin/Releasedirectory of your project. -
Run the solution by starting the
WebApp.Appproject.cd WebApp.App\bin\Release\net9.0 dotnet run --project ../../../WebApp.App.csproj
-
After compiling, there should be a file with the
.wxpextension in thepkg/Releasedirectory. This file do you need inWebExpress.
- Check the result by calling up the following URL in the browser: http://localhost/webapp
- Good luck!
#WebExpress #WebServer #WebCore #WebUI #Tutorial #DotNet
