Category Archives: .NET Framework

ExternalException: A generic error occurred in GDI+. při Image.Save()

Tuto krásnou výjimku dostaneme, pokud chceme Image ukládat do stejného souboru, z kterého byl načten. GDI+ to prostě nedovoluje.

Dá se to ale obejít například zkopírováním obrázku do nové instance:

Bitmap bitmap;
using (Image image = Image.FromFile(sourceFilename))
 {
   // načteme si obrázek do bitmapy, abychom mohli zavřít soubor
   bitmap = new Bitmap(image);
}
...
bitmap.Save(...); // tady už to nevadí, přetrhli jsme vazbu na soubor

Rozdíl mezi int.Parse() a Convert.ToInt32()

Mnoho vývojářů tápe, kterou z metod Int32.Parse() a Convert.ToInt32() používat pro parsování textových vstupů na číslo. Rozdíl je malý, a sice v interpretaci vstupu null. Vše je jasné, pokud se podíváme na vnitřnosti Convert.ToInt32():

 

public static int ToInt32(string value)
{
   if (value == null)
   {
      return 0;
   }
   return int.Parse(value, CultureInfo.CurrentCulture);
}

Metoda Convert.ToInt32() tedy na vstup null vrátí hodnotu 0, zatímco int.Parse() vyhodí výjimku ArgumentNullException.

RAISERROR a jeho efekt v ADO.NET

RAISERROR

Z SQL stored procedur můžeme oznamovat vnější aplikaci chyby prostřednictvím příkazu RAISERROR, nejběžněji:

RAISERROR(message_str, severity_int, state_int, arg1, arg2)

přičemž

  • message_str představuje textový popis chyby v like-PRINTF podobě s procentama (argn pak představují hodnoty k dosazení),
  • severity_int udává závažnost chyby (viz níže),
  • state_int je číslo od 1 do 127 a předává se tím stavová hodnota (obvykle prostě 1)

např. tedy

RAISERROR ('The level for job_id:%d should be between %d and %d.',
      16, 1, @@JOB_ID, @@MIN_LVL, @@MAX_LVL)
ADO.NET

A teď k efektu RAISERROR v ADO.NET – vše závisý na parametry severity. Pro uživatelské chyby jsou určeny severity od 1 do 18, severity od 19 do 25 jsou určeny pro sysadmina.

Výsledký efekt v ADO.NET je tedy následující:

  • severity <= 10 nevyvolá výjimku v .NET, nýbrž event InfoMessage související SqlConnection (k odchycení musíme navěsit event-handler),
  • severity > 10 vyvolá výjimku SqlException, ale nezavře spojení,
  • severity > 16 vyvolá výjimky SqlException a uzavře spojení.

POZOR!!! Samotné RAISERROR nezajistí ROLLBACK transakce (musí se provést explicitně), ani nepřeruší běh T-SQL dávky (nutno třeba RETURN).

DirectoryNotFoundException: Could not find a part of the path „C:\“.

Takovoudle prima výjimku dostaneme, pokud voláme System.IO.Directory.CreateDirectory(String path) a nemáme přístupová práva alespoň na prohlížení všech nadřazených složek, typicky třeba chceme-li vytvořit novou složku z webové aplikace.

Directory.CreateDirectory() totiž neslouží jen pro založení jedné složky, ale pokud je potřeba, vytvoří celou požadovanou cestu, založí všechny potřebné složky. Základní potíž je v tom, že si nekontroluje existenci složek zdola, ale shora. Takže požadavek na založení složky C:\Inetpub\wwwroot\WebApplication\slozka\ kontroluje nejprve existenci C:\, pak C:\Inetpub\, pak C:\Inetpub\wwwroot\. No a pokud nemáme práva alespoň LIST na celou trasu, tak jsme v loji…