Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Stáhněte si Texy.net a NForms přes SVN

16.02 - 13. září 2008 | ASP.NET 2.0

Projekty, které se rozhodnu vypustit ven, většinou hostuju na CodePlexu. Jeho UI mi přijde mnohem rychlejší než konkurenční SourceForge a přehlednější než Google Code. Nevadí mi, že za tímto hostingem stojí velký zlý Microsoft, naopak to vítám. Tento projekt byl jedním z prvních krůčků na podporu OpenSource ze strany Microsoftu a navíc je místem, kde samotný Microsoft uveřejňuje spoustu zajímavých projektů. Například budoucí části ASP.NET.

Ale zpět k tématu. Tento hosting je postaven na Team Foundation Serveru (TFS), který je centrem pro týmovou práci, verzovacím systémem a v neposlední řadě i systémem pro vedení požadavků a úkolů. Tím se odlišuje od konkurence, která většinou používá tradiční SVN, což je po léta de-facto standard pro verzování OpenSource projektů. Komunita dlouho volala po tom, že chtějí SVN i CodePlexu. V MS nakonec udělali kompromis.

SVN Bridge

SVN Bridge byl první krok. Je to taková malá utilitka, kterou si spustíte na vašem počítači a ona překládá vaše SVN požadavky do řeči, které rozumí TFS. Můžete s ní pak používat oblíbené nástroje jako TortoiseSVN nebo VisualSVN. Ale pořád je tu nutnost donahrát si utilitu a ani URL repository ve tvaru http://localhost:8081/<tfs.server.name>/<projectname> nejsou nějak úchvatná.

Tento měsíc však došlo k zásadní změně. Na Codeplexu byl nasazen serverový SVN bridge, takže už nemusím pouštět lokální verzi, ale rovnou můžu pro snadný přístup přes SVN nástroje používat adresy následující:

  1. pro NForms https://nforms.svn.codeplex.com/svn
  2. pro Texy.net https://texynet.svn.codeplex.com/svn

No a vy také ;)

NForms na Codeplexu

13.59 - 16. srpna 2008 | ASP.NET 2.0

Na Codeplexu se objevil nový opensource projekt a není to nic menšího než NForms. Zatím jste se o nich mohli jen dočíst u mě na blogu a prakticky vyzkoušet taktéž tady – přidávání komentářů frčí na NForms. Nyní však máte jedinečnou možnost stáhnout si zdrojáky, poučit se z nich, nahlásit chyby nebo diskutovat náměty na vylepšení, zkompilovat, spustit testy a konečně nasadit a používat ve vlastních projektech.

No není to skvělé?

K čemu je to dobré?

NForm jsem napsal jako programátorské cvičení. Líbila se mi Davidova myšlenka, chtěl jsem napsat něco v C# 3.0… Jenže je to taky docela užitečná věc. Daj se pomocí toho snadno vytvářet znovupoužitelné formuláře nezávislé na infrastruktuře. Můžete je používat jak v klasickém ASP.NET modelu (můžete použít více než jeden formulář na stránce), tak v MVC nebo MVP modelu.

Další vývoj

Aktuálně připravuju podrobnější dokumentaci na wiki, ale pro začátek jistě bude stačit pár mých spotíků tady na blogu, příklady užití najdete v Unit Testech, popřípadě další moudra najdete v nedokonalých XML komentářích v samotném kódu.

Při psaní wiki jsem už našel nějaké možnosti pro vylepšení, tak až bude připraveno, hodím je zase na Codeplex. Stay tuned…

Časem bych chtěl přidat podporu validace na straně klienta. Zatím se generují jen některé třídy, na které lze napojit vlastní implementace v JavaScriptu, ale není to nic pro složitější validaci…

Credits

Musím poděkovat Davidovi za inspiraci, NForms jsou značně obšlehnuté od Nette::Forms (dříve známé jako NForms), trochu inspirace jsem pobral i u New Forms z djanga, některé zajímavé nápady, jak využít novinky C# 3.0 pro změnu z ASP.NET MVC. Takže díky!

Téměř nový rarouš.weblog

10.42 - 23. června 2008 | Moje práce

Poslední týden jsem trávil úpravami tohoto blogu. Měl jsem už nějaký nástřel grafiky už několik dní před tím, dokonce rozběhaný na úvodní straně blogu. :) Jenže abych to mohl posunout dál i do článků, musel jsem šáhnout do šablon blogu. Jenže prezentační vrstva, byla napsaná tak nepoužitelně a každá změna vyžadovala dost práce.

Měl jsem před sebou dvě možnosti. Nechat to být a počkat až napíšu nový systém, nebo upravit stávající. Jenže čekat sám na sebe, až něco napíšu, to bych se taky nemusel dočkat… ;) Nakonec jsem napsal zbrusu novou prezentační vrstvu nad starým systémem.

Rozhodl jsem se pokračovat v započatém stylu, který jsem zvolil pro svoji homepage, tedy návrhový vzor MVP pro prezentační část a Repository pro datovou. Využil a trochu rozšířil některé entity modelu o další vlastnosti a přidal některé nové. Pro výpis článků a komentářů na stránce jsem napsal serverové prvky založené na Generickém repeateru. Pak jsem se dostal k formuláři pro přidávání komentářů. Aktuální WebForms implementace se mi moc nelíbila a tak jsem se rozhodl oprášit NForms a povolat je do služby.

Musel jsem odladit několik bugů, protože tohle bylo poprvé, co jsem je použil. :) Ale nakonec se z toho vyklubal celkem použitelný a elegantní kus softwaru. Proč elegantní? Líbí se mi definování validačních pravidel (sice zatím pouze serverových), znovupoužitelnost kódu apod.

NForms v akci

Když jsem vymýšlel, jak vlastně budu nově komentáře zpracovávat, rozhodl jsem se pro handler, který bude obsluhovat požadavky na akce a zavolá správnou třídu, která má požadavek zpracovat – v tomto případě ukládač komentářů. (Tento model jsem zvolil protože, každá třída by měla dělat pouze jednu věc, proto komentáře nezpracovává ta samá, co prezentuje články.) Jenže teď jsem stál před problémem, že budu muset definovat ten samý formulář na dvou místech. Naštěstí u NForms to není třeba.

Podědil jsem novou třídu CommentForm z formuláře NForms. V ní jsem nadefinoval, jaká políčka a s jakými pravidly se mají vytvořit. Kód vypadá nějak tak:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using Rarous.NForms;
using Rarous.NForms.Validation;

namespace Rarous.Net.Components {
  public class CommentsForm : Form {
    public const string ArticleUrl = "comment_article_url";
    public const string ArticleId = "comment_article_id";
    public const string Validity = "comment_validity";
    public const string Text = "comment_text";
    public const string UserName = "comment_user_name";
    public const string UserEmail = "comment_user_email";
    public const string UserWeb = "comment_user_web";
    public const string UserAnswer = "comment_user_answer";
    public const string Submit = "comment_submit";

    public CommentsForm()
      :this(null) {
    }

    public CommentsForm(NameValueCollection data)
      : this(data, null) {
    }

    public CommentsForm(NameValueCollection data, List<string> messages)
      : base(data, messages) {
      CreateForm();
      BindData();
    }

    private void CreateForm() {
      AddHidden(ArticleUrl);
      AddHidden(ArticleId);
      AddHidden(Validity);

      AddTextArea(Text, "Text komentáře:", 10, 55).
        Required("Text příspěvku je povinný.");
      AddText(UserName, "Jméno:").
        Required("Jméno je povinné.");
      AddText(UserEmail, "E-mail:").
        SetEmptyValue("@");
      AddText(UserWeb, "Web:").
        SetEmptyValue("http://");

      AddText(UserAnswer, "Odpověď je pivo:").
        AddRule("Zadejte pivo.", s => String.Compare("pivo", s, true) == 0);

      AddSubmit(Submit, "Přidat komentář");
    }
  }
}

Tento formulář pak použivám ve View i handleru. V handleru se vytváří s daty poslanými přes POST, která se pak validují a dále zpracovávají. Líbí se mi, že data se předávají jako NameValueCollection, díky tomu se dá bez problému načítat z Request.Forms, Request.QueryString, nebo z kolekce Cookies.Values. Těmi můžu data předvyplňovat, nebo je nechat validovat a tak. V budoucnu by mohlo přibýt i inteligentní vytváření objektů…

Další featury

  1. U komentářů jsem oprášil Gravatary, které jsem tu už kdysi míval. Použil jsem implementaci z dotnetKicks, kde se používá lokální cachování.
  2. Bezpečnostní otázka se vyplňuje JavaScriptem, takže už vás nebude otravovat.
  3. Po letech jsem přidal stránkování v článcích. Jak na hlavní stránce blogu, tak v rubrikách.
  4. Zvýrazňovač syntaxe teď funguje jen napůl, protože už přestal stačit mým potřebám. Čekám na uvolnění zvýrazňavoče z Codeplexu, který by měl být o dost lepší.

Jsou to takové drobnosti, ale mám z nich radost, protože jsem je dlouho dobu odbýval.

Závěrem

Ještě mi zbývá pár věcí dopsat, aktualizovat odkazy v článcích na nové URL, ale už jsou to spíš drobnosti (doufám). Ještě bych chtěl závěrem poděkovat Davidovi a Honzovi, protože u nich jsem se dost inspiroval. Taky děkuju Exíkovi za hodnotné připomínky, Jerrymu za hosting a naší zahradě za příjemné pracovní prostředí atd.

Jak je to s tím seriálem?

09.58 - 2. února 2008 | ASP.NET 2.0

Před Vánocema jsem slíbil seriál o tom, jak napsat redakční systém nad ASP.NET MVC pomocí TDD. Mám pár dílů na disku, tak proč nejsou venku?

No při psaní jsem narazil na pár problémů, ať je to ještě nezralost ASP.NET MVC, nedostatek času a tak. Rozhodně však nejde o další mrtvý projekt. Pokusím se ho dopsat společně s návazností na NForms a CSSX, protože to jsou věci, od kterých si slibuju mnohem jednodušší a rychleší tvorbu webíků.

Ale psát kód a zároveň tvořit článek, kterému by rozuměl i macík, je dost časově náročné. A protože musim chodit občas pařit, nebou skouknout nějakej ten film a nebo prostě jenom relaxovat, tak asi blognu až jenom finál…

Přišli jste sem z RSS čtečky? Zkontrolujte si prosím, zda máte správnou URL feedu http://feeds.feedburner.com/rarous-weblog. Děkuji

Vizualizace vlastních typů v debuggeru

07.54 - 16. ledna 2008 | ASP.NET 2.0

Jistě všichni znáte možnost jak přepsat výchozí zobrazování vlastního typu v debuggeru VS pomocí přepsání metody ToString(). Ovšem někdy je tato metoda velice užitečná i na jiné účely, co potom s tím?

Když debuguje ve VS vlastní typy ve watches se vám u proměnné zobrazuje celý název typu, např. Rarous.NForms.TextItem. Pokud chcete v debuggeru vidět užitečnější informace, zpravidla přepíšete metodu ToString(), kterou má každý objekt, tak, aby vypisovala to, co chcete. Např.:

public override string ToString() {
  return "\"" + Control.Name + "\", Value=" + Control.GetValue();
}

Při debutování by se nám pak mohlo zobrazovat něco jako "email", Value=frantisek.koudelka@sts-chvojkovice.cz. Jenže. Teď chci, aby se mi v šabloně při zápisu <%=Form["email"]%> vypsal kód formulářového prvku a jeho labelu. Jak to udělat, aby se zachovalo pěkné debugování a přibyla nová a ještě lepší funkčnost?

Naštěstí existuje jiné řešení, jak debugovací informace zobrazovat. Troufnu si tvrdit, že i mnohem čistší. V .net frameworku existuje atribut System.Diagnostics.DebuggerDisplayAttribute, který je určen, právě k zobrazování informací v debuggeru. Jeho užití je následující:

[DebuggerDisplay("{Control.Name}, Value={Control.GetValue(),nq}")]
public class TextItem : FormItem {
  // implementace třídy...

  public override string ToString() {
    return Label + " " + Control;
  }
}

Tímto jsme dosáhli, nové funkčnosti metody ToString() a zachovali jsme vlastní informace zobrazované v debuggeru. Více informaci o atributu DebuggerDisplay, najdete v MSDN.

Tagy: C#, debugger, NForms

Validace v NForms pro ASP.NET

16.09 - 4. ledna 2008 | ASP.NET 2.0

Oproti původnímu očekávání, jsem za uplynulý týden na NForms skoro nešáhl. Chtělo by se říci naštěstí, protože jsem se věnoval jiným aktivitám, nepočítačovým. :) Ale asi z toho bude zpáteční projekt. Po týdnu jsem to tedy znovu otevřel a včera dopsal získávání hodnot formuláře a na dnešek zbylo začít validační vrstvu.

Validaci jsem započal jednoduchým pravidlem PredicateRule. Otázka je, jestli je to dobrý krok. Proto vlastně tento spot píšu. :) Predikátová pravidla vznikají zápisem lambda výrazů, což je sám o sobě mocný nástroj a dalo by se s ním hodně vyhrát. Ovšem naráží to pár překážek. Například typovost hodnot formulářových prvků.

Když jsem psal tu část NForms, která získává poslaná data, vytvořil jsem generickou metodu GetValue<T>(Converter<string,T>). Tato metoda získá hodnotu v požadovaném typu. Pro převod na základní datové typy z textového řetězce se dají použít předpřipravené metody třídy `System.Convert `, pro vlastní struktury stačí předat delegát na vlastní converter a mělo by to fungovat… Jenže jak se validátor dozví, jaký typ zvolit?

Znamená to asi jediné, musím napsat ještě generické ekvivalenty formulářových prvků. Na jednu stranu to znamená docela víc práce, než jsem čekal :) a na druhou mnohem větší komfort při tvorbě formulářů a validačních pravidel. Díky tomu, že je celý framework určen pro verzi 3.5, můžu využít lambda výrazy ke generování JScriptových pravidel. Tedy doufám, že to půjde. Validační kód by pak mohl vypadat nějak tak:

Form.AddRule("age", age => age > 18, "Uživatel musí být plnoletý");

Co myslíte? Mám se vydat touto cestou, nebo je to moc odvážné? :)

Tagy: , ,

NForms pro ASP.NET

18.15 - 28. prosince 2007 | ASP.NET 2.0

Do vydání kompletního frameworku Nette je ještě asi daleko, ale to nevadí. My na ASP.NET bychom z něj stejně žádný užitek neměli. Tedy vlastně, proč by ne?

Vždyť Nette je protkáno spoustou skvělých nápadů. A když jde o skvělé nápady proč je nezhmotnit že? :) Ukradl jsem Davidovo mentální bohatství a jal se implementovat NForms v C#. Jako inspirace mi sloužila skvělá přednáška o Nette frameworku. Zatím jsem ve fázi (po dvou dnech koukání na přednášku a přerušovaného psaní), kdy se formuláře hezky generují. To je tak čtvrtina úspěšné cesty, doufám.

Nahlížíme pod pokličku

Základem je něco, jako NHtml, třída HtmlElement, která se stará o generování kódu. Syntaxe částečně vychází z NHtml, ale vzhledem k rozdílnosti jazyků, jsem některé věci musel řešit odlišně. V podstatě jsem zde narážel na limity C# jako staticky typovaného jazyka.

var input = new HtmlElement(
  "input",
  new { Name = "name", Id = "nameInput", Type = InputType.Text },
  HtmlElement.SelfClosing
);

V ukázce je vytvoření elementu input včetně některých atributů. Atributy se předávají pomocí vlastností anonymní třídy. Vygenerovaný kód vypadá následovně:

<input name="name" id="nameInput" type="Text" />

Další vlastnosti lze nastavovat přes indexer následujícím způsobem:

input["MaxLength"] = 25;

Dále pak má metody pro přidávání potomků, nastavování textu nebo HTML, přidávání/odebírání CSS třídy a samotné renderování.

Na tomto základě pak vyrůstá formulářová nadstavba. Snažil jsem se co nejvíce přiblížit API PHPčkovému vzoru, ale práce je v tomto směru velice těžká. Zlatej Microsoft a OpenXML ;) Vzorem je pár zachycených řádků na přednášce (David pekelně rychle mačká PgDown/PgUp) a vlastní fantazie ohledně zbytku.

No prozatím jsem se dostal do následujícího stavu. Následná akce řadiče:

[ControllerAction]
public void Index() {
  var genres = new ListItem[] {
    new ListItem { Text = "muž", Value = 1 },
    new ListItem { Text = "žena", Value = 2 }
  };

  Form form = new Form();
  form.AddText("name", "Jméno:", 20, 50);
  form.AddText("email", "E-mail", 20, 255);
  form.AddHidden("skryte").SetValue("nějaká hodnota - skrytá");
  form.AddRadio("pohlavi", "Pohlaví:", genres);
  form.AddButton("submit", "Odeslat");
  Form = form;
  RenderView("Index");
}

ve spojení se šablonou v pohledu:

<form method="post" action="">
<div style="display:none"><%=Form["skryte"].Control %></div>
<fieldset>
  <legend>Osobní údaje</legend>
<table>
<tr>
  <td><%=Form["name"].Label %></td>
  <td><%=Form["name"].Control %></td>
</tr>
<tr>
  <td><%=Form["email"].Label %></td>
  <td><%=Form["email"].Control %></td>
</tr>
<tr>
  <td><%=Form["pohlavi"].Label %></td>
  <td><%=Form["pohlavi"].Control %></td>
</tr>
<tr>
  <td></td>
  <td><%=Form["submit"].Control %></td>
</tr>
</table>
</fieldset>
</form>

Vygeneruje následující kód:

<form method="post" action="">
<div style="display:none">
<input name="skryte" type="Hidden" value="nějaká hodnota - skrytá" />
</div>
<fieldset>
  <legend>Osobní údaje</legend>
<table>
<tr>
  <td><label for="name">Jméno:</label></td>
  <td><input name="name" id="name" type="Text" size="20" maxlength="50" /></td>
</tr>
<tr>
  <td><label for="email">E-mail</label></td>
  <td><input name="email" id="email" type="Text" size="20" maxlength="255" /></td>
</tr>
<tr>
  <td><label>Pohlaví:</label></td>
  <td>
    <input name="pohlavi" id="pohlavi0" type="Radio" value="1" />
    <label for="pohlavi0">muž</label><br />
    <input name="pohlavi" id="pohlavi1" type="Radio" value="2" />
    <label for="pohlavi1">žena</label><br />
  </td>
</tr>
<tr>
  <td></td>
  <td><input name="submit" type="Button" value="Odeslat" /></td>
</tr>
</table>
</fieldset>
</form>

A to je zatím vše. A proč to vlastně dělám a nepokračuju v seriálu o Gryphoonu? Inu, vlastně pokračuju, pokračuju…

Tagy: , ,

Čekání na ASP.NET Extensions

20.12 - 7. prosince 2007 | ASP.NET 2.0

Dneska snad maj vyjít ASP.NET Extensions CTP, které mimo jiné obsahují i ASP.NET MVC framework. Těšim se jak malý dítě, ale protože tu ještě není, koukal jsem na přednášku o frameworku Nette. Taky pěkné.

Pěknou přednáškou v podání Davida Grudla (-dgx-), jsem se jenom namlsal (no ten pitelpytel chipsů k tomu taky prasknul). No zatim jsem prolítnul ve čtečce příspěvky, který o ASP.NET MVC vyšly a udělal z nich stránku. Vybral jsem jen hodnotné, které jsou o něčem. :) No a když jsem udělal ten souhrn o ASP.NET MVC, tak proč bych ho neudělal i pro Nette? Nevim… Tady je.