Author Archives: Robert Haken

avatar Neznámé

About Robert Haken

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

Pozor na UpdatePanel a unikátní názvy (ID) controlů

AJAXový UpdatePanel se chová zvláštně vůči logice naming-containerů, pokud se tedy potkáte s názvy (ID) controlů, nepůjde Vaše stránka zkompilovat. Stačí zkusit následujících jednoduchý snippet:

<asp:TextBox ID="SomethingTB" runat="server" />
<asp:Repeater ID="MyRepeater" runat="server">
  <ItemTemplate>
    <asp:UpdatePanel runat="server">
      <ContentTemplate>
        <asp:TextBox ID="SomethingTB" runat="server" />
      </ContentTemplate>
    </asp:UpdatePanel>
  </ItemTemplate>
</asp:Repeater>

…při kompilaci budete obšťastněni chybovými hláškami

D:\Development\UpdatePanelCompiler\Default.aspx(18,57): error CS0102: The type '_Default' already contains a definition for 'SomethingTB'
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\updatepanelcompiler\1c44388f\ad38e94\App_Web_r7xfjqxf.0.cs(231,59): error CS0111: Type 'ASP.default_aspx' already defines a member called '__BuildControlSomethingTB' with the same parameter types

Transaction log narůstá, backup nepomáhá, shrink neúčinný

Na MSSQL serveru se občas stává, že backupování přestane truncatovat transaction log a ten narůstá a narůstá.

Z nějakého důvodu je potřeba udělat sekvenci shrink-backup-shrink, aby bylo dosaženo požadovaného účinku:

1) Run this code:

DBCC SHRINKFILE(pubs_log, 2)

2) Run this code if you want to truncate the transaction log and not keep a backup of the transaction log. Truncate_only invalidates your transaction log backup sequence. Take a full backup of your database after you perform backup log with truncate_only:

BACKUP LOG pubs WITH TRUNCATE_ONLY

-or-

Run this code if you want to keep a backup of your transaction log and keep your transaction log backup sequence intact. See SQL Server Books Online topic „BACKUP“ for more information:

BACKUP LOG pubs TO pubslogbackup

3) Run this code:

DBCC SHRINKFILE(pubs_log, 2)

Aktualizace pro SQL 2008

V SQL Serveru 2008 již není BACKUP LOG WITH TRUNCATE_ONLY přepínač použitelný, místo toho je možné přepnout DB do Simple recovery modelu a udělat shrink logu. Pak je možné přepnout zpět na Full.

-nebo-

Update od Martina Falty pro SQL 2008+ (díky)

DBCC SHRINKFILE(pubs_log, TRUNCATEONLY)

Viz http://technet.microsoft.com/en-us/library/ms189493(v=sql.100).aspx

Excel: Podmíněný součet SUMIF s podmínkou na (ne)prázdné buňky

Chvíli jsem bádal, jak zapsat podmínku do funkce SUMIF, pokud chci sečíst jen buňky, kterým odpovídá kritérium (ne)prázdné buňky.

Pro prázdné buňky je to

=SUMIF(C2:C10;"=";B2:B10)

Pro neprázdné buňky je to

=SUMIF(C2:C10;"<>";B2:B10)

…pozoruhodná podoba podmínky, ale hlavně, že to funguje.

Fiddler: Zachytávání lokálního ASP.NET Web Development Serveru (aktualizováno)

Fiddler je výborný nástroj pro zachytávání HTTP provozu – zobrazí Vám přesnou podobu HTTP requestu a responsu, kterou Váš počítač dělá vůči webovým serverům.

Ve skutečnosti Fiddler funguje jako proxy-server. Při spuštění se nastaví v Internet Options jako proxy a veškeré běžné požadavky tak jdou přes něj. Problém je v tom, že ne zas tak úplně veškeré, Innternet Explorer i .NET Framework natvrdo směřují veškeré požadavky na „localhost“ a „127.0.0.1“ mimo proxy, přestože je proxy zapnutý i pro intranet.

První podmínkou pro zachytávání Fiddlerem je tedy používat pro browsing adresu v podobě http://mujpocitac:1234/MyPage.aspx, čímž jdou takové požadavky přes proxy a dostane je Fiddler.

Další problém je však v tom, že ASP.NET Web Development Server (Visual Studio, Web Developer Express, …) přijímá požadavky pouze na „localhost“ a ostatní zamítá.

Řešením je překlad adresy ve Fiddleru. Fiddleru můžeme přidat pravidlo, aby požadavky na „mujpocitac“ převáděl na podobu „localhost“. Do CustomRules.js (Rules ~ Customize rules…) přidáme na začátek události BeforeRequest:

static function OnBeforeRequest(oSession:Fiddler.Session)
{
    oSession.host = oSession.host.replace("mujpocitac", "localhost");
}

…a je to.

(Samozřejmě ten překlad by se dal udělat i odolnější, aby fungovaly i adresy http://mujpocitac/mujpocitac/mujpocitac.aspx a nebylo z nichhttp://localhost/localhost/localhost.aspx)

Update pro Windows Vista

Ve Windows Vista je mimo výše uvedeného potřeba ještě ve Fiddleru v Options vypnout volbu „Enable IPv6“.

Nastavení Image.Source z kódu

myImage.Source = new BitmapImage(new Uri("images/myImage.jpg", UriKind.Relative));

mstsc.exe /admin

Pokud jste u RDP clienta byli zvyklí na přepínač /console, pak vězte, že ho Microsoft přejmenoval na přepínač /admin:

mstsc.exe /admin

Cílovou adresu je možné předat přepínačem /v

mstsc.exe /v:my.server.com

Je to zjednodušeně řečeno připojení na jednu vyhrazenou session RDP (přesněji řečeno lokální konzoli, jako u běžného Remote Desktopu), kde se zejména neuplatňuje limit 3 admin-session, nýbrž se v rámci té jedné vyhrazené session připojení navzájem vykopávají (a tedy je to řešení, když vás server nechce pustit na RDP kvůli limitu 3 a Vám by jinak nezbývalo, než vyrazit k serveru a otevřené session sestřelit). Potřeba je pochopitelně účet s administrátorskými právy.

Exchange 2007: Podivná authentizace starších klientů (Outlook 2003, Outlook Express)

Vynikající chybu jsem objevil v Outlook Expressu (z Win2k3 Serveru). Při připojení na standardní instalaci Exchange 2007 se při zaškrtnutí „Přihlašovat k serveru odchozí pošty“ – „Použít stejné přihlašovací údaje jako server příchozí pošty“ – klient neauthentizuje vůči serveru. Pokud však využijeme možnosti zadat authentizační údaje ručně, OE se přihlásí a poštu odešle. Pokud opět přepnete zpět na „Použít stejné jako příchozí“, tak odesílání pošty funguje, ale jen než restartujete OE.

Pominu-li tento bug v Outlook Expressu, tak problém je v tom, že standardní instalace Exchange 2007 nemá povolenu Basic authentization, resp. ji má pod podmínkou „Offer Basic Authentization only after starting TLS“. Exchange server tak v odpovědi na EHLO odpovídá jen AUTH NTLM a nenabízí AUTH LOGIN.

AUTH LOGIN povolíme odšrktnutím „Offer Basic Authentization only after starting TLS“ (Server Configuration – Hub Transport – Receive Connector – Properties – Authentication).

Exchange 2007 Setup: Topology discovery failed, error 0x80040a02 (DSC_E_NO_SUITABLE_CDC).

Pokud budete během instalace Exchange 2007 obdařeni touto príma chybou, vězte, že je potřeba zapnout IPv6 a nastavit serveru IPv6 adresu.

Podrobnosti zde.

Pozor na FileUpload v UpdatePanelu

Po prázdninové odmlce jsem tu zpět s další čerstvou zkušeností, kterou jsme udělali na jednom z našich projektů.

Story

Společné uživatelské rozhraní pro vytváření nových a editaci stávajících záznamů mělo části, které byly použitelné jen pro existující objekty, mj. i možnost připojení souborů pres control FileUpload. Části použitelné jen u existujících objektů byly skryty pomocí Visible=“fase“ a zobrazovány pomocí UpdatePanelu, který je zobrazil po uložení nového objektu.

Problém byl v tom, že u nově vytvořených objektů nebylo možné připojit soubory, zatímco u existujících objektů to bez problémů šlo. Ukázalo se, ze control FileUpload v postbacku žádný soubor nedostane (HasFile bylo false), přestože uživatel soubor do formuláře zadal. Stejně se to chovalo ve všech prohlížečích a Fiddler potvrdil, že se z klienta žádný soubor nepřenesl.

Primitivní testovací kód by mohl vypadat třeba takto:

<form id="form1" runat="server">
     <asp:ScriptManager EnablePartialRendering="false" runat="server" />
        <asp:UpdatePanel runat="server">
            <ContentTemplate>
                <asp:FileUpload ID="FileFU" Visible="false" runat="server" />
                <asp:Label ID="HasFileLb" runat="server" />
                <asp:Button ID="SaveBt" Text="Save" runat="server" />
            </ContentTemplate>
        </asp:UpdatePanel>
</form>
void SaveBt_Click(object sender, EventArgs e)
{
    FileFU.Visible = true;
    HasFileLb.Text = FileFU.HasFile.ToString();
}

Po chvilce ladění se ukázala příčina problému. V režimu editace existujícího objektu formulář již od prvního requestu renderoval control FileUpload, který si sám do elementu form doplňuje potřebný atribut enctype=“multipart/form-data“, zatímco v režimu založení nového objektu se control FileUpload renderoval až AJAXem z UpdatePanelu po uložení nového objektu. UpdatePanel však v DOM stránky vymění jen svoji část a element form zůstává nedotčen, bez atributu enctype.

Summary

Pozor na to, ze AJAXovy partial rendering pomoci UpdatePaneliu vymění pouze určitou část DOM stránky a nesmi se zapomínat na vztahy teto části se zbytkem stránky. Většinou jsou tyto vztahy zřejmé, záludnost s FileUpload a atributem enctype vsak může pozlobit.

Možným řešením je například nastavování hodnoty atributu z kódu už při prvním requestu, přestože control FileUpload ještě na stránce není:

this.Page.Form.Enctype = "multipart/form-data"

Detailní ASP.NET Request + WebForm Page LifeCycle diagram

Pokud se zabýváte technologií ASP.NET do hloubky, může se Vám hodit můj „ASP.NET 2.0/3.5 Request + Page LifeCycle Diagram“:

ASP.NET LifeCycle 2

Jedná se o první verzi mého diagramu, který hodlám dále graficky vylepšovat a zpřehledňovat. Až mi zbyde chvilka, dám sem i PDF verzi k tisku. Stejnětak je možné, že jsem v něm někde udělal chybu. Pokud tedy nějakou nesrovnalost objevíte, dejte mi prosím vědět.

Červeně jsou označena místa, kde se lze zapojit s vlastní invencí, jde buď o události, virtuální metody, nebo adapter. Modře jsou vyznačeny interface pro implementaci dané funkčnosti a šedě jsou interní implementace ASP.NET.

Viz též