ASP.NET MVC v praxi od A do Z, 7. díl – CRUD II. část
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

ASP.NET MVC v praxi od A do Z, 7. díl – CRUD II. částASP.NET MVC v praxi od A do Z, 7. díl – CRUD II. část

 
Hledat
Vybavení pro Laser Game
Spuštěn Filmový magazín
Laser Game Brno
Laser Game Ostrava

ASP.NET MVC v praxi od A do Z, 7. díl – CRUD II. část

Google       Google       31. 8. 2009       15 900×

Jak jsme si posledně slíbili, dnes doděláme podporu pro přidávání a mazání večeří.

Reklama
Reklama

Začneme vytvořením podpory pro přidávání večeří a s tím související akční metodou Create.

Akční metoda Create

HTTP-GET

Nejdříve vytvoříme GET verzi naší nové metody, která se zavolá tehdy, když uživatel zadá URL „/Dinners/Create“, a vygeneruje formulář pro přidání nové večeře. Není tady moc co řešit, vše potřebné už umíme, takže do DinnersControlleru jen přidáme následující metodu:

// GET: /Dinners/Create
public ActionResult Create()
{
    Dinner dinner = new Dinner()
    {
        EventDate = DateTime.Now.AddDays(7)
    };

    return View(dinner);
}

Tato metoda vytvoří nový Dinner objekt s předem nastaveným časem konání večeře (to aby měl uživatel představu, v jakém formátu má datum zadat) a pak vrátí view, který teď přidáme.

Už tradičně klikneme pravým tlačítkem dovnitř metody, zvolíme položku „Add View“ a dialog nastavíme podle obrázku:

Vygenerovanou šablonu rovnou upravíme tak, aby vypadala následovně (je téměř identická s tou, kterou jsme vytvořili pro upravování večeří):

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Models.Dinner>" %>

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
     Vytvořit večeři
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Vytvořit večeři</h2>

    <%=Html.ValidationSummary("Opravte prosím všechny chyby a zkuste to znovu.") %>
 
    <% using (Html.BeginForm()) {%>
  
        <fieldset>
            <p>
                <label for="Title">Název:</label>
                <%= Html.TextBox("Title") %>
                <%= Html.ValidationMessage("Title", "*") %>
            </p>
            <p>
                <label for="EventDate">Datum:</label>
                <%=Html.TextBox("EventDate") %>
                <%=Html.ValidationMessage("EventDate", "*") %>
            </p>
            <p>
                <label for="Description">Popis:</label>
                <%=Html.TextArea("Description") %>
                <%=Html.ValidationMessage("Description", "*") %>
            </p>
            <p>
                <label for="Address">Adresa:</label>
                <%=Html.TextBox("Address") %>
                <%=Html.ValidationMessage("Address", "*") %>
            </p>
            <p>
                <label for="Country">Země:</label>
                <%=Html.TextBox("Country") %>
                <%=Html.ValidationMessage("Country", "*") %>
            </p>
            <p>
                <label for="ContactPhone">Telefon:</label>
                <%=Html.TextBox("ContactPhone") %>
                <%=Html.ValidationMessage("ContactPhone", "*") %>
            </p>            
            <p>
                <label for="Latitude">Zem. šířka:</label>
                <%=Html.TextBox("Latitude") %>
                <%=Html.ValidationMessage("Latitude", "*") %>
            </p>
            <p>
                <label for="Longitude">Zem. délka:</label>
                <%=Html.TextBox("Longitude") %>
                <%=Html.ValidationMessage("Longitude", "*") %>
            </p>
            <p>
                <input type="submit" value="Uložit"/>
            </p>
        </fieldset>
    <% } 
%>
</asp:Content>

A je to, během pár minut jsme vytvořili šablonu pro přidávání nových večeří! Teď je na řadě vytvořit POST verzi metody Create.

HTTP-POST

Tato verze metody Create se zavolá ve chvíli, kdy uživatel klikne na tlačítko „Uložit“ ve formuláři. Stejně jako v případě upravování večeří, i zde nejdříve přidáme přetíženou verzi akční metody Create označenou atributem „AcceptVerbs“:

// POST: /Dinners/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Dinner dinner)
{
    // ...
}

Tím, že tato metoda přijímá Dinner parametr, docílíme toho, že ASP.NET MVC automaticky vezme zadaná data ve formuláři, vytvoří objekt typu Dinner a ten předá naší metodě, která ho zkontroluje a, pokud bude vše v pořádku, uloží do databáze. Implementace metody bude vypadat takto:

// POST: /Dinners/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Dinner dinner)
{
    if (ModelState.IsValid)
    {
        try
        {
            dinner.HostedBy = "Někdo";

            dinnerRepository.Add(dinner);
            dinnerRepository.Save();

            return RedirectToAction("Details", new { id = dinner.DinnerID });
        }
        catch
        {
            ModelState.AddRuleViolations(dinner.GetRuleViolations());
        }
    }

    return View(dinner);
}

Abychom viděli, jak to funguje, aplikaci spustíme a zadáme URL „/Dinners/Create“:

Všimněte si, že naše už dávno vytvořená validační logika funguje bezchybně i během vytváření večeří. Pořadatele večeře (vlastnost HostedBy) nastavujeme natvrdo v kódu, protože v budoucnu se budou moci uživatelé registrovat a jméno se bude doplňovat dynamicky podle právě přihlášeného uživatele.

Když opravíme všechny chyby a klikneme na tlačítko „Uložit“, vše by mělo proběhnout v pořádku a aplikace nás přesměruje na stránku s detaily nové večeře.

Akční metoda Delete

Díky této metodě, jak už název napovídá, budeme moci večeře mazat. Nejdříve implementujeme HTTP-GET, pak HTTP-POST.

HTTP-GET

Tato verze metody se zavolá, když uživatel zadá URL „/Dinners/Delete/{id}“, implementace bude vypadat takto:

// GET: /Dinners/Delete/1
public ActionResult Delete(int id)
{
    Dinner dinner = dinnerRepository.GetDinner(id);

    if (dinner == null)
        return View("NotFound");
    else
        return View(dinner);
}

Pokud nebude večeře, kterou chceme smazat, existovat, použijeme NotFound view, v opačném případě se použije Delete view, který teď vytvoříme. Tento krok děláme asi posté – jednoduše klikneme dovnitř metody Delete, zvolíme „Add View“ a dialog nastavíme podle obrázku:

Vytvoří se nám téměř prázdná šablona, kterou trochu doplníme, abychom dostali něco takového, jako ukazuje následující kód:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Models.Dinner>" %>

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Potvrzení smazání:  <%=Html.Encode(Model.Title) %>
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>
        Potvrzení smazání
    </h2>

    <div>
        <p>Skutečně chcete smazat večeři s názvem: 
           <i> <%=Html.Encode(Model.Title) %>? </i> 
        </p>
    </div>
    
    <% using (Html.BeginForm()) {  %>
        <input name="confirmButton" type="submit" value="Smazat" />        
    <% } %>
     
</asp:Content>

Hned to můžeme na nějaké večeři vyzkoušet (URL ve tvaru „/Dinners/Delete/{id}“):

HTTP-POST

Teď máme stránku, která zobrazuje potvrzení ke smazání. Když uživatel klikne na tlačítko „Smazat“, zavolá se POST verze naší metody, to už teď jistě víte. Proto tuto přetíženou metodu hned vytvoříme, bude to opět záležitost minutky. Implementace je jednoduchá, zase vše zařídí repository třída, kterou jsme si kdysi napsali:

// POST: /Dinners/Delete/1
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int id, string confirmButton)
{

    Dinner dinner = dinnerRepository.GetDinner(id);

    if (dinner == null)
        return View("NotFound");

    dinnerRepository.Delete(dinner);
    dinnerRepository.Save();

    return View("Deleted");
}

Budeme potřebovat vytvořit nový view, který zobrazí zprávu o tom, že smazání proběhlo úspěšně. Klikneme dovnitř metody pravým tlačítkem a zvolíme „Add View“ (jaké to překvapení). Ovšem je tady malá změna, nic nebudeme nastavovat, políčko „Create a strongly-typed view“ by mělo být odškrtlé. Jen přejmenujeme šablonu na „Deleted“ a klikneme na tlačítko „Add“. Teď do šablony přidáme takovéto HTML:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Večeře smazána
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Večeře smazána</h2>

    <div>
        <p>Večeře byla úspěšně smazána.</p>
    </div>
    
    <div>
        <p><a href="/dinners">Klikněte pro zobrazení chystaných večeří</a></p>
    </div>
    
</asp:Content>

Když teď večeři smažeme, všechno proběhne v pořádku:

Bezpečnost při databindingu

Ukázali jsme si, jak je pomocí metody UpdateModel snadné automaticky vytáhnout zadaná data z formuláře a vytvořit pomocí nich nový Dinner objekt. Stejně jako spousta dalších věcí ve webovém programování, i toto přináší určitá rizika – uživatel ani náhodou nesmí být schopný upravit kolekci RSVPs (v ní budou uloženi uživatelé přihlášení k večeřím), nesmí ani moci upravit vlastnosti DinnerID nebo HostedBy. Zamezíme tomu tím, že třídu Dinner odekorujeme atributem Bind, ve kterém explicitně definujeme vlastnosti, které mají být zahrnuty v databindingu:

[Bind(Include = "Title,Description,EventDate,Address,Country,ContactPhone,Latitude,Longitude")]
public partial class Dinner
{ //...

CRUD je hotov!

Gratuluji, že jste to zvládli až sem, CRUD máme hotový. Naše aplikace tedy podporuje čtení, vytváření, mazání i upravování večeří. Ukažme si ještě zdrojový kód kompletního DinnersControlleru a na shledanou u příštího dílu, ve kterém si povíme o třídách ViewData a ViewModel.

using System;
using System.Linq;
using System.Web.Mvc;
using NerdDinner.Models;

namespace NerdDinner.Controllers
{
    public class DinnersController : Controller
    {
        DinnerRepository dinnerRepository = new DinnerRepository();

        // GET: /Dinners/
        public ActionResult Index()
        {
            var dinners = dinnerRepository.FindUpcomingDinners().ToList();
            return View(dinners);
        }

        // GET: /Dinners/Details/2
        public ActionResult Details(int id)
        {
            Dinner dinner = dinnerRepository.GetDinner(id);

            if (dinner == null)
                return View("NotFound");
            else
            {
                return View(dinner);
            }
        }

        // GET: /Dinners/Edit/2
        public ActionResult Edit(int id)
        {
            Dinner dinner = dinnerRepository.GetDinner(id);
            return View(dinner);
        }

        // POST: /Dinners/Edit/2
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, FormCollection formValues)
        {
            Dinner dinner = dinnerRepository.GetDinner(id);
            try
            {
                UpdateModel(dinner);
                dinnerRepository.Save();

                return RedirectToAction("Details", new {id = dinner.DinnerID});
            }
            catch
            {
                ModelState.AddRuleViolations(dinner.GetRuleViolations());

                return View(dinner);
            }
        }

        // GET: /Dinners/Create
        public ActionResult Create()
        {
            Dinner dinner = new Dinner()
            {
                EventDate = DateTime.Now.AddDays(7)
            };

            return View(dinner);
        }

        // POST: /Dinners/Create
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Dinner dinner)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    dinner.HostedBy = "Někdo";

                    dinnerRepository.Add(dinner);
                    dinnerRepository.Save();

                    return RedirectToAction("Details", new { id = dinner.DinnerID });
                }
                catch
                {
                    ModelState.AddRuleViolations(dinner.GetRuleViolations());
                }
            }

            return View(dinner);
        }

        // GET: /Dinners/Delete/1
        public ActionResult Delete(int id)
        {
            Dinner dinner = dinnerRepository.GetDinner(id);

            if (dinner == null)
                return View("NotFound");
            else
                return View(dinner);
        }

        // POST: /Dinners/Delete/1
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id, string confirmButton)
        {

            Dinner dinner = dinnerRepository.GetDinner(id);

            if (dinner == null)
                return View("NotFound");

            dinnerRepository.Delete(dinner);
            dinnerRepository.Save();

            return View("Deleted");
        }
    }
}
Zdroj: http://nerddinnerbook.s3.amazonaws.com/Part5.htm

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

2 názory  —  2 nové  
Hlasování bylo ukončeno    
0 hlasů
Google
Jakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku Konference: Moderní informační systémy podporují automatizaci

Konference: Moderní informační systémy podporují automatizaci

Současná situace v šíření onemocnění Covid-19 klade na řadu firem nové nároky a mnohé z nich jsou nyní více než kdy jindy závislé na nejmodernějších informačních technologiích. Proto i v oblasti podnikových informačních systémů vidíme rostoucí důraz na automatizaci nebo na důslednou integraci. Také o těchto trendech se bude mluvit na konferenci Firemní informační systémy, která se koná 24.9.2020 v pražském Kongresovém centru Vavruška na Karlově náměstí.

Reklama
Reklama
Obrázek ke článku Nebezpečí ukrytá v USB: z nuly na škvarek za pět sekund

Nebezpečí ukrytá v USB: z nuly na škvarek za pět sekund

Za cenu šesti dolarů lze celkem bez obtíží koupit nový, líbivě vyhlížející flash disk. Přidaná hodnota, které se vám spolu s ním dostane, už tak moc líbivá není. To, co se před pár sekundami tvářilo jako externí disk, se po připojení k počítači změní v důmyslné elektrické křeslo, které vaše zařízení v onen příslovečný škvarek promění za pár sekund. Cílovou skupinou pro koupi takových zařízení by mohli být záškodníci, kteří by tímto způsobem osnovali pomstu třeba vůči záletnému partnerovi. 

Obrázek ke článku Znalosti, dovednosti i prestižní titul MBA: Jde to i moderně a online

Znalosti, dovednosti i prestižní titul MBA: Jde to i moderně a online

Snad nikdy není špatná příležitost na investici do hodnotného vzdělání. Obzvlášť v případě, že absolvent dovede teoretické poznatky přetavit v praktické dovednosti, využitelné při řešení problémů i v komunikaci. Právě na to se specializuje studijní program MBA Řízení informačních technologií, vyučovaný na Business Institutu.

Obrázek ke článku Coding Bootcamp Praha: Obor IT krize nepoznamenala, žádaní jsou weboví vývojáři

Coding Bootcamp Praha: Obor IT krize nepoznamenala, žádaní jsou weboví vývojáři

Pandemie Covid-19 otřásla trhem práce v základech. Dopady krize pocítilo celkově až 45 % zaměstnanců. Není divu, že čím dál větší jistotu přináší obor IT. Ten zůstal krizí téměř nepoznamenán a při nutnosti začít dělat věci na dálku se ještě více ukázalo, jak moc mnohé firmy kvalitní IT potřebují. Do IT nyní přicházejí začátečníci, kteří v něm vidí lukrativní budoucnost a jistotu, ale i freelanceři a zaměstnanci z oborů zasažených krizí

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032020 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý