Förvandla din rakbladssida till reaktiv form (2024)

  • Ladda ner källkod - 14,3 KB
  • Ladda ner mer avancerade exempel - 25,8 KB

Introduktion

ASP.NET Core Razor Pages är ett relativt nytt tillägg till ASP.NET Core. Den introducerades med .NET Core v2.0, som ett lätt alternativ till fullskalig MVC. Den föreslår en mycket enklare programmeringsmodell som är ganska lik de gamla WebForms, förutom att den är statslös och fri från kontroller på serversidan. Istället för att skriva kontroller som returnerar vyer, skulle en utvecklares fokus ligga på att skapa sidvisningar, med kod bakom som liknar ett MVVM-ramverk. Routing behöver inte vara explicit konfigurerat, utan baseras på konventionen att använda filnamnen du ger till sidorna.

Razor pages är lätta att plocka upp av nybörjare. Det är mest lämpligt för statiska webbplatser och andra enkla, server-side-renderade lösningar som inte involverar för mycket interaktivitet. Men för applikationer som kräver mer sofistikerad användarinteraktion, föreslås det ofta att man föredrar att använda JavaScript-ramverk på klientsidan med data som serveras av webb-API:er.

Men kommer det inte att vara bra att behålla enkelheten hos Razor Pages samtidigt som vi fortfarande kan utveckla rika renderade lösningar på klientsidan? Följande avsnitt i den här artikeln kommer att demonstrera hur man använder en Razor-sida för att bygga en renderad form på klientsidan i MVVM-stil, och där varje fältkonfiguration, inklusive valideringar på både klient- och serversidan, definieras i en C#-klass.

För denna ansträngning kommer vi att användadotNetify-Elementskomponentbibliotek som jag skrev. Detta bibliotek är i grunden en uppsättning ReactJS-komponenter som är anpassade för integration med .NET C#-klasser och kommunicerar via SignalR. Det är också nära integrerat med Rx.NET (System.Reaktiv) som främjar ett sätt att skriva kod som är enklare och mer underhållbart.

Reaktiv programmering

Innan vi börjar skriva kod, låt oss först ha en snabb översikt om reaktiv programmering. Jag har ännu inte hittat en definition som omedelbart kan förstås, men min egen uppfattning är att det är ett sätt att skriva kod som handlar om dataström (som texten som en användare skriver i ett textfält i en webbläsare, till en egenskap för en C#-klassinstans i back-end) där istället för att data proaktivt skickas av datakällan (eller utgivaren) till den som vill ha den (eller prenumeranterna), är det prenumeranterna som lyssnar på förändringen i utgivarens tillstånd och reagera på det.

Denna förklaring kan faktiskt beskriva vilken händelsedriven programmeringsteknik som helst, men den viktiga skillnaden ligger i de abstraktioner som Reactive-biblioteket tillhandahåller. De tillåter oss att implementera konceptet på ett uttrycksfullt, deklarativt och asynkront sätt, och ta det vidare genom att tillhandahålla en rik verktygsuppsättning för att manipulera och transformera dataströmmen, som att kartlägga, reducera och kombinera en eller flera strömmar till något annat.

För ett enkelt exempel, överväg förhållandet mellan en ljusströmbrytare och en glödlampa. Om vi ​​skulle programmera det skulle det vanligtvis vara så här:

C#

privat bool_växla;offentlig boolVäxla{skaffa sig{lämna tillbaka_växla; }uppsättning{ _switch =värde; Glödlampa =värde? State.On : State.Off; }}offentligState Light Bulb {skaffa sig;uppsättning; }

DeVäxlaär kopplat tillGlödlampa, och denGlödlampaberor påVäxlaatt ändra sitt eget tillstånd. Vad händer om vi lägger till en tredje stat tillGlödlampa, eller så vill vi koppla en andra glödlampa tillVäxla? Du måste återbesökaVäxlas implementering och ändra den därefter, även om det är något externt tillVäxlasom förändras.

Låt oss undersöka det igen efter att vi har omfaktort koden till ett reaktivt tillvägagångssätt:

C#

offentligReactiveProperty Switch =>nyReactiveProperty();offentligReactiveProperty Lightbulb =>nyReactiveProperty();constructor(){ Switch .SubscribedBy(LightBulb, switchValue => switchValue ? State.On : State.Off);}

Med hjälp av de nya abstraktionerna vänder viVäxlaochGlödlampatill reaktiva egenskaper som kan tecknas. Vi gör dem frikopplade från varandra och etablerar deras relation med ett uttryckligt, deklarativt och kedjabart kommando. Att lägga till en andra glödlampa skulle bara lägga till en ny kedja i konstruktören och en ny tredjeGlödlampas tillstånd skulle finnas i den funktionella kartläggningslogiken förPrenumererade avkommando.

Det här är ett så enkelt exempel att fördelarna kan verka subtila, men när vi extrapolerar detta till en mycket mer komplex applikation har den här typen av programmering en stor potential att göra vår kodbas mycket mer enkel, underhållbar och skalbar.

Reaktiv rakhyvelsida steg-för-steg

För följande övning måste du installera .NET Core v2.1 (eller senaste) SDK, och jag rekommenderar att du använder Visual Studio Code med en kommandoradsterminal.

Steg 1: Nytt Razor Pages-projekt

Börja med att skapa en ny ASP.NET Core Razor Pages Web App från den officiella mallen från kommandoraden:

MC++

dotnetnyrakapparat

Det kommer att skapa ett projekt som har några sidor. Vi kommer att implementera vårt formulär på indexsidan, så vi behöver inte många av dessa standardfiler. Låt oss bli av med följande:

  • Alla filer i Pages/Sharedbortsett från _Layout.cshtml.
  • Alla filer i Pagesbortsett från _ViewImports.cshtml,_ViewStart.cshtml,Index.cshtmlochIndex.cshtml.cs.
  • Allt underwwwroot bortsett från favicon.ico(vi behöver inte dessa CSS, bilder och skript).

Steg 2: Inkludera skript till huvudlayout

ÖppenPages/Shared/_Layout.cshtmloch ersätt hela innehållet med följande:

HTML

<!DOCTYPE html><html><huvud> <meta teckenuppsättning="utf-8" /> <meta namn="utsiktsplats" innehåll="bredd=enhetsbredd, initialskala=1,0" /> <länk href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stilmall" /> <länk href="https://unpkg.com/dotnetify-elements@0.1.1/dotnetify-elements.css" rel="stilmall" /></huvud><kropp>@RenderBody()<manus src="https://unpkg.com/react@16.3.2/umd/react.production.min.js"></manus> <manus src="https://unpkg.com/react-dom@16.3.2/umd/react-dom.production.min.js"></manus> <manus src= "https://cdnjs.cloudflare.com/ajax/libs/styled-components/3.3.3/styled-components.min.js"> </manus> <manus src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.js"></manus> <manus src="https://code.jquery.com/jquery-3.3.1.min.js"></manus> <manus src="https://unpkg.com/dotnetify@3.0.1/dist/signalR-netcore.js"></manus> <manus src="https://unpkg.com/dotnetify@3.0.1/dist/dotnetify-hub.js"></manus> <manus src="https://unpkg.com/dotnetify@3.0.1/dist/dotnetify-react.min.js"></manus> <manus src="https://unpkg.com/dotnetify-elements@0.1.1/lib/dotnetify-elements.bundle.js"> </manus> </kropp></html>

Vad vi gjorde var att rensa upp huvudlayouten från onödig standardkod och sedan lägga till alla CDN-skript som krävs avdotNetify-Elementsbibliotek. Som du kan se använder den Bootstrap 4-formatmallen och beror på:

  • ReactJS - visa bibliotek för att återge vårt formulär på klientsidan
  • Styled-Components - ett ReactJS-baserat CSS-in-JS-bibliotek för UI-styling
  • Babel - översätter vår kod som vi kommer att skriva i senaste JavaScript-syntaxen till något äldre webbläsare kan förstå
  • JQuery - tillhandahåller vanliga verktyg
  • SignalR .NET Core - tillhandahåller transportskiktet mellan webbläsaren och vår ASP.NET-server.

Steg 3: Installera dotNetify Server-Side Libraries

Utför följande kommandon för att installera biblioteken från NuGet:

MC++

dotnet lägg till paketet DotNetify.SignalRdotnet lägg till paketet DotNetify.Elementsdotnet återställning

Steg 4: Konfigurera dotNetify och SignalR

ErsättStartup.csmed följande (ersätt namnområdet med ditt):

C#

använder sig avSystemet;använder sig avSystem.Collections.Generisk;använder sig avSystem.Linq;använder sig avSystem.Threading.Tasks;använder sig avMicrosoft.AspNetCore.Builder;använder sig avMicrosoft.AspNetCore.Hosting;använder sig avMicrosoft.AspNetCore.Http;använder sig avMicrosoft.AspNetCore.HttpsPolicy;använder sig avMicrosoft.AspNetCore.Mvc;använder sig avMicrosoft.Extensions.Configuration;använder sig avMicrosoft.Extensions.DependencyInjection;använder sig avDotNetify;namnutrymmeRakapparat{offentlig klassBörja {offentligStartup(IConfiguration configuration) { Configuration = configuration; }offentligIConfiguration Configuration {skaffa sig; }offentlig tomhetConfigureServices(IServiceCollection-tjänster) { services.AddMemoryCache(); services.AddSignalR(); services.AddDotNetify(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }offentlig tomhetConfigure(IApplicationBuilder app, IHostingEnvironment env) { app.UseWebSockets(); app.UseSignalR(rutter => rutter.MapDotNetifyHub()); app.UseDotNetify(); app.UseStaticFiles(); app.UseMvc(); } }}

Steg 5: Implementera Reactive Form C# Class

Formuläret vi implementerar är ett konferensregistreringsformulär som samlar in följande information med validering:

  • namn- krävs
  • E-post- krävs, måste överensstämma med standard e-postmönster, får inte användas vid tidigare registrering
  • TShirtSize- antingen inte specificerat, eller en av dessa:S,M,L,XL

ÖppenIndex.cshtml.cs, och ersätt med följande:

C#

använder sig avDotNetify;använder sig avDotNetify.Elements;använder sig avSystem.Collections.Generisk;använder sig avSystem.Linq;använder sig avSystem.Reactive.Linq;namnutrymmeRazor.Pages{offentlig klassIndexVM : BaseVM {privat klassFormData {offentlig strängNamn {skaffa sig;uppsättning; }offentlig strängE-posta {skaffa sig;uppsättning; }offentlig strängTShirtSize {skaffa sig;uppsättning; } }privatList _registeredList =nyList();offentligIndexVM() {varclearForm = AddInternalProperty("Rensa formulär"); AddProperty("Namn") .WithAttribute(nyTextFieldAttribute { Label ="Namn:", Platshållare ="Ange ditt namn (obligatoriskt)"}) .WithRequiredValidation() .SubscribeTo(clearForm.Select(_ =>"")); AddProperty("E-post") .WithAttribute(nyTextFieldAttribute { Label ="E-post:", Platshållare ="Skriv in din mailadress"}) .WithRequiredValidation() .WithPatternValidation(Pattern.Email,"Måste vara en giltig e-postadress.") .WithServerValidation(ValidateEmailNotRegistered,"Email redan registrerad") .SubscribeTo(clearForm.Select(_ =>"")); AddProperty("TshirtSize") .WithAttribute(nyDropdownListAttribute { Label ="T-shirt storlek:", Platshållare ="Välj storlek på din T-shirt...", Alternativ =nyOrdbok { {"",""}, {"S","Små"}, {"M","Medium"}, {"L","Stor"}, {"XL","Extra stor"} }.ToArray() }) .SubscribeTo(clearForm.Select(_ =>"")); AddProperty("Registrera") .WithAttribute(ny{ Etikett ="Registrera"}) .SubscribedBy( AddProperty("ServerResponse"), submittedData => Save(submittedData)) .SubscribedBy(clearForm, _ =>Sann); }privat strängSave(FormData data) { _registeredList.Add(data);lämna tillbaka$"Namnet __'{data.Name}'__ med e-postadressen '{data.Email}' har registrerats."; }privat boolValidateEmailNotRegistered(strängemail) => !_registeredList.Any(x => x.Email == email); }}

Låt oss undersöka den här koden. Vi har lagt till tre reaktiva egenskaper att samla innamn,E-post, ochTShirtSizeinformation och fortsätt sedan för att definiera konfiguration (märka,Platshållare,falla neralternativ) och valideringarna för varje egenskap deklarativt genom att använda kedjebara API:er som tillhandahålls avDotNetify.Elementsnamnutrymme.

Vid körning kommer konfigurationen och valideringarna som vi har definierat här att användas avdotNetifybibliotek för att initiera klientsidans UI-komponenter. Valideringar som de obligatoriska och mönstervalideringarna är på klientsidan, så när användaren slu*tför sin inmatning valideras den direkt i webbläsaren. Biblioteket tar bekvämt hand om valideringar på serversidan, som valideringen för att kontrollera om e-postmeddelandet har registrerats som vi kör på back-end, genom att skicka inskriven text till servern som ska valideras, allt utan att du behöver skriva din egen koda.

Det kommer att finnas en Skicka-knapp som kommer att kopplas tillRegistrerafast egendom. Egenskapen kommer att få all information om det knappklicket. Vi har lagt till en annan egenskap som heterServerresponsatt prenumerera påRegistreraegendom och i sin tur skicka feedback till webbläsaren för att indikera att servern har tagit emot informationen.

Den sista egenskapen ärRensa formuläregendom, skapad sominreegenskap, vilket innebär att värdet inte kommer att skickas till webbläsaren. Den prenumereras av alla tre indataegenskaperna för att rensa sina egna fältvärden, vilket inträffar närServersvaregendom publicerar sitt värde.

Sista steget: Implementera Reactive Form View

ÖppenIndex.cshtmloch ersätt innehållet med följande:

JavaScript

@sida
"Montera"/>

Vi lägger endivtagga medid'Montera', där ReactJS renderar sidkomponenten (på sista raden inutimanusmärka). Inutimanustaggen implementerade vi sidkomponenten, som är sammansatt av UI-komponenter fråndotNetify-Elementsbibliotek (varje komponent är dokumenterad på webbplatsen).

DedotNetify-Elementskomponenter är utformade för att minimera behovet för utvecklare att skriva JavaScript-kod. Enligt konvention matchas en komponent med en C#-klassegenskap med hjälp avidattribut. När de matchas kommer konfigurationen och valideringarna som definieras i den C#-klassen att användas automatiskt för att initiera komponenten. Identifieringen av själva C#-klassen sker genomVMContextkomponent som anger namnet på C#-klassen, i vårt fall är detIndexVM.

Observera att vi använderBabelbibliotek för att göra runtime-kompilering av skriptet. Det är enkelt och bekvämt, men medför prestationsstraff. Om detta utgör ett problem åtgärdas det genom att sätta upp ett byggverktyg som WebPack för att kompilera skripten före distribution.

Kör projektet

Kör projektet genom att ange:

dotnet kör

När du går till adressenlokal värd: 5000, bör du se formuläret. Testa valideringarna. Om du registrerar samma e-post två gånger,E-posttextfältet ska visa "E-post inte registrerat" meddelande och tillåter dig inte att skicka.

Avancerade exempel

Också bifogat är källkoden för mer avancerade exempel på att använda Razor Pages för en komplex, kapslad form som kan öppna en dialogruta för modal inmatning, och även en live-instrumentpanel. Se dokumentationen på webbplatsen för detaljer om komponenterna som ingår i dessa exempel.

Förvandla din rakbladssida till reaktiv form (1)

Sammanfattning

ASP.NET Core Razor Pages är ett nytt Microsofts erbjudande för webbutveckling, även om tekniken i sig inte är ny. Den är baserad på den befintliga MVC Razor View men med anmärkningsvärda förbättringar som syftar till att göra utvecklingen av serverrenderade webbsidor enklare och mer organiserad.

För utvecklare som vill använda Razor Pages för en mer sofistikerad applikation med rik interaktion på klientsidan, erbjuder vi integration meddotNetify-Elements, ett bibliotek med öppen källkod med ReactJS-komponenter som är designade för att fungera sömlöst med .NET C#-klasser och använda SignalR för transportlagret.

DotNetify-Elementssyftar till att minska komplexiteten i samband med modern webbapplikationsutveckling ur .NET-utvecklarens perspektiv. Det är väldokumenterat och har rika reatures. Förutom att ha många användbara komponenter; det ger ett enkelt layoutsystem för att snabbt ställa in sidvisningar som denna och ännu mer komplexa sådana som har navigeringssidofält; den stöder tema och avancerad anpassning. Och i kraft av att använda SignalR kan den ge realtidsdata-push till webbläsare, såsom liveövervakning från IoT-enheter och annan realtidsvisualisering.

Mer läsning om biblioteket:

Full-stack s/w ingenjör, öppen källkod författare.

Förvandla din rakbladssida till reaktiv form (2024)

References

Top Articles
Latest Posts
Article information

Author: Pres. Carey Rath

Last Updated:

Views: 5975

Rating: 4 / 5 (41 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Pres. Carey Rath

Birthday: 1997-03-06

Address: 14955 Ledner Trail, East Rodrickfort, NE 85127-8369

Phone: +18682428114917

Job: National Technology Representative

Hobby: Sand art, Drama, Web surfing, Cycling, Brazilian jiu-jitsu, Leather crafting, Creative writing

Introduction: My name is Pres. Carey Rath, I am a faithful, funny, vast, joyous, lively, brave, glamorous person who loves writing and wants to share my knowledge and understanding with you.