Po půl dni snažení a bádání jsem dospěl k subjektivnímu závěru, že nelze udělat rozumný ASP.NET validátor založený na AJAXu. Přesněji řečeno bylo mým cílem vytvořit obdobu CustomValidatoru, který by měl běžný ServerValidate a navíc klientskou jscript část, která by pomocí AJAXového HTTP-requestu validovala hodnotu vůči tomuto ServerValidate.
Narazil jsem na následující zásadní překážky, které podle mě nelze snadno překonat:
- Současné ASP.NET validátory, resp. všechny jejich Microsoftí obslužné klientské skripty a API jsou nekompromisně synchronní. V okamžiku požadavku validace (obvykle před submitem stránky) jsou volány prosté validační funkce všech povolených validátorů a od těchto se očekává jen true/false dle výsledku validace. V současném konceptu validátorů nikde není rozumný prostor pro asynchronní operace či nějakého zásahu do průběhu validace.
- Je prakticky nemožné rozumným způsobem provést synchronní AJAXové volání vůči serveru a stejnětak je nemožné rozumně toto synchronní volání simulovat nějakým blokováním threadu uvnitř validační funkce. Javascript nezná žádné sleep/wait/pause a veškeré snahy o jeho implementaci vždy končí v tupé smyčce zatěžující CPU ze 100% do okamžiku splnění nějaké podmínky (přijetí AJAXového callbacku, dosažení určitého času, naplnění čítače, atp.)
Pro současný koncept ASP.NET validátorů jsem dospěl k těmto závěrům:
- Protože je koncept založen především na jednorázové kontrole hodnot před submitem formuláře a má za účel tento submit povolit/zakázat, je oprávněně založen na synchronních operacích a pro jakékoliv dlouhotrvající operace či asynchronní volání zde není prostor a poměrně logicky se s nimi nepočítá.
- Asynchronní AJAXová validace vůči serveru by byla použitelná u konceptu průběžné validace, kdy by byly hodnoty kontrolovány ihned po jejich zadání (onchange) a takováto validace by díky svému zpoždění nemohla blokovat odeslání formuláře, spíše by sloužila jako proaktivní kontrola uživatelského zadání.
- Současný koncept validátorů připouští pouze zběsilá řešení se synchronizačním blokováním threadu v různých sleep smyčkách (byť s timeoutem), popř. „chováním nekompatibilní“ on-change implementace dle bodu 2.
Veškeré pokusy o implementace AjaxValidatoru, které jsem na netu viděl, trpěly jedním nebo několika nedostatky z výše uvedených a jejich praktická použitelnost se tak blíží nule (spíše se tak stávají přetěžovači serverů, než účinnými validátory).
Avšak! Pokud by se našel někdo, koho by napadlo, jak výše uvedená omezení účinně obejít a funkční AjaxValidator vytvořit, sem s myšlenkou a pochvala ho nemine… ;-)))
PS: Sám jsem dospěl k implementaci AjaxValidatoru, který měl nastavitelný Timeout a ve validační funkci po zavolání asynchronního AJAX requestu na ServerValidate čekal po dobu tohoto timeoutu na odezvu serveru (čekal = různé hnusné implementace zatěžujících smyček čekajících na nějaký příznak nebo timeout). Pokud do Timeoutu nebyl AJAXem výsledek od serveru získán, propustila klientská část validaci jako IsValid=true, a tak se to v případě submitu zvalidovalo na serveru, nebo v případě onchange validace dovalidovalo později asynchronně (až dorazil callback, tak se aktualizoval validátor). Výsledek mi přišel pro praxi nepoužitelný, už timeout 1s je pro ovládání webového formuláře nepříjemný, stránka nereaguje na odeslání formuláře okamžitě, proto jsem to celé zahodil… Můj poznatek je, že pokud validátorem chápeme to, co ASP.NET, tedy blokaci odeslání formuláře, tak přes AJAX cesta nevede, i kdyby to šlo bez toho cyklického pollingu s timeoutem. Leda by byla odezva v řádu milisekund, což při serverových validacích moc nehrozí (obvykle nějaký dotaz do DB na exists, atp.).