Ne, tenhle článek nebude o sběratelích známek. Ale o epidemii, která postupně zachvacuje Evropu a která nutí postižené kupovat a vylepovat známky. Abych byl přesnější, dálniční a eko známky. Pokud bydlíte v Brně a chcete jet do Bratislavy, tak potřebujete českou a slovenskou dálniční nálepku. Pokud do Vídně, tak českou a rakouskou nálepku. Pokud se pustíte dál, tak slovinskou nálepku - a pravděpodobně rovnou dvě (díky jejich časové platnosti). Když chcete vjet do některých měst v Německu, musíte mít jejich eko nálepku. Od roku 2016 nás to má čekat i v Praze. Řidiči užitkových vozů si musí připravit €25 za eko nálepku do rakouských měst už nyní.
čtvrtek 8. ledna 2015
středa 7. ledna 2015
Validace v ASP.NET MVC poprvé a snadno
Validace v ASP.NET MVC je prý snadná - stačí ve ViewModelu použít příslušné atributy a je to - hned se provádí klientská i serverová aplikace. Jenže praxe až tak snadná není. Pokusím se popsat vývoj jedné malé aplikace.
sobota 27. prosince 2014
ASP.NET Binding kolekcí po třetí
View modely, které obsahují kolekce objektů, s sebou nesou obvykle nutnost testovat kolekci na na null hodnotu. Což není příjemné, komplikuje to kód a ten je i méně čitelný. V tomto posledním příspěvku věnovaného kolekcím v ASP.NET MVC popíši jedno z možných řešení.
čtvrtek 25. prosince 2014
Plánování cest
V jednom ze starších příspěvků jsem popsal, jak lze dnes snadno strávit a naplánovat dovolenou bez nutnosti cestovní kanceláře. Dnes popíšu, jak si zhruba připravuji plán na kratší dovolené:
ASP.NET MVC Binding podruhé
V minulém příspěvku jsem ukázal, jak navázat objekt s více jak jednou vlastností na ovládací prvek. Nyní popíši obrácený přístup, kdy je jedna vlastnost navázaná na dva ovládací prvky. Lze to řešit několika možnými způsoby, takže můj přístup určitě není jediný možný.
středa 24. prosince 2014
ASP.NET MVC Binding - kolekce
K ASP.NET MVC přistupují někteří vývojáři jako k zázračnému blackboxu, ze kterého vypadávají výsledky tak nějak sami, pokud ovšem nechceme dělat něco neobvyklého a který se někdy chová nevyzpytatelně. Přitom tato technologie není nijak složitá, je dobře promyšlená a umožňuje dělat téměř vše, co chceme. Jednou z prvních oblastí je binding - tedy naplnění vstupních objektů Action metody controlleru a to ze zdrojů hodnot. Zdrojů hodnot je několik (a je možné si napsat další), ale nejdůležitějším a nejpoužívanějším je FormValueProvider - tedy využíti hodnot zaslaného formuláře
Naplnění kolekcí
Nejlépe se jakékoliv plnění popisuje tak, že se ukáže, co je na vstupu a co z toho výchozí nastavení MVC udělá. Prvním předpokladem, aby se název vstupní hodnoty shodoval s názvem objektu či vlastnosti, kterou chceme plnit.
Například zde máme view, které zobrazuje seznam jmen, z nichž se může žádné a nebo všechna vybrat:
@{
IEnumerable<string> names = new[] { "Martin", "Jakub", "Jan" };
}
@using (Html.BeginForm())
{
foreach (var name in names)
{
<input type="checkbox" value="@name" name="names" />@name<br/>
}
<input type="submit" />
}
IEnumerable<string> names = new[] { "Martin", "Jakub", "Jan" };
}
@using (Html.BeginForm())
{
foreach (var name in names)
{
<input type="checkbox" value="@name" name="names" />@name<br/>
}
<input type="submit" />
}
Tato action metoda však bude obsahovat prázdnou kolekci, neboť v požadavku byly z prohlížeče poslány obsahy prvku names a tedy výchozí MVC binder neví, že mají naplnit vstupní parametr authors:
[HttpPost]
public ActionResult Index(List<string> authors)
{
return View();
}
public ActionResult Index(List<string> authors)
{
return View();
}
Stačí však přejmenovat authors na names a vstupní kolekce je naplněna korektně:
[HttpPost]
public ActionResult Index(List<string> names)
{
return View();
}
public ActionResult Index(List<string> names)
{
return View();
}
Přitom nezáleží na velikosti písmen, může se napsat nAmES a i tak se kolekce naplní - zkrátka to není case sensitive.
A jaký má být vstupní typ objektu? Takový, jaký potřebujeme, tedy v případě kolekcí a výše uvedeného případu může vypadat například takto:
- List<string> names
- IEnumerable<string> names
- string[] names
a nebo pokud to mám podat obecně, jakýkoliv typ IEnumerable<T>, ICollection<T>, IList<T>, T[], Collection<T> a List<T>.
Kolekce objektů
jak je vidět, binding do kolekcí s jednoduchým typem funguje bez problému. Co ale v případě, že máme objekty následující třídy (tedy bez nějaké jednoznačné hodnoty):
public class Person
{
public string FirstName { get; set; }
public string LastName {get;set;}
}
{
public string FirstName { get; set; }
public string LastName {get;set;}
}
Checkbox má jen jednu hodnotu a jak tedy přimět binder, aby tuto hodnotu nějak použil na vlastnosti? Můžeme si sice napsat vlastní binder a nějak to udělat, ale takové řešení není elegantní. Jde to ale takto:
@{
IEnumerable<Person> persons = new[] {
new Person{FirstName ="Martin", LastName="Strimpfl"},
new Person{FirstName = "Jakub", LastName="Strimpfl"},
new Person{FirstName = "Jan", LastName = "Strimpfl"}
};
}
@using (Html.BeginForm())
{
foreach (var person in persons)
{
var index = Guid.NewGuid().ToString();
<input type="checkbox" value="@index" name="persons.index" />@person.FirstName@: @person.LastName<br />
<input type="hidden" value="@person.FirstName" name="persons[@index].FirstName" />
<input type="hidden" value="@person.LastName" name="persons[@index].LastName" />
}
<input type="submit" />
}
IEnumerable<Person> persons = new[] {
new Person{FirstName ="Martin", LastName="Strimpfl"},
new Person{FirstName = "Jakub", LastName="Strimpfl"},
new Person{FirstName = "Jan", LastName = "Strimpfl"}
};
}
@using (Html.BeginForm())
{
foreach (var person in persons)
{
var index = Guid.NewGuid().ToString();
<input type="checkbox" value="@index" name="persons.index" />@person.FirstName@: @person.LastName<br />
<input type="hidden" value="@person.FirstName" name="persons[@index].FirstName" />
<input type="hidden" value="@person.LastName" name="persons[@index].LastName" />
}
<input type="submit" />
}
Prvky, které obsahují vlastnosti objektů, budou skryté (hidden) a jejich jméno bude určené podle vzorce:
název kolekce [index prvku].jmeno vlastnosti
Prvek typu checkbox pak bude obsahovat hodnotu indexu - nepředané indexy (=checkbox není aktivní), nebudou zpracovány.
Poznámka: v příkladu používám guid, ale je možné použít konstrukci for a vzestupnou hodnotu - fantazii se meze nekladou.
Tento přístup je i řešením případů, kdy objekt, který používáme, nemá jednoznačný jediný identifikátor, tedy kdy je jedinečnost objektu dána více jak jednou vlastností.
Nejčastěji pro kolekci v modelech pro views používám IEnumerable<T> a nebo obyčejné pole - ale používání polí pro bindování je záludné a tedy jednoznačně upřednostňuji generický typ IEnumerable<T>.
pondělí 22. prosince 2014
Nevědomě k plnému disku
Člověk se pořád učí. A když se neučí, tak je následně poučen. Stalo se mi toto - pracovali jsme na komunikačním modulu, který pro komunikaci s cizím serverem používá podepsané zprávy. Uživatel modulu nejprve do systému nahraje certifikát i s privátním klíčem a modul pak s jeho pomocí podepisuje odesílané zprávy.
Přihlásit se k odběru:
Příspěvky (Atom)