pondělí 26. prosince 2011

ASP.NET MVC3–Binding příklad

V tomto příspěvku popíši, jak namapovat data pomocí “nesouvislých indexů” – ony se ty anglické výrazy špatně překládají, respektive nejsem jazykový odborník.

Problém

Představte si, že máte k dispozici seznam telefonních čísle a jmen a chcete je zobrazit uživateli, který pomocí zaškrtávátka určí, které z nich chce vložit do svého seznamu kontaktů. Běžně se tento problém řeší tak, že se uvažuje, že každý záznam má své ID (identifkátor).
Ale zkusme vyřešit situaci, kdy prostě žádné ID není k dipozici a nebo ho použít nechceme, tedy třída vypadá takto:
  1. public class Contact
  2. {
  3.     public string Name { get; set; }
  4.     public string Phone { get; set; }
  5. }
Zdroj dat nám nahradí tento kód:
  1. public static IEnumerable<Contact> Get()
  2. {
  3.     return new Contact[] {
  4.         new Contact() {Name= "Pepa", Phone= "123456789"},
  5.         new Contact() {Name= "Petr", Phone=  "987654321"},
  6.         new Contact() {Name= "Lopuch", Phone= "456789123"}
  7.     }.AsEnumerable();
  8. }
Kontroler není složitý:

  1. public class HomeController : Controller
  2. {
  3.     [HttpGet]
  4.     public ActionResult Index()
  5.     {
  6.         return View(Contact.Get());
  7.     }
  8. }
A View Index pak vypadá takto:
  1. @model IEnumerable<Contact>
  2. @{
  3.     ViewBag.Title = "Index";
  4. }
  5. <h2>Import - contacts</h2>
  6.  
  7. @using (Html.BeginForm())
  8. {
  9.     foreach (var contact in Model)
  10.     {
  11.     <input type="checkbox" name="index" value="@contact.GetHashCode()" /> @string.Format("{0}-{1}", contact.Name, contact.Phone) <br />
  12.     <input type="hidden" name="@string.Format("[{0}].Name", contact.GetHashCode())" value="@contact.Name" />
  13.     <input type="hidden" name="@string.Format("[{0}].Phone", contact.GetHashCode())" value="@contact.Phone" />
  14.     }
  15.     <input type="submit" value="send" />
  16. }

Metoda kontrolleru, který bude zpracovávat přijímaná data, pak vypadá takto:
  1. [HttpPost]
  2. public ActionResult Index(Contact[] contacts)
  3. {
  4.     return View("IndexPosted", contacts);
  5. }

a ve View IndexPosted vypisujeme přijaté kontakty pomocí jednoduchého kódu:
  1. <h2>Posted contects</h2>
  2. @foreach (var contact in Model)
  3. {
  4.      @string.Format("{0}-{1}", contact.Name, contact.Phone) <br />
  5. }
A takto se to chová:
imagea po odeslání stlačením tlačítka Send: image

Závěr

Veškeré kouzlo spočívá v checkboxu pojmenovaném index. Hodnota checkboxu je na server odeslána pouze v případě, že je zaškrtnut. MVC3 framework na serveru se pak snaží vytvořit kolekci objektů třídy  Contact (viz cílová akce formuláře Index(Contact[]  contacts)) – a hodnutu index použivá pro nalezení hodnot jednotlivých objektů.
Samozřejmě by se dal tento jednoduchý příklad řešit i jinak, ale všimněte si některých výhod tohoto řešení:
  • uživateli neposíláme žádné ID a Hashcode, který ho do jisté míry nahrazuje, je naprosto umělá hodnota.
  • Metodu pro zpracování dat do formuláře můžeme použít i pro zpracování normálního formuláře
  • díky tomu, ze využíváme model zpracování MVC frameworku, došlo by i k oveření všech podmínek, které bychom pro model případně definovali.
Celý zdrojový kód projektu BindingExample je dostupný na CodePlex – ale prakticky vše je uvedeno v tomto článku.

Poznámka na konec – index se nemusí jmenovat jen index, ale můžeme používat i prefixů při řešení složitějších případů:

  1. @Html.CheckBox("phones.index", new { value = contact.GetHashCode() })
  2.     @Html.Hidden(string.Format("phones[{0}].Name", contact.GetHashCode()), contact.Name)

Žádné komentáře:

Okomentovat