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
Moderní platforma pro vytvoření vašeho nového webu – Wix.com.
Nyní už můžete mít web zdarma.
Vytvořte si vlastní webové stránky. Snadno, rychle a levně přes Saywebpage.com
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 507×

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 V přechodu na DVB-T2 tápou především senioři. Přeladit jim pomáhají vnoučata, zapojí se i stát

V přechodu na DVB-T2 tápou především senioři. Přeladit jim pomáhají vnoučata, zapojí se i stát

Už na konci měsíce může zůstat část Čechů bez televizního signálu. Vypínání stávající sítě začne již 27. listopadu v Praze a středních Čechách a do poloviny roku 2020 čeká přechod na nový standard pozemního digitálního televizního vysílání DVB-T2 celou republiku. K naladění nového televizního vysílání musí řada lidí nakoupit modernější zařízení, upravit antény nebo přejít na kabelové či internetové vysílání. 

Reklama
Reklama
Obrázek ke článku Zavádění Master Data Management v praxi

Zavádění Master Data Management v praxi

Předchozím článku jsme si vysvětlili, co jsou to Master Data, kdy je firma obvykle začíná řešit, v jakých krocích postupovat a jak nám může pomoci zvláštní nástroj pro evidenci Master dat. V tomto článku se podíváme na dvou příkladech, jak prakticky začít Master data řešit.

1. Nová Master Data, která potřebujeme někde spravovat
2. Zmapování existujících Master dat a určení jejich vlastníků

Obrázek ke článku 5 nesprávných důvodů, proč dělat vlastní mobilní aplikaci

5 nesprávných důvodů, proč dělat vlastní mobilní aplikaci

Myslíte si, že máte skvělý nápad na byznys apku a znáte všechno, co potřebujete? Možná vám vývoj software na míru rozmluví Vláďa Skoumal, z firmy studio SKOUMAL vyvijející mobilní aplikace 5.11. 2019 v 18:00 v Impact Hub Praha nebo tento jeho článek.


 

Obrázek ke článku Ericsson ConsumerLab Report: rozšířená realita je další úrovní gamingu

Ericsson ConsumerLab Report: rozšířená realita je další úrovní gamingu

Celkem 66 % uživatelů zajímá rozšířená realita v oblasti gamingu. Mezi nimi je i 35 % těch, kteří jinak hry nehrají.
Pro téměř 50 % respondentů by bylo zajímavé zapojení virtuální objektů do reálného světa. Objekty by zůstaly tam, kde je při hře „umístili“.
Až 43 % uživatelů láká využití rozšířené reality ve sportu

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