Forskarens svar i html. Beskrivning av Response-objektet. Fråga professor Markup
Översättning: Vlad Merzhevich
Alla vet väl om webbformulär? Vi sätter in en tagg, några, kanske, komplettera det hela med en knapp och du är klar.
Du vet inte hälften. HTML5 definierar över ett dussin nya fälttyper som du kan använda i dina formulär. Och när jag säger "använd", menar jag att de kan användas direkt - utan några jippon, hacks eller lösningar. Oroa dig inte för mycket, jag säger inte att alla dessa spännande nya funktioner faktiskt stöds i alla webbläsare. Absolut inte, jag menar inte med alla. I moderna webbläsare, ja, dina formulär visar allt de kan. Men i äldre webbläsare kommer dina formulär fortfarande att fungera, om än inte till sin fulla potential. Det vill säga, dessa funktioner försämras elegant i varje webbläsare. Även i IE6.
SnabbtextDvs. | Firefox | Safari | Krom | Opera | iPhone | Android |
- | 4.0+ | 4.0+ | 4.0+ | 11.0+ | 4.0+ | - |
Den första HTML5-förbättringen när det gäller formulär är möjligheten att ställa in snabbtext i inmatningsfältet. Denna text visas i inmatningsfältet om fältet är tomt och inte har fokus. Så fort du klickar i inmatningsfältet (eller navigerar till det via Tab) försvinner tipstexten.
Du har förmodligen sett uppmaningstexten förut. Till exempel, Mozilla Firefox innehåller tipstext i adressfält med inskriptionen "Sök i bokmärken och journal."
När du klickar på adressfältet försvinner tipstexten.
Så här kan du inkludera suggestiv text i dina formulär.
Webbläsare som inte stöder platshållarattributet ignorerar det helt enkelt. Ingen skada eller kränkning.
Fråga professor Markup☞ F. Kan jag använda HTML-uppmärkning för platshållarattributet? Jag vill infoga en bild eller kanske ändra färgerna.
S. Platshållarattributet kan bara innehålla text, ingen HTML-kod. Det finns dock speciella CSS-tillägg som låter dig ställa in textstilen i vissa webbläsare.
AutofokusfältDvs. | Firefox | Safari | Krom | Opera | iPhone | Android |
- | - | 4.0+ | 3.0+ | 10.0+ | - | - |
Webbplatser kan använda JavaScript för att automatiskt kvitto fokus i det första formulärfältet. Till exempel på huvudsidan Google.com Fältet för att ange sökord har autofokus. Även om detta är bekvämt för de flesta, kan det vara irriterande för avancerade användare och personer med särskilda behov. Om du trycker på blanksteg medan du väntar på att sidan ska rulla blir det ingen rullning eftersom fokus ligger på formulärets inmatningsfält (det kommer att skriva blanksteg i fältet istället för att rulla). Om du flyttar fokus till ett annat inmatningsfält medan sidan laddas, kan webbplatsens autofokusskript "hjälpsamt" flytta tillbaka fokus till det ursprungliga inmatningsfältet, vilket avbryter din skrivning och får dig att skriva på fel ställe.
Eftersom autofokus fungerar genom JavaScript kan det vara svårt att hantera dessa extrema fall och få alternativ för de människor som inte vill att en webbsida ska "stjäla" deras fokus.
För att lösa dessa problem introducerar HTML5 autofokusattributet för alla formulärelement. Autofokusattributet gör precis vad det låter som: så snart sidan laddas flyttar det fokus till det angivna fältet. Men eftersom detta bara är uppmärkning och inte ett skript, kommer beteendet att vara konsekvent på alla webbplatser. Dessutom kan webbläsartillverkare (eller tilläggsförfattare) erbjuda användare ett sätt att inaktivera autofokus.
Så här kan du ställa in ett formulärfält för autofokus.
Webbläsare som inte stöder autofokusattributet kommer att ignorera det.
Vad har hänt? Säg att du vill att autofokus ska fungera överallt, inte bara i snygga HTML5-webbläsare? Du kan lämna det aktuella skriptet med autofokus, gör bara två små ändringar:
- lägg till attributet autofokus till HTML-koden;
- Kontrollera om webbläsaren stöder autofokus-attributet, och om inte, kör ditt eget skript.
Autofokus med alternativ
if (!("autofokus" i document.createElement("input")) ) (
document.getElementById("q").focus();
}
Många webbsidor väntar på att window.onload ska avfyras och sätta fokus. Men window.onload-händelsen aktiveras inte förrän alla bilder har laddats. Om din sida har många bilder, kommer sådana naiva skript potentiellt att ändra fokus efter att användaren har börjat interagera med en annan del av din sida. Det är därför avancerade användare hatar autofokusskript.
Till exempel, i föregående avsnitt placerades autofokusskriptet omedelbart efter formulärfältet det refererade till. Detta optimal lösning, men det kan störa dina känslor att lägga ett block med JavaScript-kod i mitten av sidan (eller mer vardagligt, ditt system kanske inte är så flexibelt). Om du inte kan infoga ett skript i mitten av sidan bör du ställa in fokus via en anpassad händelse som $(document).ready() i jQuery istället för window.onload .
Autofokus via jQuery
$(document).ready(function() (
$("#q").focus();
}
});
Den anpassade händelsen jQuery aktiveras så snart DOM är tillgänglig - det vill säga den väntar på att sidtexten ska laddas, men väntar inte på att alla bilder ska laddas. Detta är inte det optimala tillvägagångssättet - om sidan är ovanligt stor eller nätverksanslutning långsamt kan användaren fortfarande interagera med sidan innan fokusskriptet körs. Men det är fortfarande mycket bättre än att vänta på att window.onload-händelsen ska hända.
Om du håller med och är villig att infoga ett skript med ett påstående i din sidas kod är detta en kompromiss som är mindre otäck än det första alternativet och bättre än det andra. Du kan använda anpassade händelser i jQuery för att ställa in dina egna händelser, säg autofocus_ready. Du kan sedan utlösa denna händelse manuellt så snart autofokusfältet blir tillgängligt. Tack till E.M. Shtenberg för att du lärde mig denna teknik.
Autofokus med alternativ anpassad händelse
$(document).bind("autofocus_ready", function() (
if (!("autofokus" i document.createElement("input"))) (
$("#q").focus();
}
});
$(dokument).trigger("autofokus_klar");
Denna lösning är optimal, precis som den första metoden. Fokus kommer att ställas in på formulärfältet så snart som tekniskt möjligt medan sidtexten fortfarande laddas. En del av applikationslogiken (fokus i formulärfältet) har flyttats från sidans brödtext till sektionen. Det här exemplet är baserat på jQuery, men konceptet med anpassade händelser är inte unikt för jQuery. Andra JavaScript-bibliotek som YUI och Dojo erbjuder liknande möjligheter.
Låt oss sammanfatta.
- Att ställa in fokus korrekt är viktigt.
- Om möjligt, låt webbläsaren använda autofokusattributet på fältet där du vill fokusera.
- Om du använder alternativ kod för äldre webbläsare, definiera stöd för autofokus-attributet så att skriptet endast körs i äldre webbläsare.
- Sätt fokus så tidigt som möjligt. Infoga fokusskriptet i koden omedelbart efter formulärfältet. Om detta inte stör dig, bädda in ett JavaScript-bibliotek som stöder anpassade händelser och höj händelsen i kod direkt efter formulärfältet. Om detta inte är möjligt, använd en händelse som $(document).ready() från jQuery.
- Under inga omständigheter bör du vänta på att window.onload ska få fokus.
I mer än ett decennium har formulär endast innehållit ett fåtal typer av fält. De vanligaste är följande.
Alla dessa fälttyper fungerar fortfarande i HTML5. Om du "uppgraderar till HTML5" (kanske genom att ändra !DOCTYPE ), behöver du inte göra en enda ändring i dina formulär. Yay för bakåtkompatibilitet!
HTML5 definierar dock 13 nya fälttyper och det finns ingen anledning att inte börja använda dem.
Den första av dessa nya typer av e-postadresser. Det ser ut ungefär så här.
Jag tänkte skriva en mening som började "på webbläsare som inte stöder type="email" ..." men slutade. Varför? Eftersom jag inte är säker på om webbläsare inte stöder type="email" . Alla webbläsare "support" type="email" . De kanske inte gör något speciellt, men webbläsare som inte känner igen type="email" kommer att behandla det som type="text" och återge det som ett vanligt textfält.
Jag kommer att betona hur viktigt detta är. Det finns miljontals formulär på Internet som ber dig att ange din e-postadress, och alla använder . Du ser en textruta, skriv in din e-postadress i den och det är allt. Och sedan kommer HTML5, som definierar type="email" . Blir webbläsare galen? Nej. Varje webbläsare på jorden behandlar det okända typens attribut som type="text" - även IE6. Så du kan "uppdatera" dina formulär med type="email" just nu.
Vad händer om vi säger att webbläsaren stöder type="email" ? Tja, det kan betyda vad som helst. HTML5-specifikationen kräver inget specifikt användargränssnitt för de nya fälttyperna. Opera lägger till en liten ikon i formulärfältet. Andra HTML5-webbläsare som Safari och Chrome återges som ett textfält - samma som type="text" - så att dina användare inte märker skillnaden (förrän de tittar på källkoden).
Och så är det iPhone.
iPhone har inget fysiskt tangentbord. All "skrivning" görs genom att klicka på tangentbordet på skärmen som dyker upp vid lämplig tidpunkt, till exempel när du går till ett formulärfält på en webbsida. Apple gjorde något smart iPhone webbläsare. Den känner igen några nya HTML5-fält och ändrar dynamiskt tangentbordet på skärmen för att optimera inmatningen.
Till exempel, en e-postadress är text, eller hur? Naturligtvis, men det här är en speciell typ av text. Så gott som alla e-postadresser innehåller @-symbolen och enl minst, en enda punkt (.), men det är osannolikt att de innehåller ett mellanslag. Så när du använder en iPhone och går till , får du ett tangentbord på skärmen som innehåller ett mindre mellanslagstangent samt dedikerade tangenter för symboler. Och @.
Låt mig sammanfatta det. Det finns ingen nackdel att omedelbart översätta alla dina fält från mejladresser i type="e-post" . Nästan ingen kommer att märka detta förutom iPhone-användare, som förmodligen inte kommer att märka det heller. Men de som märker det kommer att le tyst och tacka dig för att du gör deras jobb lite lättare.
WebbadresserEn webbadress – som standardiserar nördar som kallas URLs, förutom några få pedanter som kallade URIs – är en annan typ av specialiserad text. Syntaxen för en webbadress är begränsad till den relevanta internetstandarden. Om någon ber dig att ange en webbadress i ett formulär förväntar de sig något som "http://www.google.com/", inte "125 Farwood Road." Sned linjer är vanliga – även i startsida Google har tre av dem. Prickar är också vanliga, men utrymmen är förbjudna. Och varje webbadress har ett domänsuffix som ".com" eller ".org".
Och så... (trumrulle tack)... . På iPhone ser det ut så här.
iPhone har ändrat sin virtuellt tangentbord, precis som jag gjorde för en e-postadress, men nu optimerade den för att skriva en webbadress. Mellanslagstangenten har helt ersatts av tre virtuella nycklar: snedstreck, punkt och ".com" (du kan hålla ned ".com"-tangenten för att välja ett annat suffix som ".org" eller ".net").
Webbläsare som inte stöder HTML5 kommer att behandla type="url" som type="text" , så det finns ingen nackdel med att använda den här typen för alla fält där du behöver ange en webbadress.
Siffror som räknareNästa steg: siffror. Att begära ett nummer är mer komplicerat än att begära en e-post eller webbadress. För det första är siffror mer komplexa än du tror. Välj snabbt ett nummer. -1? Nej, jag menade ett tal mellan 1 och 10,7 ½? Nej, nej, var inte en bråkdel, dum. π? Nu valde du bara ett irrationellt tal.
Jag skulle vilja notera att du inte ofta får frågan "bara ett nummer." Det är mer troligt att de kommer att fråga efter ett nummer inom ett visst intervall. Du kanske bara vill ha vissa typer av tal inom detta intervall - kanske heltal, men inte bråk eller decimaltal eller något mer exotiskt, som multiplar av 10. HTML5 täcker allt.
Välj ett nummer, nästan vilket som helst
Låt oss titta på ett attribut i taget.
- type="number" betyder att detta är ett numeriskt fält.
- min="0" anger det lägsta tillåtna värdet för detta fält.
- max="10" är det högsta tillåtna värdet.
- step="2" i kombination med minimivärdet definierar de giltiga siffrorna i intervallet: 0, 2, 4 och så vidare, upp till det maximala värdet.
- värde="6" standardvärde. Borde se bekant ut, detta är samma attribut som alltid används för att definiera formulärfältsvärden. Jag nämner detta här som en utgångspunkt, som HTML5 bygger på tidigare versioner HTML. Du behöver inte lära dig om för att göra det du redan har gjort.
Detta är koden för ett numeriskt fält. Tänk på att alla dessa attribut är valfria. Om du har ett minimum men inte ett maximum kan du ange min-attributet men inte max-attributet. Standardstegvärdet är 1 och du kan utelämna stegattributet tills ett annat stegvärde behövs. Om det inte finns något standardvärde kan värdeattributet vara det tom rad eller till och med utelämnat helt.
Men HTML5 slutar inte där. För samma låga lågt pris friheten du får med dessa praktiska JavaScript-metoder.
- input.stepUp(n) ökar fältvärdet med n.
- input.stepDown(n) minskar fältvärdet med n.
- input.valueAsNumber returnerar det aktuella värdet som ett flyttal (egenskapen input.value är alltid en sträng).
Visningsproblem? Tja, det korrekta gränssnittet för att hantera nummer implementeras på olika sätt i webbläsare. På iPhone, där det är svårt att skriva, optimerar webbläsaren återigen det virtuella tangentbordet för att ange siffror.
I skrivbordsversionen av Opera visas fältet type="number" som en räknare med små upp- och nedpilar som du kan klicka på för att ändra värdena.
Opera respekterar min , max och steg attribut, så du kommer alltid att uppnå ett acceptabelt numeriskt värde. Om du ökar värdet till maximalt blir upp-pilen i räknaren grå.
Som med alla andra inmatningsfält som jag har diskuterat i det här kapitlet, kommer webbläsare som inte stöder type="number" att behandla det som type="text" . Standardvärdet kommer att visas i fältet (eftersom det lagras i värdeattributet), men andra attribut som min och max kommer att ignoreras. Du är fri att implementera dem själv eller använda ett JavaScript-ramverk som redan implementerar diskhantering. Kolla här först.
if (! .inputtypes.number) (
// inget inbyggt stöd för fälttyp=nummer
// kan prova Dojo eller ett annat JavaScript-ramverk
}
Räknaren är det inte det enda sättet. Du har säkert också sett en reglage som ser ut så här.
Nu kan du även ha en reglage på formuläret. Koden ser konstigt ut som ett räknarfält.
Alla tillgängliga attribut är desamma som för type="number" - min , max , step , value - och betyder samma sak. Den enda skillnaden är användargränssnitt. Istället för ett inmatningsfält förväntas webbläsare visa type="range" som ett skjutreglage. I skrivande stund senaste versionerna Safari, Chrome och Opera fungerade med detta. Tyvärr visas iPhone som en enkel textfält, den optimerar inte ens sitt tangentbord på skärmen för att ange siffror. Alla andra webbläsare behandlar helt enkelt fältet som type="text" , så det finns ingen anledning att börja använda den här typen omedelbart.
HTML 4 inkluderar inte datumval via kalender. JavaScript-ramverk låter dig komma runt detta (Dojo, jQuery UI, YUI, Closure Library), men naturligtvis kräver var och en av dessa lösningar att "implementera" ramverket för vilken inbyggd kalender som helst.
HTML5 definierar äntligen ett sätt att aktivera infödda datumväljare utan skript. Det finns faktiskt sex av dem: datum, månad, vecka, tid, datum + tid och datum + tid med tidszon.
Än så länge är stödet... ringa.
type="datum" | 9.0+ | - |
type="månad" | 9.0+ | - |
type="vecka" | 9.0+ | - |
type="tid" | 9.0+ | - |
type="datetime" | 9.0+ | - |
type="datetime-local" | 9.0+ | - |
Så här visas Opera:
Om du behöver tid tillsammans med datum, stöder Opera också:
Om du behöver en månad plus ett år (till exempel utgångsdatumet för ett kreditkort), kan Opera visa:
Mindre vanligt, men tillgängligt, är att välja veckan på året via:
Sist men inte minst är timingen med:
Datumväljare med alternativ
...
var i = document.createElement("input");
i.setAttribute("typ", "datum");
if (i.type == "text") (
// Inget stöd för inbyggt datumväljare :(
// Använd Dojo/jQueryUI/YUI/Closure för att skapa den,
// ersätt sedan elementet dynamiskt
}
Det är troligt att andra webbläsare så småningom kommer att stödja dessa typer. Precis som type="email" och andra typer kommer dessa formulärfält att visas som vanlig text i webbläsare som inte känner igen type="date" och dess varianter. Om du vill kan du bara använda , göra Opera-användare nöjda och vänta på att andra webbläsare kommer ikapp. Det är mer realistiskt att använda detta, men kontrollera om webbläsaren har inbyggt stöd för datumväljare, och inkludera en alternativ lösning i form av ett valfritt skript (Dojo, jQuery UI, YUI, Closure Library eller andra alternativ).
SökfönsterSå sök. Inte bara sökningar från Google eller Yahoo (ja, de också). Tänk på vilken sökruta som helst, på vilken sida som helst, på vilken webbplats som helst. Amazon har en sökruta, Yandex har en sökruta, de flesta bloggar har också. Hur är de gjorda? , precis som alla andra textfält på webben. Låt oss fixa det här.
Sök efter en ny generation
I vissa webbläsare kommer du inte att märka någon skillnad från ett vanligt textfält. Men om du använder Safari på Mac OS X kommer det att se ut så här.
Hittade du skillnaden? Inmatningsfältet har rundade hörn! Jag vet, jag vet, du kan knappt hålla tillbaka dina känslor. Men vänta, det finns mer! När du börjar skriva type="search" i fältet kommer Safari att infoga en liten "x"-knapp på höger sida av fönstret. Genom att klicka på "x" rensas innehållet i fältet. Google Chrome, som har samma teknik under huven, beter sig på samma sätt. Båda dessa små knep ser ut och beter sig på samma sätt som inbyggd sökning i iTunes och andra Mac OS X-klientprogram.
Apple.com använder webbplatssökning för att hjälpa webbplatsen att förmedla en "ara-älskande" känsla. Men det finns inget specifikt för Mac här. Det är bara kod, så varje webbläsare på varje plattform kan välja hur den ska renderas enligt plattformens konventioner. Som med alla andra nya typer kommer webbläsare som inte känner igen type="search" att behandla det som type="text" , så det finns absolut ingen anledning att inte börja använda type="search" för alla dina sökrutor idag .
säger professor MarkupSom standard tillämpar Safari inte de flesta stilar. Om du vill tvinga Safari att behandla sökfältet som ett vanligt textfält (så att du kan använda dina egna stilar), lägg till den här regeln i din stilmall.
inmatning(
-webkit-utseende:textfält;
}
Tack till John Lane för att du lärde mig detta trick.
FärgvalHTML5 definierar också ett fält som låter dig välja en färg och returnerar den i hexadecimal form. Ingen webbläsare stöder färgväljare, vilket är synd eftersom jag alltid har älskat Mac OS-paletter. Kanske en dag.
Notera översättare Opera 11 stöder denna funktion.
FormulärvalideringI det här kapitlet pratade jag om nya formulärelement och nya funktioner som autofokus, men jag nämnde inte den kanske mest spännande delen av HTML5-formulär: automatisk kontroll indata. Låt oss överväga vanliga problem ange din e-postadress i formuläret. Du har förmodligen validering på klientsidan genom JavaScript, följt av validering på serversidan genom PHP, Python eller något annat språk på serversidan. HTML5 kommer aldrig att ersätta validering på serversidan, men det kan en dag ersätta validering på klientsidan.
Det finns två stora problem med e-postadressvalidering i JavaScript:
Seriöst, du kommer att få fel adress. Att avgöra att en uppsättning slumpmässiga tecken är en giltig e-postadress är otroligt svårt. Ju hårdare du tittar, desto svårare blir det. Nämnde jag att det här är väldigt, väldigt svårt? Är det inte lättare att hänga denna huvudvärk på din webbläsare?
Opera kontrollerar type="email"
Här är en skärmdump från Opera 11, även om funktionaliteten har funnits sedan Opera 9. Koden går ut på att ställa in e-postvärdet för typattributet. När en Opera-användare försöker skicka ett formulär med , kontrollerar webbläsaren automatiskt e-postadressen, även om skript är inaktiverade.
HTML5 erbjuder även validering av webbadresser med fält och nummer med . Nummervalidering tar hänsyn till värdena för min- och max-attributen, så webbläsare tillåter dig inte att skicka in formuläret om du anger ett för stort tal.
Det finns ingen kod som möjliggör formulärvalidering i HTML5, det görs som standard. För att inaktivera validering, använd novalidate-attributet.
Testa mig inte
Webbläsare har varit långsamma med att inkludera stöd för formulärvalidering i HTML5. Firefox 4 kommer att ha fullt stöd. Tyvärr är Safari och Chrome endast delvis implementerade: de validerar formulärelement, men visar inga synliga meddelanden när ett formulärfält misslyckas med valideringen. Med andra ord, om du anger ett felaktigt (eller felstavat) datum i type="date" kommer Safari och Chrome inte att skicka in formuläret, men kommer inte att berätta varför det inte gjorde det. De kommer att sätta fokus på fältet som innehåller ett ogiltigt värde, men kommer inte att visa ett felmeddelande som Opera eller Firefox 4.
Obligatoriska fältDvs. | Firefox | Safari | Krom | Opera | iPhone | Android |
- | 4.0+ | - | - | 9.0+ | - | - |
Formulärvalidering i HTML5 är inte begränsad till typen av varje fält. Du kan också ange att vissa fält är obligatoriska, sådana fält måste ha ett värde innan du kan skicka in formuläret.
Koden för obligatoriska fält är så enkel som möjligt.
Webbläsare kan ändra det ursprungliga utseendet på ett obligatoriskt fält. Här är ett exempel på hur det ser ut i Mozilla Firefox 4.0.
Dessutom, om du försöker skicka ett formulär utan att fylla i ett obligatoriskt värde, visar Firefox ett informationsfält som säger att fältet är obligatoriskt och inte får vara tomt.
Genererar ett svar från styrenheter
Efter att kontrollanten har avslutat bearbetningen av begäran behöver den vanligtvis generera ett svar. När vi skapar en lågnivåkontroller genom att direkt implementera IController-gränssnittet, måste vi ta ansvar för varje aspekt av förfrågningsbehandling, inklusive att generera ett svar till klienten.
Till exempel, för att skicka ett HTML-svar, måste du skapa och komponera HTML-data och sedan skicka den till klienten med metoden Response.Write() . På samma sätt, för att omdirigera användarens webbläsare till en annan URL, måste du anropa metoden Response.Redirect() och skicka den nödvändiga URL:en. Båda tillvägagångssätten visas i koden nedan, som visar tillägg av BasicController-klassen som vi skapade i en tidigare artikel genom att implementera IController-gränssnittet:
Använder System.Web.Mvc; använder System.Web.Routing; namespace ControllersAndActions.Controllers ( public class BasicController: IController ( public void Execute(RequestContext requestContext) ( string controller = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData.Values "]; if (action.ToLower() == "redirect") ( requestContext.HttpContext.Response.Redirect("/Derived/Index"); ) else ( requestContext.HttpContext.Response.Write(string.Format("Controller : (0), Åtgärdsmetod: (1)", styrenhet, åtgärd)); ) ) ) )
Samma tillvägagångssätt kan tillämpas vid ärvning av en controller från Controller-klassen. Klassen HttpResponseBase, som returneras när egenskapen requestContext.HttpContext.Response läses i metoden Execute() är tillgänglig via egenskapen Controller.Response, som visas i exemplet nedan, som utökar klassen DerivedController, som också skapades tidigare av ärver från klassen Controller:
Använda System; använder System.Web; använder System.Web.Mvc; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public void ProduceOutput() ( if (Server.MachineName == "ProfessorWeb") Response.Redirect("/Basic/Index" ); else Response.Write("Controller: Derived, Action Method: ProduceOutput"); ) ) )
Metoden ProduceOutput() använder värdet för egenskapen Server.MachineName för att bestämma vilket svar som ska skickas till klienten. ("ProfessorWeb" är namnet på min utvecklingsmaskin.)
Även om detta tillvägagångssätt att generera ett svar till användaren fungerar, finns det flera problem med det:
Controllerklasser ska innehålla information om HTML-struktur eller URL, vilket gör klasser svåra att läsa och underhålla.
En styrenhet som genererar ett svar direkt på utsignalen är svår att enhetstesta. Du måste skapa skenimplementationer av Response-objektet och sedan kunna bearbeta utdata från styrenheten för att avgöra vad det är. Detta kan till exempel innebära behovet av att analysera HTML-uppmärkning till nyckelord, vilket är en lång och omständlig process.
Att bearbeta de små detaljerna i varje svar på detta sätt är komplext och felbenäget. Vissa programmerare gillar den absoluta kontrollen som tillhandahålls genom att bygga en lågnivåkontroller, men detta blir vanligtvis komplicerat mycket snabbt.
Lyckligtvis har MVC Framework ett praktiskt verktyg som löser alla dessa problem - resultatet av åtgärder. Följande avsnitt förklarar konceptet med handlingsresultat och visar olika sätt dess användning för att generera svar från styrenheter.
Resultat av åtgärderÅtgärdsresultat i MVC-ramverket används för att skilja avsiktsförklaringar från verkställande av avsikt (ursäkta tautologin). Konceptet kommer att verka enkelt när du väl fått kläm på det, men det tar lite tid att förstå på grund av viss indirekthet.
Istället för att ta itu direkt med ett Response-objekt, returnerar åtgärdsmetoder ett ActionResult-härlett klassobjekt som beskriver vad svaret från styrenheten ska vara – till exempel rendering av en vy eller omdirigering till en annan URL eller åtgärdsmetod. Men (detta är själva indirektheten) är svaret inte direkt genererat. Istället skapas ett ActionResult-objekt, som MVC Framework bearbetar för att producera resultatet efter att åtgärdsmetoden har anropats.
Ett åtgärdsresultatsystem är ett exempel på kommandodesignmönstret. Det här mönstret representerar scenarier där du lagrar och skickar objekt som beskriver de operationer som utförs.
När MVC Framework tar emot ett ActionResult-objekt från en åtgärdsmetod anropar det ExecuteResult()-metoden, definierad i klassen för detta objekt. Implementeringen av åtgärdsresultaten fungerar sedan på Response-objektet och genererar utdata som matchar din avsikt. För att demonstrera detta i praktiken, låt oss skapa en Infrastructure-mapp och lägga till en ny klassfil till den som heter CustomRedirectResult.cs med en anpassad ActionResult-implementering som visas i exemplet nedan:
Använder System.Web.Mvc; namespace ControllersAndActions.Infrastructure ( offentlig klass CustomRedirectResult: ActionResult ( public string URL ( get; set; ) public override void ExecuteResult(ControllerContext context) ( string fullUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext.Redirect.HttpContext); context.Redirect.HttpContext (full URL); ) ) )
Denna klass är baserad på hur klassen System.Web.Mvc.RedirectResult fungerar. En av fördelarna öppen källa MVC Framework handlar om att kunna utforska det inre av vad som helst. Klassen CustomRedirectResult är mycket enklare än dess MVC-motsvarighet, men är tillräcklig för syftet med denna artikel.
När vi instansierar klassen RedirectResult skickar vi in URL:en som användaren ska omdirigeras till. Metoden ExecuteResult(), som kommer att exekveras av MVC Framework när åtgärdsmetoden är klar, tar emot Response-objektet för begäran via Frameworks tillhandahållna ControllerContext-objekt och anropar antingen metoden RedirectPermanent() eller Redirect()-metoden (detta är exakt vad som gjordes i lågnivåimplementeringen av IController i exemplet tidigare i artikeln).
Användningen av klassen CustomRedirectResult illustreras i exemplet nedan, som visar ändringarna som gjordes i den härledda styrenheten:
// ... med ControllersAndActions.Infrastructure; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public ActionResult ProduceOutput() ( if (Server.MachineName == "MyMachineName") returnerar nytt CustomRedirectResult ( Url = "/Basic/ Index" ); else ( Response.Write("Controller: Derived, Action Method: ProduceOutput"); return null; ) ) ) )
Observera att vi var tvungna att ändra resultatet av åtgärdsmetoden för att returnera ActionResult. Vi returnerar null om vi inte vill att MVC Framework ska göra något när vår åtgärdsmetod körs, vilket är vad vi gjorde om CustomRedirectResult-instansen inte returnerades.
Enhetstestning av styrenheter och åtgärder
Många delar av MVC Framework är utformade för att göra enhetstester enklare, och detta gäller särskilt för åtgärder och kontroller. Det finns flera anledningar till detta stöd:
Du kan testa åtgärder och kontroller utanför webbservern. Kontextobjekt nås via sina basklasser (som HttpRequestBase), vilket är lätt att håna.
För att testa resultatet av en åtgärdsmetod behöver du inte analysera HTML-uppmärkningen. För att säkerställa att du får de förväntade resultaten kan du inspektera det returnerade ActionResult-objektet.
Emulering av klientförfrågningar behövs inte. MVC Frameworks modellbindningssystem låter dig skriva åtgärdsmetoder som tar emot indata i sina parametrar. För att testa en åtgärdsmetod anropar du den helt enkelt direkt och anger lämpliga parametervärden.
Framtida artiklar om att generera data från kontroller kommer att visa dig hur du skapar enhetstester för olika typer av åtgärdsresultat.
Glöm inte att enhetstestning bara är en del av bilden. Komplext beteende i en applikation uppstår när åtgärdsmetoder anropas sekventiellt. Enhetstestning fungerar bäst i kombination med andra testmetoder.
Nu när du vet hur det speciella resultatet av en omdirigeringsåtgärd fungerar kan du byta till dess motsvarighet som erbjuds av MVC-ramverket, som är mer kraftfullt och har testats grundligt av Microsoft. Den nödvändiga ändringen av den härledda styrenheten anges nedan:
// ... public ActionResult ProduceOutput() ( returnera nytt RedirectResult("/Basic/Index"); ) // ...
Det villkorliga uttalandet har tagits bort från åtgärdsmetoden, vilket innebär att efter att ha startat applikationen och navigerat till en URL som /Derived/ProduceOutput, kommer webbläsaren att omdirigeras till en URL som /Basic/Index. För att förenkla åtgärdsmetodkod innehåller klassen Controller bekvämlighetsmetoder för att generera olika typer av ActionResult-objekt. Så, till exempel, kan vi uppnå samma effekt som i exemplet ovan genom att returnera resultatet av metoden Redirect():
// ... public ActionResult ProduceOutput() ( return Redirect("/Basic/Index"); ) // ...
Det finns inget särskilt komplicerat med åtgärdsresultatsystemet, men det hjälper i slutändan till att producera enklare, renare, mer konsekvent kod som är lätt att läsa och enhetstesta. Till exempel, vid omdirigering kan du helt enkelt kontrollera att åtgärdsmetoden returnerar en RedirectResult-instans vars URL-egenskap innehåller det förväntade målet.
MVC-ramverket definierar många inbyggda åtgärdsresultattyper, som beskrivs i tabellen nedan:
Visa Resultat | Återger den angivna eller standardvymallen |
Se() |
PartialViewResult | Återger den angivna eller standardmallen för delvy |
PartialView() |
RedirectToRouteResult | frågor HTTP-omdirigering 301 eller 302 till en åtgärdsmetod eller specificerad ruttpost, genererar en URL enligt routingkonfigurationen |
RedirectToAction() RedirectToActionPermanent() RedirectToRoute() RedirectToRoutePermanent() |
RedirectResult | Utfärdar en HTTP 301 eller 302 omdirigering till den givna URL:en |
Dirigera om() RedirectPermanent() |
ContentResult | Returnerar oformaterad textdata till webbläsaren och ställer dessutom in rubriken för innehållstyp |
Innehåll() |
Filresultat | Överför binära data (som en fil på disk eller en byte-array i minnet) direkt till webbläsaren |
Fil() |
JsonResult | Serialiserar ett .NET-objekt till JSON-format och skickar det som ett svar. Svar av denna typ genereras oftare när du använder webb-API och AJAX-verktyg |
Json() |
JavaScriptResultat | Skickar en del av JavaScript-källkod som ska köras av webbläsaren |
JavaScript() |
HttpUnauthorizedResult | Ställer in HTTP-svarsstatuskoden till 401 (vilket betyder "ej auktoriserad"), vilket gör att autentiseringsmekanismen på plats (formulärautentisering eller Windows-autentisering) uppmanar besökaren att logga in |
Nej |
HttpNotFoundResult | Returnerar HTTP-fel med kod 404 - Hittade inte (hittades ej) |
HttpNotFound() |
HttpStatusCodeResult | Returnerar den angivna HTTP-koden |
Nej |
Tomt Resultat | Gör inget |
Nej |
Alla dessa typer härrör från ActionResult-klassen, och många av dem har praktiska hjälpmetoder i Controller-klassen. Vi kommer att visa användningen av dessa typer av resultat i efterföljande artiklar.
Det beskrivna objektet är ett mycket användbart och kraftfullt verktyg. Detta objekt har flera metoder, deras beskrivning ges nedan:
Samlingar: Metoder: Egenskaper: Response.Cookies samlingCookies-samlingen anger värden för cookies. Om de angivna kakorna inte finns skapas dem. Om kakan finns får den ett nytt värde och förstör det gamla.
Response.Cookies(cookie) [(nyckel) | . attribut ] = värde
Alternativ:
- cookie - Cookies namn
- nyckel - Valfri parameter. Om det anges är cookien en katalog (kapslad) och nyckeln är en uppsättning värden.
- attribut - Specificerad information om själva cookies. Denna parameter kan vara en av följande:
- värde - Anger värdet som ska tilldelas denna nyckel eller attribut.
namn | Beskrivning |
Domän | Endast inspelning. Om det anges skickas cookies endast på begäran från denna domän. |
Upphör att gälla | Endast inspelning. Datumet då cookien upphör. Detta datum måste anges för att cookies ska kunna skrivas till klienten HDD efter sessionens slut. Om detta attribut inte är inställt, antas cookiens utgångsdatum dagens datum. Cookies kommer att förfalla omedelbart efter slutet av sessionen. |
HasKey | Bara läsning. Indikerar om cookien innehåller den givna nyckeln. |
Väg | Endast inspelning. Om det anges skickas cookies endast på begäran från denna sökväg. Om parametern inte är inställd används sökvägen till applikationen. |
Säkra | Endast inspelning. Indikerar om cookies kommer att skyddas eller inte. |
Kommentar:
Om nyckelcookien skapas som visas i följande skript,
då kommer följande rubrik att skickas:
Set-Cookie:MYCOOKIE=TYPE1=socker&TYPE2=cookies
Om du tilldelar ett värde till mycookie utan att använda nycklar, kommer denna åtgärd att förstöra nycklar typ1 och typ2. T.ex:
I det föregående exemplet kommer nycklarna typ1 och typ2 att förstöras och deras värden kommer att gå förlorade. Mycookie kommer nu att innehålla värdet chokladmarshmallow.
Du kan också kontrollera att det finns en specifik nyckel på följande sätt:
Om TRUE visas, så finns en sådan nyckel, om FALSE, inte.
Response.Write metodSvar.Skriv variabel_eller_värde
Alternativ:
- variabel_eller_värde - Data som ska visas på webbläsarens skärm via HTML. Denna parameter kan vara av vilken typ som helst som stöds av VisualBasic Scripting Edition. Det vill säga, data kan vara av följande typer: datum, sträng, tecken, numeriska värden. Menande denna parameter kan inte innehålla %> kombinationer. Istället kan du använda motsvarande kombination %\>. Webbservern kommer att konvertera denna sekvens till den nödvändiga när skriptet körs.
Följande exempel visar hur metoden Response.write fungerar för att mata ut ett meddelande till klienten.
Jag ska bara säga dig: Och ditt namn
Följande exempel lägger till en HTML-tagg på en webbsida. Eftersom denna metod inte kan innehålla kombinationen %> använder vi sekvensen %\>. Så ett exempelskript:
Utgången blir raden: