Konvence a zásady z vývojářské praxe [TechEd Praha 2011]

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

Z přednášky nebyl pořizován záznam, rozšířená podoba přednášky však byla prezentována pro WUG Praha a k té záznam existuje.

Excel: Podmíněný součet SUMIF s odkazem na jinou buňku v podmínce

Opět jsem chvíli bádal, tentokrát, jak zapsat do funkce SUMIF podmínku, která by se odkazovala na hodnotu jiné buňky. Např. chci sečíst hodnotu, pokud je větší než hodnota v jiné buňce (konkrétně jsem řešil jakési plovoucí součty umořování, ale to ten není podstatné). Důležité je, že pokud se potřebuji v podmínce (criteria), která je jinak textovým řetězcem, odkázat na hodnotu určité jiné buňky, tak si tam mohu hodnotu té jiné buňky prostě dostat textovým skládáním onoho řetězce:

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

…jak prosté.

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

Český stemmer do MSSQL 2008 R2 x64

Dneska se budu s laskavým svolením chlubit cizím peřím, uvádím postup (mnou neověřený, ale z důvěryhodného zdroje – od Roberta Kindla z firmy EXEC), jak do MS SQL 2008 R2 x64 dostat český stemmer pro fultextové vyhledávání:

****

musis nainstalovat Microsoft Search Server 2010 Express – to by melo byt zdarma a cesky stemmer to obsahuje

bohuzel je ale ten stemmer dostupny jen v tom Sharepointu (neregistruje se to do systemu)

takze jsem vlasnimi silami vyhackoval toto:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSearch\Language\ces]
„TsaurusFile“=“tsces.xml“
„Locale“=dword:00000405
„WBreakerClass“=“{468bfc77-3876-4a47-a6ff-f5f6e8ea7968}“
„StemmerClass“=“{f51b7203-9bf9-4c39-b655-18fad8fa8a9a}“
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSearch\CLSID\{f51b7203-9bf9-4c39-b655-18fad8fa8a9a}]
@=“c:\\Program Files\\Microsoft Office Servers\\14.0\\Bin\\mswb7.dll“
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSearch\CLSID\{468bfc77-3876-4a47-a6ff-f5f6e8ea7968}]
@=“c:\\Program Files\\Microsoft Office Servers\\14.0\\Bin\\mswb7.dll“
toto konkretne zaregistruje ten cesky stemmer z Microsoft Search Server 2010 Express do MSSQL 2008 R2 (pro MSSQL 2008 a MSSQL 2005 by to zrejme slo podobne)

pak uz staci jen
exec sp_fulltext_service ‚update_languages‘;
exec sp_fulltext_service ‚restart_all_fdhosts‘;

overeni instalace (vypise se stemmer) s lcid 1029
exec sp_help_fulltext_system_components wordbreaker
SELECT * FROM sys.fulltext_languages order by lcid

sklonovat to umi:
select * from sys.dm_fts_parser(‚FORMSOF(INFLECTIONAL, květina)‘, 1029, 0, 0)

++++

jeste je asi treba tohle:
copy „c:\Program Files\Microsoft Office Servers\14.0\Data\Config\tsces.xml“ „c:\MSSQL2008R2\FTData“ (do slozky k ostatnim ts???.xml)
Noise Words, ktere jsou v Sharepointu 2010 ulozeny v c:\Program Files\Microsoft Office Servers\14.0\Data\Config\noiseces.txt by se na MSSQL 2008 R2 mely konfigurovat pres CREATE FULLTEXT STOPLIST

SmtpTraceListener – mailování výstupů trace

V návaznosti na používání ExceptionTraceru, který pomocí standardní .NET mechanizmů Trace/TraceSource loguje neobsloužené výjimky, jsem dopsal jednoduchý TraceListener, který lze používání pro mailování těchto výjimek na určený mail. Cílovým scénářem je tedy automatické mailování výjimek z consolových/WinForm aplikací, či spíše utilit. Není to zatím příliš vyladěno, spíše takový náznak, jakou cestou se vydat.

Do činnosti se to zapojuje zhruba takto (app.config):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <sources>
            <source name="Exceptions" switchValue="Error">
                	<listeners>
<!--                    <add name="XmlListener" initializeData="Exceptions.xml" type="System.Diagnostics.XmlWriterTraceListener"/>
                    <add name="TextWriterListener" initializeData="Exceptions.log" type="System.Diagnostics.TextWriterTraceListener"/>
-->
                    <add name="SmtpListener" initializeData="Subject=Chyby z mojí utility;To=errors@firma.cz" type="Havit.Diagnostics.SmtpTraceListener, Havit"/>
                </listeners>
            </source>
        </sources>
    </system.diagnostics>
    <system.net>
        <mailSettings>
            <smtp deliveryMethod="Network" from="neco@nekde.cz">
                <network host="mail.server.cz"/>
            </smtp>
        </mailSettings>
    </system.net>
</configuration>

Základem je implementovat třídu dědící z předka TraceListener:

  /// <summary>
    /// TraceListener, který výstup posílá mailem.
    /// </summary>
    /// <remarks>
    /// Inspirováno implementaci System.Diagnostics.XmlWriterListener.
    /// </remarks>
    public class SmtpTraceListener : TraceListener
    {
        #region MailTo
        /// <summary>
        /// E-mailová adresa, na kterou se posílají zprávy.
        /// </summary>
        public string MailTo
        {
            get
            {
                if (_mailTo == null)
                {
                    return "devmail@havit.cz";
                }
                return _mailTo;
            }
            set
            {
                _mailTo = value;
            }
        }
        private string _mailTo;
        #endregion

        #region Subject
        /// <summary>
        /// Subject zprávy.
        /// </summary>
        public string Subject
        {
            get
            {
                if (_subject == null)
                {
                    return "SmtpTraceListener";
                }
                return _subject;
            }
            set
            {
                _subject = value;
            }
        }
        private string _subject;
        #endregion

        #region Constructors
        /// <summary>
        /// Constructor, který je volán při použití TraceListerneru z app.configu a předává se do něj hodnota atributu initializeData.
        /// </summary>
        /// <param name="initializeData">hodnota atributu initializeData z app.config</param>
        public SmtpTraceListener(string initializeData)
        {
            if (initializeData == null)
            {
                return; // použijí se defaulty                
            }

            foreach (string arg in initializeData.Split(';'))
            {
                string[] paramValue = arg.Split('=');
                if (paramValue.Length >= 2)
                {
                    switch (paramValue[0].Trim().ToUpper())
                    {
                        case "TO":
                            MailTo = paramValue[1].Trim();
                            break;
                        case "SUBJECT":
                            Subject = paramValue[1].Trim();
                            break;
                        default:
                            throw new InvalidOperationException("Neznámý parametr konfigurace SmtpTraceListeneru v initializeData.");
                    }
                }
            }
        }
        #endregion

        #region SendMessage
        /// <summary>
        /// Interní implementace odesílání mailu.
        /// </summary>
        /// <param name="message">zpráva z trace</param>
        private void SendMessage(string message)
        {
            if (String.IsNullOrEmpty(this.MailTo))
            {
                return;
            }

            try
            {
                MailMessage mailMessage = new MailMessage();
                mailMessage.To.Add(this.MailTo);
                mailMessage.Subject = this.Subject;
                mailMessage.Body = message;
                SmtpClient smtpClient = new SmtpClient();
                smtpClient.Send(mailMessage);
            }
            catch
            {
                // NOOP - nechceme, aby nám nefunkční trace-mailing zabil server
#if DEBUG
                // při debugování nás to ale zajímá
                throw;
#endif
            }

            // http://www.codeproject.com/KB/trace/smtptracelistenerarticle.aspx
            // In the SMTPTraceListener Write method - I call the Flush method. This forces the e-mail output to happen right then, and makes the component more stable.
            // With the Flush taken out of the Write method, I was experiencing some inconsistent behavior - i.e. exceptions thrown sometimes but not always...
            // goofy problem perhaps someone knows why?
            this.Flush();
        }
        #endregion

        #region SendTrace
        /// <summary>
        /// Hlavní interní implementace sestavení mailu.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="data">An array of objects to emit as data. Pokud je string, obsahuje přímo text zprávy.</param>
        private void SendTrace(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
        {
            StringBuilder message = new StringBuilder();
            foreach (object item in data)
            {
                if (item != null)
                {
                    message.AppendLine(item.ToString());
                }
            }
            message.AppendLine();

            message.Append("CommandLine: ");
            message.AppendLine(Environment.CommandLine);

            message.Append("CurrentDirectory: ");
            message.AppendLine(Environment.CurrentDirectory);

            message.Append("MachineName: ");
            message.AppendLine(Environment.MachineName);

            message.Append("UserDomainName: ");
            message.AppendLine(Environment.UserDomainName);

            message.Append(".NET Framework: ");
            message.AppendLine(Environment.Version.ToString());

            if (eventCache != null)
            {
                message.AppendLine();
                message.AppendLine("Call stack:");
                message.AppendLine(eventCache.Callstack);
                message.AppendLine();

                message.AppendLine("Logical operation stack:");
                foreach (object item in eventCache.LogicalOperationStack)
                {
                    if (item != null)
                    {
                        message.AppendLine(item.ToString());
                    }
                }
                message.AppendLine();

                message.Append("DateTime: ");
                message.AppendLine(eventCache.DateTime.ToString());

                message.Append("Timestamp: ");
                message.AppendLine(eventCache.Timestamp.ToString());

                message.Append("ProcessId: ");
                message.AppendLine(eventCache.ProcessId.ToString());

                message.Append("ThreadId: ");
                message.AppendLine(eventCache.ThreadId);
            }

            if (!String.IsNullOrEmpty(source))
            {
                message.Append("Source: ");
                message.AppendLine(source);
            }

            message.Append("EventType: ");
            message.AppendLine(eventType.ToString("g"));

            message.Append("EventId: ");
            message.AppendLine(id.ToString("g"));

            SendMessage(message.ToString());
        }
        #endregion

        #region TraceData (override)
        /// <summary>
        /// Writes trace information, an array of data objects and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="data">An array of objects to emit as data.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, data))
            {
                SendTrace(eventCache, source, eventType, id, data);
            }
        }

        /// <summary>
        /// Writes trace information, an array of data objects and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="data">An array of objects to emit as data.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data, null))
            {
                SendTrace(eventCache, source, eventType, id, data);
            }
        }
        #endregion

        #region TraceEvent (override)
        /// <summary>
        /// Writes trace information, a message, and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="message">A message to write.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, message, null, null, null))
            {
                SendTrace(eventCache, source, eventType, id, message);
            }
        }

        /// <summary>
        /// Writes trace information, a formatted array of objects and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="format">A format string that contains zero or more format items, which correspond to objects in the <paramref name="args"/> array.</param>
        /// <param name="args">An object array containing zero or more objects to format.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, format, args, null, null))
            {
                SendTrace(eventCache, source, eventType, id, String.Format(CultureInfo.InvariantCulture, format, args));
            }
        }
        #endregion

        #region TraceTransfer (override)
        /// <summary>
        /// Writes trace information, a message, a related activity identity and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="message">A message to write.</param>
        /// <param name="relatedActivityId">A <see cref="T:System.Guid"/> object identifying a related activity.</param>
        public override void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId)
        {
            SendTrace(eventCache, source, TraceEventType.Transfer, id, String.Format("{0} : {1}", message, relatedActivityId));
        }
        #endregion

        #region Write, WriteLine (override)
        /// <summary>
        /// When overridden in a derived class, writes the specified message to the listener you create in the derived class.
        /// </summary>
        /// <param name="message">A message to write.</param>
        public override void Write(string message)
        {
            TraceEvent(null, "Write", TraceEventType.Information, 0, message);
        }

        /// <summary>
        /// When overridden in a derived class, writes a message to the listener you create in the derived class, followed by a line terminator.
        /// </summary>
        /// <param name="message">A message to write.</param>
        public override void WriteLine(string message)
        {
            this.Write(message);
        }
        #endregion
    }

Tipy a triky T-SQL z praxe – Slides a dema [TechEd Praha 2010]

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

Záznam z přednášky nebyl pořizován.

Povinné a volitelné parametry v C# 4.0 – Dema [MS Days 2010]

Dema z mého příspěvku na konferenci MS Days 2010 – Demománii:

Ze vstupu nebyl pořizován záznam.

Optimalizace výkonu webových aplikací – Slides, dema a záznam [MS Fest 2010]

Slides a dema z přednášky na konferenci MS Fest 2010 (tentokrát se zaměřením na client-side a přenos):

Z přednášky byl pořizován obrazový záznam (HD 720p), který najdete na našem YouTube Channelu:

Code Contracts – Slides a dema [TechEd Praha 2010]

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

Záznam z přednášky nebyl pořizován.

Ladění výkonu webových aplikací – Slides a dema [TechEd Praha 2010]

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

Záznam z přednášky nebyl pořizován, rozšířená podoba byla však prezentována pro WUG Praha a k té záznam existuje.

WebResource.axd: This is an invalid webresource request. Špatné datum na serveru.

Symptom

Všechny requesty na WebResource.axd (včetně základních na .NET skripty) končí chybou 404 – „This is an invalid webresource request.“, resp. „Toto je neplatný požadavek webového prostředku.“

Cause

Problém byl v tom, že na serveru byl nastaven čas o několik měsíců nazpět.

Jestli tomu vadí, že aplikace byla kompilována později, než je datum/čas na serveru, nebo co konkrétně je problém, to jsem nehledal. Každopádně navrácení korektního data okamžitě problém vyřešilo.