Author Archives: Robert Haken

avatar Neznámé

About Robert Haken

Software Architect, Founder at HAVIT, Microsoft MVP - ASP.NET/IIS

Optimalizace databázových aplikací – Slides, dema, záznam [SQL DevCon 2009, MS Fest 2009]

Slides a další materiály z přednášky na konferenci SQL DevCon 2009 a MS Fest 2009 (na obou konferencích byla prezentována velmi podobná verze):

Z přednášky byl pořizován záznam, který je k dispozici na našem YouTube Channelu:

Podobná přednáška v rozsáhlejší podobě se záznamem byla prezentována i pro WUG Praha v březnu 2013.

web.config transformace a Code Contracts – Dema [MS DevDays 2009]

Dema k mým ukázkám na konferenci MS DevDays 2009:

Záznam z vystoupení nebyl pořizován, na téma web.config transformací však doporučuji svůj screencast.

Pozor na IIS Application pool: Maximum Worker Processes (Web Garden)

V nastavení application poolu na IIS je zastrčeno jedno nastavení s výchozí hodnotou 1, které je poměrně zrádné, pokud ho někdo změní a neví, co to přesně znamená.

Jde o volbu „Maximum Worker Processes“ a neznalé svádí tuto hodnotu z jedničky zvětšit na vyšší číslo.

Co to však ve skutečnosti znamená – jde o to, že IIS pustí pro Application Pool více instancí Worker Processu (w3wp.exe), které jsou navzájem izolované. Vznikne tak více nezávislých instancí aplikací běžících na daném Application Poolu a celé se to začne chovat jako Web Garden (= lokální virtuální Web Farm na jednom serveru). Následky jsou pak prakticky stejné, jako běh aplikace na webové famě – instance aplikace mezi sebou nezdílí kontext (Application, Cache, in-proc Session, atp.).

Protože každý Váš request pak může vyřdit jiná instance aplikace, projevy mohou být např. následující:

  • ztrácí se Vám Session, pokud používáte výchozí InProc session (hodnoty Session jsou uloženy na jiném „serveru“, než který vyřizuje aktuální request),
  • nefunguje dobře cachování (každý „server“ si udržuje vlastní cache a musí se tedy naplnit tolik cachí, kolik „serverů“ Vám běží),
  • ztrácí se Vám hodnoty Application contextu (opět stejný důvod),
  • nefungují Vám grafy DevXpress (protože si obrázek ukládají do lokálního contextu v okamžiku renderování stránky s grafem a požadavek browseru na obrázek grafu se dostane na jiný „server“),
  • atp. atp.

Osobně v běžném provozu nenacházím scénář, kde by Maximum Worker Processes mělo být nastaveno jinak než na 1. Dokážu si představit jedině, že někdo chce záměrně testovat chování své aplikace na webové farmě, nebo nějaké obskurní důvody s unmanaged componentami, nebo řešením nedostatečné thread-safety aplikace.

ASP.NET Routing – Když v IIS7 integrated-mode nechodí Session

Pokud Vám po nastavení ASP.NET routingu na IIS7 v integrated-mode nechodí na stránkách Session, pak je potřeba elementu system.webServer/modules nastavit atribut runAllManagedModulesForAllRequests na true:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true"><!-- bez tohoto s ASP.NET Routingem nechodí Session v integrated-mode -->
        <remove name="UrlRoutingModule" />
        <add name="UrlRoutingModule"
             type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </modules>

…ono to není jenom o Session, pro ASP.NET Routing se v integrated-mode nespouští moduly, které mají pre-condition managedHandler.

asp:Chart aneb grafy od Microsoftu

Microsoft přišel se svým „vlastním“ controlem na renderování grafů do webových stránek (ve skutečnosti je to zřejmě Dundas „Lite“).

<asp:Chart runat="server"/>

Každopádně je to zajímavá alternativa ke komerčním komponentám třetích stran a přestože podstatně chybí design-time podpora, určitě se na nové grafy podívám.
Control, dokumentace i rozsáhlá dema jsou ke stažení.
Krátké intro-video můžete zkouknout i na MSTV.cz.

Pozor na ImageUrl, resp. UrlPathEncode() a znaky % (procenta) nebo # (hash)

Při bezstarostném používání Image.ImageUrl jsem narazil na zajímavý problém – pokud se Vám v názvu souboru nebo v cestě k němu vyskytne % (procenta) nebo # (hash), pak máte problém – metoda HttpUtility.UrlPathEncode(), kterou Image.ImageUrl a mnohé další controly pro encodování URL odkazů používají, Vám tyto znaky neencoduje:

<asp:Image ImageUrl="~/Folder #3/File.jpg" runat="server" />

udělá

<img src="/Folder%20#3/File.jpg" />

protože

HttpUtility.UrlPathEncode("/Folder #3/File.jpg") == "/Folder%20#3/File.jpg"

Metoda UrlPathEncode() totiž encoduje jen mezerník a non-ASCII znaky.

Správné samozřejmě je, abyste se na webových serverech pokusili těmto znakům vyhnout. Nicméně uživatelé jsou tvořiví a tak se můžete dočkat překvapení stejně jako já.

Osobně si myslím, že se jedná o bug v metodě UrlPathEncode(), resp. o nenaplnění očekávaného contractu, nicméně Microsoft to samozřejmě interpretuje jako by-design a radí, ať si uděláte Replace() těchto znaků sami.

Nezbývá tedy než:

myImage.ImageUrl = path.Replace("%", "%25").Replace("#", "%23");

Mimochodem obdobných vychytávek se můžete dočkat i se znakem + (plus).

web.config transformace – Screencast, slides, dema [MSTV 2009]

Screencast, který jsem svého času vytvořil pro MSTV.cz

Slides a dema ke screencastu:

Viz též:

Generátor klíčů GP WebPay (PayMuzo) hlásí chybu „Illegal key size“

Při poslední z implementací GP WebPay (PayMuzo) se nám stalo, že nám generátor klíčů obchodníka zahlásil chybu

exception encrypting data - java.security.InvalidKeyException: Illegal key size

Po chvilce testování (na dvou různých PC) jsme zjistili, že to dělá při Heslu pro keystore delším 8 a více znaků. Pokud jsme heslo zkrátili na 7 a méně znaků, vygenerování klíčů proběhlo úspěšně.

Verzi utility lze popsat jako „(c) 2004/2005 Muzo a.s.“ v UI a velikost souboru GenCert.jar 33567 bytů, víc mě nad tím bádat nebaví.

Pokud byste někdo bojoval s implementací GP WebPay pro .NET, tak se mi klidně ozvěte, máme to hotový a určitě se nějak dohodneme… ;-)

X509Certificate2: CryptographicException: The system cannot find the file specified.

Pokud vytváříte ve webové aplikaci X509Certificate2

myCertificate = new X509Certificate2(rawData, password);
//nebo
myCertificate = new X509Certificate2(fileName, password);

pak můžete být po nasazení své funkční aplikace na produkční server (např. hosting) obdařeni výjimkou

System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password)

…přestože soubor s certifikátem buď zaručeně existuje (fileName), nebo se ani nepoužívá (rawData).

Problém souvisí s tím, že v produkčním prostředí Vaše aplikace beží pod uživatelským účtem, který nemá založen profil, který se má certifikát vytvořit (volně přeloženo, omlouvám se za případnou nepřesnost).

Řešením je použití přetížení constructoru, kterým zvolíte cílové uložiště certifikátu:

 

myCertificate = new X509Certificate2(rawData, password, X509KeyStorageFlags.MachineKeySet);
//nebo
myCertificate = new X509Certificate2(fileName, password, X509KeyStorageFlags.MachineKeySet);

Web Deployment Dev10 (VS2010, NET4) – Slides a dema [TechEd Praha 2009]

Slides a dema z přednášky na konferenci TechEd Praha 2009:

Z přednášky nebyl pořizován záznam, část tématiky o web.config transformacích lze najít ve v podobě screencastu, který jsem svého času dělal pro MSTV.cz.