Klicke hier für den deutschen Artikel.
General
In web development, a distinction is made between the frontend (client) and the backend (server). This generally results in a cleaner architecture that improves maintainability, scalability, and security, and ensures a clear separation of responsibilities between the user interface (UI) and the business logic.
Frontend: UI in web browser (client)
The frontend encompasses everything that runs in the browser or on the user’s device, such as Razor, HTML, CSS, or JavaScript. It is responsible for rendering the user interface and for the user’s interaction with the web application.
Backend: Processing/Data/Business Logic (server)
The backend encompasses everything that runs on the server, such as ASP.NET Core. It handles business logic, data processing, authentication, and access to data sources such as databases.
Structure and Components of List & Label
The List & Label Web Report Designer (WRD) and Web Report Viewer (WRV) components provided in .NET are structured in accordance with this separation and architecture. But how do you transfer information from the client (frontend) to the server (backend) so that you can continue working with it?
Use cases
Typical use cases include:
- Passing an authentication key (authKey)
- Specifying the List & Label display language directly from the frontend - for example, based on the client’s system or browser language - rather than having it determined by the backend or server
- Passing the entire data source for a report, for example as a JSON stream
- And much more
Implementation
The web components for WRD and WRV provide the clientData attribute for this purpose. This allows any client-specific data to be passed from the frontend (client) to the server-side context of WRD/WRV in the backend (server).
Frontend (client): JavaScript frameworks
Vue.js (*.vue)
...
<template>
<div>
<ll-webreportdesigner
backendurl="https://localhost:<PORT>/LLWebReportDesigner"
showTutorial="true"
clientData="MyCustomClientDataFromFrontEnd"
/>
</div>
</template>
<script lang="ts">
</script>
...
React (*.tsx)
...
import { useExternalScript } from './hooks/useExternalScript';
export const WebReportDesigner = () => {
const state = useExternalScript("https://localhost:<PORT>/WebReportDesigner.js");
return (
<div>
<div>
<title>WebReportDesigner</title>
</div>
<div>
{state === "loading" && <p>Loading...</p>}
{state === "ready" &&
<ll-webreportdesigner
backendurl="https://localhost:<PORT>/LLWebReportDesigner"
showTutorial="true"
clientData="MyCustomClientDataFromFrontEnd" />
}
</div>
</div>
);
}
...
Angular (*.html)
...
<div>
<ll-webreportdesigner
backendUrl="http://localhost:<PORT>/LLWebReportDesigner"
showTutorial="true"
clientData="MyCustomClientDataFromFrontEnd"
/>
</div>
...
Frontend (client): MVC/Razor (*.cshtml)
...
@using combit.Reporting.Web
@using combit.Reporting.Web.WebReportDesigner
@model MVC_Web_Reporting_Sample.ViewModels.CustomViewModel
@{
Layout = null;
var options = new WebReportDesignerMVCOptions(string.Empty)
{
ShowTutorial = true,
ClientData = "MyCustomClientDataFromFrontEnd"
};
}
<!DOCTYPE html>
@Html.WebReportDesigner(options);
...
Backend (server): C#
...
public override void OnProvideListLabel(
ProvideListLabelContext provideListLabelContext)
{
// verify if the context is in the initialization phase, if not, you can
// access the client data (if sent by the client) and handle it accordingly
if (!provideListLabelContext.Initializing)
{
// check, if clientData exists and is valid
if(provideListLabelContext.ClientData != null)
{
// Handle/Access the client data here e.g. a simple string
// or more complex JSON object
var myClientData = provideListLabelContext.ClientData;
}
}
// Forward with creating the ListLabel object, defining the dataprovider etc.
// and returning the prepared object
ListLabel ll = DefaultSettings.GetListLabelInstance(
provideListLabelContext.RepositoryId, null);
provideListLabelContext.NewInstance = ll;
}
...