Tuesday, 12 March 2013

Programming in HTML5 with JavaScript and CSS3 (70-480)

Just passed another MS Exam: 70-480 "Programming in HTML5 with JavaScript and CCS3"
About two months ago MS sent me an offer for a free exam and I wanted to try this new exam and new examination workflow with new types of questions.
It was quite simple to pass in my opinion.
I watched this set of video lessons: https://www.microsoftvirtualacademy.com/training-courses/learn-html5-with-javascript-css3-jumpstart-training
Also I read this book: http://diveintohtml5.info/
So these two sources of information plus some experience of JavaScript programming was sufficient to pass the exam.

Tuesday, 29 January 2013

How to execute different code if your .NET component is used within web application

I've just discovered a tiny workaround helping me to execute different code inside of .NET component if it is used within a web application:

bool webMode = (System.Web.HttpContext.Current != null);

if (webMode)
{
    // code for web application
}
else
{
    // code for all other types of apps
}

Probably it has some drawbacks and hidden pitfalls but so far it works well...

Friday, 31 August 2012

.NET Application Architecture

I've just finished reading first 6 chapters of a great book ".NET Application Architecture Guide".
In my opinion it is a must-read book for any senior software developer or a software architect (no matter what language you use).
The main point of this book is to provide a basis, a starting point for getting holistic knowledge about modern software architectures.
This book has a lot of references to other articles, books, guidelines which can be used for further study.
I may expect some concerns that this book is outdated because it was released in 2009, but things and technologies described in it is still in use and architectural approach described in it can be used not only for .NET platform. Another concern can be about "obvious" topics covered by this book (in my opinion these topics are not very obvious because I've seen a lot of software products designed with a lot of simple rules broken).
This book is important for me as a set of recipes, references and check lists for software design and this is just priceless!

Sunday, 6 May 2012

Problem steps recorder

Last week I found very useful tool in Windows: Problem steps recorder.
It can be executed as "psr.exe" (from either command line or "Windows+R")
The following window will appear:


Then you can record all the steps, for example, for reproducing a bug or explaining how to do something.
The "Steps Recorder" creates a ZIP file which contains MHTML with steps descriptions and screenshots.
I think it creates a sequence of steps more descriptive then any tester can provide me with.

So now I recommend the testers to use this tool and just send me a ZIP file generated by "Problem Steps Recorder".

Monday, 26 December 2011

My wife's book

Today my wife released her first Kindle book on Amazon http://www.amazon.com/dp/B006Q5R4MK.
So we will see how it works.
This children books is about wise dog and it's thoughts. I hope it could be interesting for English-speaking readers.

Thursday, 15 December 2011

MS SQL Server 2008 Database Developer

I've just passed MS Exam 70-433 and now I'm a Certified SQL Server 2008 Database Developer.

It was not too difficult, especially if currently I'm spending 80% of my work time doing something with SQL Server :)

Tuesday, 13 September 2011

True Permanent Residency

Now I'm a real Permanent Resident of New Zealand.

What does it mean?

Now my visa has no expiration date and I can live in New Zealand, travel outside, return to New Zealand any time. So now I glad that I (and my family) have a safe and nice place to live.

Saturday, 27 August 2011

Online code formatter

I know that a lot of online code formatters are available. I just found this one usuful for me:
http://www.manoli.net/csharpformat/

Number to text



I had to convert number to text and haven't found any nice implemenation in 30 minutes of googling, so I created my own:

using System;
using System.Text.RegularExpressions;

class NumberToText
{
    private static string[] _numbers = { string.Empty, "one", "two", "three",
            "four", "five", "six", "seven", "eight", "nine" };
    private const string _hundred = " hundred";
    private static string[] _numbersT = { "", "ten", "twenty", "thirty",
            "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };
    private static string[] _numbers11_19 = { "", "eleven", "twelve",
            "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
            "eightteen", "nineteen" };
    private static string _thousand = " thousand ";
    private static string _million = "one million and more";

    private static string _ConvertNumber(uint inputNumber)
    {
        string unitStr, tenStr, tenString;
        uint hundreds = inputNumber / 100;
        uint hundredReminder = inputNumber % 100;
        uint tens = hundredReminder / 10;
        uint units = hundredReminder % 10;

        tenString = _numbers[hundreds < 10 ? hundreds : 0]
                + (hundreds > 0 ? _hundred : string.Empty);
        if (tens == 1 && units != 0)
        {
            tenStr = _numbers11_19[units];
            unitStr = string.Empty;
        }
        else
        {
            tenStr = _numbersT[tens];
            unitStr = _numbers[units];
        }

        return string.Format("{0} {1} {2}", tenString, tenStr, unitStr);
    }

    public static string ConvertNumber(uint inputNumber)
    {
        if (inputNumber < 1000)
            return _ConvertNumber(inputNumber);
        else if (inputNumber < 1000000)
            return _ConvertNumber(inputNumber / 1000) + _thousand
                    + _ConvertNumber(inputNumber % 1000);
        else
            return _million;
    }

    public static string RemoveExtraSpaces(string input)
    {
        return Regex.Replace(input, "\\W+", " ").Trim();
    }

    public static void Main(string[] args)
    {
        for (uint i = 1; i < 2000; i++)
        {
            Console.WriteLine(RemoveExtraSpaces(ConvertNumber(i)));
        }
    }
}

RSS for your ASP.NET web site



Some time ago I found how easily RSS Feed can be implemented on ASP.NET web-site using System.ServiceModel.Syndication namespace and classes SyndicationFeed and SyndicationItem

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Text;
using System.Web.UI;
using System.Xml;
using CompanyName.BusinessLayer.Components;
using CompanyName.BusinessLayer.Entities;
using CompanyName.Utilities;

namespace CompanyName.Presentation
{
    public partial class Rss : Page
    {
        string _webSite;

        const string rssTitle = "Test RSS Feed";
        const string rssDescription = "Provides news for Test items";
        const string rssID = "TestRSS";

        /// <summary>
        /// Creates a link to Document
        /// </summary>
        /// <param name="docID">Document version ID</param>
        /// <returns>the URL</returns>
        private string BuildDocumentLink(string docID)
        {
            return string.IsNullOrEmpty(_webSite) ? string.Empty :
                string.Format(CultureInfo.InvariantCulture, "{0}/ContentView.aspx?ID={1}",
                    _webSite, docID);
        }

        /// <summary>
        /// Creates a link to RSS Feed
        /// </summary>
        /// <returns>the URL</returns>
        private string BuildRssLink()
        {
            return string.IsNullOrEmpty(_webSite) ? string.Empty :
                string.Format(CultureInfo.InvariantCulture, "{0}/{1}.aspx",
                    _webSite, WebpageName.Rss.ToString());
        }
        
        /// <summary>
        /// Page load event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            _webSite = Config.GetValue("WebsiteUrl");

            Response.Clear();
            Response.ClearHeaders();
            Response.ContentType = "application/rss+xml";
            EnableViewState = false;

            SyndicationFeed feed =
                new SyndicationFeed(rssTitle,
                                    rssDescription,
                                    new Uri(BuildRssLink()),
                                    rssID,
                                    DateTime.Now);

            WebSession ws = null;
            try
            {
                string client = Request["client"];
                string processId = Request["processId"];

                ws = Authentication.AnonimousLogOn(Config.ConnectionString, client);
                feed.Items = BuildRssFeedList(processId, ws);
            }
            catch (Exception ex)
            {
                feed.Items = ReportError(ex);
            }

            WriteRssContent(feed);

            Response.End();
        }

        /// <summary>
        /// Writes RSS content
        /// </summary>
        /// <param name="feed">the syndication feed object</param>
        private void WriteRssContent(SyndicationFeed feed)
        {
            Rss20FeedFormatter rssFormatter = new Rss20FeedFormatter(feed);
            using (var sw = new StringWriter())
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = Encoding.UTF8;
                settings.Indent = true;

                using (XmlWriter writer = XmlWriter.Create(sw, settings))
                {
                    rssFormatter.WriteTo(writer);
                }
                // TODO: investigate why default content is utf-16
                Response.Write(sw.ToString().Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>",
                        "<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
                Response.Flush();
            }
        }

        /// <summary>
        /// Reports errors
        /// </summary>
        /// <param name="ex">exception</param>
        /// <returns>the list of syndication items with error description</returns>
        private List<SyndicationItem> ReportError(Exception ex)
        {
            List<SyndicationItem> items = new List<SyndicationItem>();

            SyndicationItem item =
            new SyndicationItem("Error occured on data retrival",
                                ex.Message,
                                new Uri(BuildRssLink()),
                                Guid.NewGuid().ToString(),
                                DateTime.Now);
            items.Add(item);

            return items;
        }

        /// <summary>
        /// Retrieves the list of syndication items
        /// </summary>
        /// <param name="processId">Process ID</param>
        /// <param name="ws">web wession</param>
        /// <returns>the list of syndication items</returns>
        private List<SyndicationItem> BuildRssFeedList(string processId, WebSession ws)
        {
            Guid processGuid = new Guid(processId);
            List<SyndicationItem> items = new List<SyndicationItem>();

            // Some data retrieval procedure is here...
            var ctx = ws.TableHelper.DataContext;
            var docVersions = ctx.DocVersions.Where(
                    dv => dv.RecordState == RecordState.Active
                    && ctx.Categories.Any(
                        c => c.CategoryID == dv.CategoryID
                        && c.ProcessID == processGuid
                    )
                ).Select(dv => dv);

            foreach (var dv in docVersions.ToList())
            {
                SyndicationItem item =
                new SyndicationItem(dv.Title,
                                    dv.Title + " - Version: " + dv.Version,
                                    new Uri(BuildDocumentLink(dv.DocVersionID.ToString())),
                                    dv.DocVersionID.ToString(),
                                    dv.PublishedDate);
                items.Add(item);
            }
            return items;
        }
    }
}