Lägga till verifieringskontroller i datalistans redigeringsgränssnitt (C#)

av Scott Mitchell

Ladda ned PDF

I den här självstudien får vi se hur enkelt det är att lägga till verifieringskontroller i DataList:s EditItemTemplate för att tillhandahålla ett mer idiotsäkert redigeringsanvändargränssnitt.

Inledning

I självstudierna för DataList-redigering hittills har redigeringsgränssnitten för DataLists inte inkluderat någon proaktiv validering av användarindata, även om ogiltiga användarindata, till exempel ett produktnamn som saknas eller ett negativt pris, resulterar i ett undantag. I den föregående självstudien undersökte vi hur du lägger till kod för undantagshantering i DataList-händelsehanteraren UpdateCommand för att fånga och korrekt visa information om eventuella undantag som har genererats. Helst skulle dock redigeringsgränssnittet innehålla verifieringskontroller för att förhindra att en användare anger sådana ogiltiga data i första hand.

I den här självstudien får vi se hur enkelt det är att lägga till verifieringskontroller i DataList EditItemTemplate för att tillhandahålla ett säkrare redigeringsgränssnitt. Närmare bestämt tar den här självstudien exemplet som skapades i föregående självstudie och utökar redigeringsgränssnittet för att inkludera relevant validering.

Steg 1: Replikera exemplet frånhanteringen av BLL- och DAL-Level-undantag

I självstudien Hantering av BLL- och DAL-Level-undantag skapade vi en sida som listade namnen och priserna på produkterna i en redigerbar datalista med två kolumner. Vårt mål med den här handledningen är att utöka datalistans redigeringsgränssnitt till att omfatta valideringskontroller. I synnerhet kommer vår valideringslogik att:

  • Kräv att produktens namn anges
  • Kontrollera att värdet som angetts för priset är ett giltigt valutaformat
  • Kontrollera att värdet som angetts för priset är större än eller lika med noll, eftersom ett negativt UnitPrice värde är ogiltigt

Innan vi kan titta på hur du utökar det tidigare exemplet för att inkludera validering måste vi först replikera exemplet från ErrorHandling.aspx sidan i EditDeleteDataList mappen till sidan för den här självstudiekursen. UIValidation.aspx För att uppnå detta måste vi kopiera över både ErrorHandling.aspx sidans deklarativa markering och dess källkod. Kopiera först över den deklarativa markeringen genom att utföra följande steg:

  1. Öppna sidan ErrorHandling.aspx i Visual Studio
  2. Gå till sidans deklarativa markering (klicka på knappen Källa längst ned på sidan)
  3. Kopiera texten i taggarna <asp:Content> och </asp:Content> (raderna 3 till och med 32), enligt bild 1.

Kopiera texten i <asp:Content> Control

Bild 1: Kopiera texten i <asp:Content> kontrollen (klicka för att visa bilden i full storlek)

  1. Öppna sidan UIValidation.aspx
  2. Gå till sidans deklarativa markering
  3. Klistra in texten i <asp:Content> kontrollen.

Om du vill kopiera över källkoden öppnar du ErrorHandling.aspx.vb sidan och kopierar bara texten iEditDeleteDataList_ErrorHandling klassen. Kopiera de tre händelsehanterarna (Products_EditCommand, Products_CancelCommandoch Products_UpdateCommand) tillsammans med DisplayExceptionDetails metoden, men kopiera inte klassdeklarationen eller using -uttrycken. Klistra in den kopierade texten inomEditDeleteDataList_UIValidation klassen i UIValidation.aspx.vb.

När du har flyttat över innehållet och koden från ErrorHandling.aspx till UIValidation.aspxtar du en stund att testa sidorna i en webbläsare. Du bör se samma utdata och uppleva samma funktioner på var och en av dessa två sidor (se bild 2).

Sidan UIValidation.aspx efterliknar funktionerna i ErrorHandling.aspx

Bild 2: Sidan UIValidation.aspx efterliknar funktionerna i ErrorHandling.aspx (Klicka om du vill visa en bild i full storlek)

Steg 2: Lägga till valideringskontrollerna i DataList-filen EditItemTemplate

När du skapar formulär för datainmatning är det viktigt att användarna anger obligatoriska fält och att alla deras angivna indata är lagliga, korrekt formaterade värden. För att säkerställa att en användares indata är giltiga tillhandahåller ASP.NET fem inbyggda verifieringskontroller som är utformade för att verifiera värdet för en enda indatawebbkontroll:

Mer information om dessa fem kontroller finns i guiden Lägga till verifieringskontroller i redigerings- och infogningsgränssnitt eller gå till avsnittet Verifieringskontroller i snabbstartsguiderna för ASP.NET.

I vår självstudie måste vi använda en RequiredFieldValidator för att säkerställa att ett värde för produktnamnet har angetts och en CompareValidator för att säkerställa att det angivna priset har ett värde som är större än eller lika med 0 och visas i ett giltigt valutaformat.

Anmärkning

Medan ASP.NET 1.x hade samma fem valideringskontroller har ASP.NET 2.0 lagt till ett antal förbättringar, varav de två främsta är stöd för skript på klientsidan för webbläsare utöver Internet Explorer och möjligheten att partitionera valideringskontroller på en sida i valideringsgrupper. Mer information om de nya funktionerna för valideringskontroll i 2.0 finns i Dissekera valideringskontrollerna i ASP.NET 2.0.

Vi börjar med att lägga till nödvändiga verifieringskontroller i DataList s EditItemTemplate. Den här uppgiften kan utföras via designern genom att klicka på länken Redigera mallar från datalistans smarta tagg eller via den deklarativa syntaxen. Låt oss gå igenom processen med alternativet Redigera mallar från designvyn. När du har valt att redigera DataList s EditItemTemplatelägger du till en RequiredFieldValidator genom att dra den från verktygslådan till mallredigeringsgränssnittet och placera den efter ProductName textrutan.

Lägg till en RequiredFieldValidator i EditItemTemplate efter textrutan ProductName

Bild 3: Lägg till en RequiredFieldValidator i EditItemTemplate AfterProductName textrutan (Klicka om du vill visa en bild i full storlek)

Alla valideringskontroller fungerar genom att verifiera indata för en enda ASP.NET webbkontroll. Därför måste vi ange att den RequiredFieldValidator som vi precis har lagt till ska verifieras mot ProductName TextBox. Detta görs genom att ange verifieringskontrollens ControlToValidate egenskap till lämplig webbkontroll (IDi den här instansenProductName). Ställ sedan in egenskapenErrorMessage till "Du måste ange produktens namn" och Text egenskapen till *. Egenskapsvärdet Text , om det anges, är den text som visas av verifieringskontrollen om verifieringen misslyckas. Egenskapsvärdet ErrorMessage, vilket är obligatoriskt, används av ValidationSummary-kontrollen; om egenskapsvärdet Text utelämnas visas egenskapsvärdet ErrorMessage av verifieringskontrollen vid ogiltiga indata.

När du har angett dessa tre egenskaper för RequiredFieldValidator bör skärmen se ut ungefär som i bild 4.

Ange egenskaperna RequiredFieldValidator s ControlToValidate, ErrorMessage och Text

Bild 4: Ange RequiredFieldValidator s ControlToValidate, ErrorMessageoch Text egenskaper (Klicka om du vill visa en bild i full storlek)

När RequiredFieldValidator har lagts till i EditItemTemplate, är allt som återstår att lägga till validering för textrutan för produktens pris. Eftersom är UnitPrice valfritt när du redigerar en post behöver vi inte lägga till en RequiredFieldValidator. Vi behöver dock lägga till en CompareValidator för att säkerställa att UnitPrice, om den tillhandahålls, är korrekt formaterad som en valuta och är större än eller lika med 0.

Lägg till CompareValidator i EditItemTemplate och ange dess ControlToValidate egenskap till UnitPrice, dess ErrorMessage egenskap till Priset måste vara större än eller lika med noll och kan inte inkludera valutasymbolen och dess Text egenskap till *. För att ange att UnitPrice värdet måste vara större än eller lika med 0, ställ in CompareValidator egenskapen Operator till GreaterThanEqual, egenskapen ValueToCompare till 0 och egenskapen till Type.

När du har lagt till dessa två verifieringskontroller bör den deklarativa syntaxen för DataList EditItemTemplate se ut ungefär så här:

<EditItemTemplate>
    Product name:
        <asp:TextBox ID="ProductName" runat="server"
            Text='<%# Eval("ProductName") %>'></asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator1"
            ControlToValidate="ProductName"
            ErrorMessage="You must provide the product's name"
            runat="server">*</asp:RequiredFieldValidator>
    <br />
    Price:
        <asp:TextBox ID="UnitPrice" runat="server"
            Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:TextBox>
        <asp:CompareValidator ID="CompareValidator1"
            ControlToValidate="UnitPrice"
            ErrorMessage="The price must be greater than or equal to zero
                          and cannot include the currency symbol"
            Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0"
            runat="server">*</asp:CompareValidator><br />
    <br />
    <asp:Button ID="UpdateProduct" runat="server" CommandName="Update"
        Text="Update" /> 
    <asp:Button ID="CancelUpdate" runat="server" CommandName="Cancel"
        Text="Cancel" />
</EditItemTemplate>

När du har gjort dessa ändringar öppnar du sidan i en webbläsare. Om du försöker utelämna namnet eller ange ett ogiltigt prisvärde när du redigerar en produkt visas en asterisk bredvid textrutan. Som bild 5 visar anses ett prisvärde som innehåller valutasymbolen, till exempel 19,95 USD, vara ogiltigt. CompareValidator s CurrencyType tillåter sifferavgränsare (till exempel kommatecken eller perioder, beroende på kulturinställningarna) och ett inledande plus- eller minustecken, men tillåter inte en valutasymbol. Det här beteendet kan förbrylla användare eftersom redigeringsgränssnittet återger UnitPrice för närvarande i valutaformatet.

En Asterisk visas bredvid textrutorna med ogiltiga indata

Bild 5: En Asterisk visas bredvid textrutorna med ogiltiga indata (Klicka om du vill visa en bild i full storlek)

Även om valideringen fungerar as-ismåste användaren manuellt ta bort valutasymbolen när en post redigeras, vilket inte är acceptabelt. Om det finns ogiltiga indata i redigeringsgränssnittet kommer varken Uppdatera- eller Avbryt-knappen att utlösa en postback när de klickas på. Helst skulle knappen Avbryt returnera DataList till dess förredigeringstillstånd oavsett giltigheten för användarens indata. Vi måste också se till att sidans data är giltiga innan produktinformationen uppdateras i DataList-händelsehanteraren UpdateCommand , eftersom valideringskontrollernas logik på klientsidan kan kringgås av användare vars webbläsare antingen inte stöder JavaScript eller har dess stöd inaktiverat.

Ta bort valutasymbolen från textrutan EditItemTemplate s UnitPrice

När du använder CompareValidator får Currency``Typede indata som verifieras inte innehålla några valutasymboler. Förekomsten av sådana symboler gör att CompareValidator markerar indata som ogiltiga. Vårt redigeringsgränssnitt innehåller dock för närvarande en valutasymbol i UnitPrice textrutan, vilket innebär att användaren uttryckligen måste ta bort valutasymbolen innan de sparar sina ändringar. För att åtgärda detta har vi tre alternativ:

  1. EditItemTemplate Konfigurera så att UnitPrice TextBox-värdet inte formateras som en valuta.
  2. Tillåt användaren att ange en valutasymbol genom att ta bort CompareValidator och ersätta den med en RegularExpressionValidator som söker efter ett korrekt formaterat valutavärde. Utmaningen här är att det reguljära uttrycket för att verifiera ett valutavärde inte är lika enkelt som CompareValidator och skulle kräva att du skriver kod om vi vill införliva kulturinställningar.
  3. Ta bort verifieringskontrollen helt och hållet och förlita dig på anpassad valideringslogik på serversidan i GridView-händelsehanteraren RowUpdating .

Låt oss gå med alternativet 1 för den här självstudien. För närvarande är UnitPrice formaterad som ett valutavärde på grund av databindningsuttrycket för textrutan i EditItemTemplate: <%# Eval("UnitPrice", "{0:c}") %>. Ändra -instruktionen Eval till Eval("UnitPrice", "{0:n2}"), som formaterar resultatet som ett tal med två siffror med precision. Detta kan göras direkt via deklarativ syntax eller genom att klicka på länken Redigera DataBindings från textrutan UnitPrice i DataList s EditItemTemplate.

Med den här ändringen innehåller det formaterade priset i redigeringsgränssnittet kommatecken som gruppavgränsare och en period som decimalavgränsare, men lämnar valutasymbolen utanför.

Anmärkning

När du tar bort valutaformatet från det redigerbara gränssnittet tycker jag att det är bra att placera valutasymbolen som text utanför textrutan. Detta fungerar som ett tips till användaren om att de inte behöver ange valutasymbolen.

Åtgärda knappen Avbryt

Som standard genererar verifieringswebbkontrollerna JavaScript för att utföra validering på klientsidan. När en Knapp, LinkButton eller ImageButton klickas, kontrolleras verifieringskontrollerna på sidan på klientsidan innan återkopplingen sker. Om det finns ogiltiga data avbryts återanropet. För vissa knappar kan dock giltigheten av data vara oväsentlig. I sådana fall är det en olägenhet att postback avbryts på grund av ogiltiga data.

Knappen Avbryt är ett sådant exempel. Anta att en användare anger ogiltiga data, till exempel att utelämna produktens namn, och sedan bestämmer sig för att hon inte vill spara produkten trots allt och trycker på knappen Avbryt. Knappen Avbryt utlöser valideringskontrollerna på sidan, vilka rapporterar att produktnamnet saknas och hindrar postback. Vår användare måste skriva in text i ProductName textrutan bara för att avbryta redigeringsprocessen.

Lyckligtvis har Button, LinkButton och ImageButton en CausesValidation egenskap som kan indikera om klick på knappen ska initiera valideringslogiken (standardvärdet är True). Ange egenskapen Avbryt knapp CausesValidation till False.

Se till att indata är giltiga i UpdateCommand-händelsehanteraren

På grund av det skript på klientsidan som genereras av verifieringskontrollerna, om en användare anger ogiltiga indata, avbryter valideringskontrollerna eventuella postbacks som initierats av Button-, LinkButton- eller ImageButton-kontroller vars CausesValidation egenskaper är True (standard). Men om en användare besöker med en föråldrad webbläsare eller en vars JavaScript-stöd har inaktiverats, kommer verifieringskontrollerna på klientsidan inte att köras.

Alla ASP.NET-valideringskontroller upprepar sin valideringslogik omedelbart vid postback och rapporterar sidans datas övergripande giltighet via Page.IsValid-egenskapen. Sidflödet avbryts dock inte eller stoppas på något sätt baserat på värdet Page.IsValidför . Som utvecklare är det vårt ansvar att se till att Page.IsValid egenskapen har ett värde för True innan du fortsätter med kod som förutsätter giltiga indata.

Om en användare har JavaScript inaktiverat, besöker vår sida, redigerar en produkt, anger ett prisvärde för För dyrt och klickar på knappen Uppdatera, kringgås verifieringen på klientsidan och en postback kommer att uppstå. Vid postback körs ASP.NET-sidans UpdateCommand händelsehanterare och ett undantag genereras när du försöker parsa För dyrt för en Decimal. Eftersom vi har möjlighet till undantagshantering hanteras ett sådant undantag smidigt, men vi kan förhindra att ogiltiga data slinker igenom från början genom att endast fortsätta med UpdateCommand-händelsehanteraren om Page.IsValid har värdet True.

Lägg till följande kod i början av UpdateCommand händelsehanteraren, omedelbart före Try blocket:

if (!Page.IsValid)
    return;

Med det här tillägget försöker produkten endast uppdateras om de inskickade data är giltiga. De flesta användare kommer inte att kunna återställa ogiltiga data på grund av valideringskontrollernas skript på klientsidan, men användare vars webbläsare inte stöder JavaScript eller som har JavaScript-stöd inaktiverat, kan kringgå kontrollerna på klientsidan och skicka ogiltiga data.

Anmärkning

Den skicklige läsaren kommer ihåg att när vi uppdaterade data med GridView behövde vi inte uttryckligen kontrollera Page.IsValid egenskapen i kod-bakom klassen på vår sida. Det beror på att GridView konsulterar Page.IsValid egenskapen åt oss och endast fortsätter med uppdateringen om den returnerar värdet True.

Steg 3: Sammanfatta problem med datainmatning

Förutom de fem valideringskontrollerna innehåller ASP.NET kontrollen ValidationSummary, som visar s för ErrorMessage de valideringskontroller som identifierade ogiltiga data. Sammanfattningsdata kan visas som text på webbsidan eller via en modal meddelanderuta på klientsidan. Låt oss förbättra den här guiden så att den innehåller ett klientsidesmeddelande som sammanfattar eventuella valideringsproblem.

Det gör du genom att dra en ValidationSummary-kontroll från verktygslådan till designern. Platsen för kontrollen ValidationSummary spelar egentligen ingen roll, eftersom vi ska konfigurera den så att den endast visar sammanfattningen som en meddelanderuta. När du har lagt till kontrollen anger du dessShowSummary egenskap till False och dessShowMessageBox egenskap till True. Med det här tillägget sammanfattas eventuella valideringsfel i en meddelanderuta på klientsidan (se bild 6).

Valideringsfelen sammanfattas i en Client-Side meddelanderuta

Bild 6: Valideringsfelen sammanfattas i en Client-Side meddelanderuta (Klicka om du vill visa en bild i full storlek)

Sammanfattning

I den här självstudien såg vi hur du minskar sannolikheten för undantag genom att använda verifieringskontroller för att proaktivt se till att våra användares indata är giltiga innan de försöker använda dem i arbetsflödet för uppdatering. ASP.NET innehåller fem verifieringswebbkontroller som är utformade för att inspektera en viss webbkontrolls indata och rapportera tillbaka om indatans giltighet. I den här självstudien använde vi två av de fem kontrollerna RequiredFieldValidator och CompareValidator för att säkerställa att produktens namn angavs och att priset hade ett valutaformat med ett värde som är större än eller lika med noll.

Att lägga till valideringskontroller i DataLists redigeringsgränssnitt är lika enkelt som att dra dem till EditItemTemplate från verktygslådan och ange en handfull egenskaper. Som standard genererar valideringskontrollerna automatiskt valideringsskriptet på klientsidan. De tillhandahåller också validering på serversidan vid efteråterställning och lagrar det kumulativa resultatet i Page.IsValid egenskapen. Om du vill kringgå verifieringen på klientsidan när en Knapp, LinkButton eller ImageButton klickas ställer du in knappegenskapen CausesValidationFalse. Innan du utför någon uppgift med de data som skickas vid postback, kontrollera också att Page.IsValid-egenskapen returnerar True.

Alla datalistredigeringskurser som vi har undersökt hittills har haft mycket enkla redigeringsgränssnitt en TextBox för produktens namn och en annan för priset. Redigeringsgränssnittet kan dock innehålla en blandning av olika webbkontroller, till exempel listrutor, kalendrar, radioknappar, kryssrutor och så vidare. I nästa självstudie kommer vi att titta på hur du skapar ett gränssnitt som använder en mängd olika webbkontroller.

Lycka till med programmerandet!

Om författaren

Scott Mitchell, författare till sju ASP/ASP.NET-böcker och grundare av 4GuysFromRolla.com, har arbetat med Microsofts webbtekniker sedan 1998. Scott arbetar som oberoende konsult, tränare och författare. Hans senaste bok är Sams Teach Yourself ASP.NET 2.0 på 24 timmar. Han kan nås på mitchell@4GuysFromRolla.com.

Särskilt tack till

Den här självstudieserien granskades av många användbara granskare. Huvudgranskare av den här handledningen var Dennis Patterson, Ken Pespisa och Liz Shulok. Vill du granska mina kommande MSDN-artiklar? Om så är fallet, hör av dig på mitchell@4GuysFromRolla.com.