ASP.NET MVC - Modely a kontaktní formulář

C# .NET ASP.NET MVC ASP.NET MVC - Modely a kontaktní formulář

V tomto dílu si ukážeme jak vytvořit kontaktní formulář. Nejprve vytvoříme vlastní model, který obohatíme atributy. Nakonec si vysvětlíme co je to scaffolding a řekneme rozdíl mezi HTTP GET a HTTP POST metodami.

Pozn. pro začínající .NETaře ve VS: Když napíšete do kódu jméno nějaké třídy, nemusí být obsažena ve jmenném prostoru, který máte načtený. Když nemáte nějaký using, tak stačí napsat přesně název třídy, najet na něj myškou a přidat daný using pomocí ikony, která se v tu chvíli zobrazí. Nebo lepší metoda bez myšky je dát CTRL + . a dát enter. Ale to už je na vás, jak velcí kamarádi s Visual Studiem jste vy :) Píšu to proto, protože se nechci zdržovat u každého usingu, který musíte přidat.

Vytvoření projektu

Vytvoříme si tedy nový projekt typu ASP.NET MVC 4 Web Application, pojmenujeme ho MvcContactForm. Klikneme na OK a vybereme template (šablonu) projektu. Minule jsme měli Empty projekt, tak dneska vytvoříme Basic. View Engine necháme Razor a unit testy zatím nepotřebujeme. Můžeme tedy kliknout znovu na OK.

Vygeneroval se nám nový projekt. Je o něco rozsáhlejší než ten Empty, navíc obsahuje BundleConfig (vysvětlím v dalších dílech) a ve složce Content obsahuje už nějaké defaultní CSS + obrázky. Tento díl ale není o CSS, takže mi do něj nějak razantně zasahovat nebudeme. Hlavně se nám vygenerovaly scripty na validaci. Nakonec je tu navíc Shared složka, kde je layout stránky. S tím se pojí ještě _ViewStart soubor, o kterém si něco řekneme v dalších dílech.

Vytvoření kontroleru a pohledu

Přidáme si klasicky nějaký defaultní kontroler a k tomu pohled. Přidáme si tedy nový kontroler se jménem HomeController (pravým na složku Controllers -> Add -> Controller). Přejmenujte si jméno na HomeController a klikněte na Add.

Vygenerovala se nám Index metoda, takže si k ní přidáme pohled (pravým do kódu metody Index -> Add View). Necháme ho takhle a klikneme na Add. Nyní můžete spustit váš server (F5) a měla by na vás vykouknout stránka s Indexem. Zatím nic nového, že ?

web home/index

Vytvoření modelu

Vypneme Debugging a vytvoříme si náš první model. Bude to model, ve kterém by jsme chtěli převést informaci o tom, jak nás uživatel chtěl kontaktovat.

Klikneme tedy pravým na složku Models, klikneme pravým a dáme Add -> Class. Pojmenujeme jí jako ContactModel a klikneme na Add.

Nyní naší třídě (modelu) přidáme pár vlastností. Chtěl bych vědět jak se jmenuje, datum odeslání, email a text zprávy. Přidáme tedy tyto 4 vlastnosti. Pro kontrolu, kód vypadá takto:

public string Name { get; set; }
public DateTime Date { get; set; }
public string Email { get; set; }
public string Message { get; set; }

V našem HomeControlleru vytvoříme tedy metodu ContactForm, která nám vrátí pohled přesně pro tento model. Aby jsme nemuseli zbytečně psát různé textové pole, popisky a tlačítko na odeslání, tak si to necháme vygenerovat. Tomuto se říká scaffolding. Jednoduše přijdete, řeknete tady máš model, vygeneruj mi pro něj stránku, která bude editovat tyto údaje. To znamená, že vy ať vytvoříte jakýkoliv model, tak nemusíte psát žádný HTML kód! To je první výhoda, kterou jsem já zaznamenal. Abych vás jen neunavoval, tak si ukážeme, jak je to jednoduché. Abych nezapomněl. Metoda ContactForm v HomeControlleru bude vypadat takto:

public ActionResult ContactForm()
{
        return View();
}

To nám ale vytvoří jen prázdnou stránku, využijeme tedy scaffolding a vygenerujeme si formulář.

Teď k naší metodě přidáme i pohled. Zaškrtneme Create a strongly-typed view a v Model class vybereme ContactModel (MvcContactFor­m.Models) (Pozn.: Jestli ho tam nemáte, tak si rebuildněte váš projekt. Chybí tam, protože projekt jednoduše neví, že tam ten model je, zatím jste ho vytvořili na disku a objevil se v projektu, ale to je vše). Nakonec u Scaffold template vybereme Create a můžeme kliknout na Add.

Vygeneroval se nám HTML kód s pár kousky C# kódu v Razor syntaxi (všude kde je zavináč)

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>ContactModel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Date)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Date)
            @Html.ValidationMessageFor(model => model.Date)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Message)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Message)
            @Html.ValidationMessageFor(model => model.Message)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

Co jaký kód dělá vysvětlovat nebudu. Když si najedete myškou na danou metodu, tak je vysvětlená. Takže bych to jen zbytečně překládal, ale aby jste pochopili princip toho generování, tak se jednoduše vezme každá vlastnost a vygeneruje se label (popisek) pro danou vlastnost, dále se vygeneruje editor a vedle toho ještě validační hláška.

Přejdeme tedy na stránku

http://localhost:28573/home/contactform

(vy máte port jiný) a vidíme, že se nám vygeneroval formulář. Povšimněte si, že jsem nenapsal absolutně nic a mám fungující formulář (z části). Zkuste si vyplnit různá pole, některá nevyplnit a odeslat.

ukazka home/contactform

Všimli jste si, že se odeslal, i když jste třeba nevyplnili email a nic se nevalidovalo? Přidáme tedy atributy k našemu modelu.

public class ContactModel
{
        [Required]
        [MinLength(3)]
        public string Name { get; set; }

        [ScaffoldColumn(false)]
        public DateTime Date { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.MultilineText)]
        public string Message { get; set; }
}

Popis atributů :

[Required]  // Nám říká, že musí něco obsahovat ( != null)
[Required(ErrorMessage="Required")] // Nastaví, že nesmí být políčko prázdné i s chybovou hláškou (Změní tu defaultní na tu naši)
[MinLength(3)] // Minimálni délka 3
[ScaffoldColumn(false)] // Ignoruje scaffolding - negeneruje to pro ně pole (jsou skryté, jako třeba datum vytvoření
[DataType(DataType.EmailAddress)] // Požaduje emailovou adresu
[EmailAddress] // Jinačí zápis atributu o řádek výše
[DataType(DataType.MultilineText)] // Více řádkový textbox
[Range(1,500)] // Hodnota musí být mezi 1 a 500 (číselně)

Rebuildneme projekt a zkusme odeslat prázdné položky teď. Vygenerovaly se nám jQuery scripty, aby se náš kód zvalidoval a pak až odeslal. Takže by to nemělo být možné.

Validace v ASP.NET MVC

Doufám, že jste si všimli, že jsem vyplnil, že datum nebude vyplňovat uživatel. Takže buď si vyhledáte v ContactForm.cshtml kód pro datum a smažete (ta rychlejší varianta) a nebo celý soubor smažete a vytvoříme nový. Nebo si to vygenerujeme pokaždé pomocí Html.EditorForModel metody. Zkuste si schválně nechat ten starý a pod to napsat generovací metodu a uvidíte výsledek. (Nezapomeňte na to, že při vkládání kódu musíte napsat razor syntaxi - @ !!!)

Tohle řešení je dobré, když si hrajete s tím, co by měl model obsahovat, že tohle se vám nelíbí a tak dále. Když to už potom máte napojené na databázi, tak tam vzniknou menší problémy, které jdou ale elegantně vyřešit, takže se nebojte.

Zatím tedy umíme odeslat formulář, teď si ho vyzvedneme a zpracujeme.

Vytvoříme si tedy metodu se stejným názvem a jako parametr předáme náš model. Zeptáme se jestli je model validní a když ano, tak přesměrujeme uživatele na indexovou stránku. Jinak se vrátíme zpátky. Kód tedy bude vypadat takto.

public ActionResult ContactForm(ContactModel model)
{
        if (ModelState.IsValid)
        {
                // přidáme model do databáze
                return RedirectToAction("Index", "Home");
        }
        return View();
}

Když se teď pokusíte dostat na stránku, tak vám vyskočí chyba. Jestli se ptáte proč, tak máte 2 metody se stejným názvem. C# jednoduše neví jakou metodu má použít. Jestli znáte rozdíl mezi HTTP GET a HTTP POST, tak asi víte proč. Pro ostatní to jednoduše vysvětlím.

Vy, když požadujete po serveru zobrazit nějakou stránku, tak je to právě GET. Takže všechny metody mají atribut [HttpGet], ale je tam generovaný už implicitně. Pravý opak od toho je POST, to znamená, že vy něco (data) chcete odeslat serveru. Přidáme tedy atribut [HttpPost] před naší druhou metodu. Klidně si můžete přidat i [HttpGet] nad tu první :) Když teď odešlete validní data, přesměruje vás to na /home/index. Implementovat odeslání na server budeme v dalších dílech. Chtěl jsem v tomto díle probrat i layout (statickou část stránky), ale jsem omezený znaky, tak se máte alespoň na co těšit. Zdrojové kódy najdete pod článkem.


 

Stáhnout

Staženo 354x (12.4 MB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal Jan Vargovský
Avatar
Autor se věnuje vývoji enterprise softwaru v .NETu.

Jak se ti líbí článek?
Celkem (6 hlasů) :
4.54.54.54.54.5


 


Miniatura
Všechny články v sekci
Základy ASP.NET MVC

 

 

Komentáře
Zobrazit starší komentáře (14)

Avatar
Jan Vargovský
Redaktor
Avatar
Jan Vargovský:

Vždyť tu je od sdraca :)

 
Odpovědět 26.2.2014 23:32
Avatar
Tommy
Člen
Avatar
Odpovídá na Jan Vargovský
Tommy:

Mňa by len zaujímalo ako by si to napojil na Entity Framework. :) Mám pocit, že sa tu EF nejako obchádza.

 
Odpovědět 26.2.2014 23:35
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Tommy
Jan Vargovský:

Stáhl si ho do aplikace skrz NuGet. Pak jak máš modely, které chceš mít v DB tak si na ně uděláš context. Většinou NazevModeluContext a dědí z DbContextu (to už je třída z EntityFrameworku, který jsi stáhl, takže musíš přidat using), uděláš v té třídě vlastnost typu DbSet<NazevModelu> a už to jen využíváš v kontroleru tak, že si uděláš instanci na ten context a pak jen voláš nějaké DML na ten kontext (nezapomeň pokaždé změnit změny - metoda SaveChanges)

Toť vše :)

Editováno 27.2.2014 0:02
 
Odpovědět 27.2.2014 0:01
Avatar
Tommy
Člen
Avatar
Odpovídá na Jan Vargovský
Tommy:

S tým EF je to úplne elegantné riešenie. Krása! Už to len zautomatizovať.

Ja som mal iba jediný problém. A to je ten, že keď už som mal triedy pripravené a išiel vytvárať controller, tak som začal dostávať hlášky typu: "Unable to retrieve metadata for..."

Bolo to spôsobené tým, že som nainštaloval najnovšiu verziu EF, teda 6.0.2. Tá nie je ešte uspôsobená na scaffolding a stále ma niekam posielala. Odinštaloval som ju, resetol VS2010, nainštaloval EF verziu 5.0.0 a problém bol vyriešený.

 
Odpovědět 27.2.2014 12:02
Avatar
vajkuba1234
Člen
Avatar
vajkuba1234:

Ahoj, chtel jsem se zeptat, zda budou dalsi pokracovani ASP.NET MVC. Dekuji :)

Odpovědět 7.3.2014 3:18
No hope, no future, JUST WAR! For world peace Israel must be DESTROYED!
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na vajkuba1234
Jan Vargovský:

Je tu už hotový seriál od sdraca.

 
Odpovědět 7.3.2014 12:01
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na Jan Vargovský
vajkuba1234:

Hotový tutorial jsem našel pouze o Webforms, nikoliv o ASP.NET MVC. Je možné, že jsem se přehlédl? Pokud ano, mohl bych poprosit o link? Děkuji

Odpovědět 7.3.2014 16:22
No hope, no future, JUST WAR! For world peace Israel must be DESTROYED!
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na vajkuba1234
David Čápka:

ASP.NET MVC je teprve v přípravě.

Odpovědět  +1 7.3.2014 16:23
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
vajkuba1234
Člen
Avatar
Odpovědět 7.3.2014 16:28
No hope, no future, JUST WAR! For world peace Israel must be DESTROYED!
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na vajkuba1234
Jan Vargovský:

Ajo, já myslel, že už to je :) proto tu psal jeden o tom EF nademnou :D

 
Odpovědět 7.3.2014 16:53
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 24. Zobrazit vše