Category Archives: .net

Event: Edinburgh, 1 May – Windows 8 for Application Developers

Calling all Scottish Developers!
Microsoft will be bringing Windows 8 to Edinburgh on May 1st – join the UK team for a day of developer-level, demo-driven sessions and see first-hand the opportunities for designing, developing and selling apps world-wide via the Windows Store.

Windows 8 offers unparalleled new opportunities for application developers to build and sell apps world-wide via the Windows Store. In this event, we’ll deliver developer-level, demo-driven sessions that give you an accelerated entry into what it means to design, develop and publish exciting, modern, polished, world-ready applications for next-generation devices running Windows 8.

Level of knowledge required:

1. A familiarity with .NET development and Visual Studio would be advantageous but not required.
2. We will talk about building Windows 8 applications with JavaScript and with .NET with an emphasis on the .NET technologies.

Agenda (subject to change):

0900 – 0930 Registration Opens
0930 – 1030 Windows 8 for Modern App Development
1030 – 1045 Break
1045 – 1130 Metro Design Language
1130 – 1145 Break
1145 – 1245 “Metro Style” Apps – The Power of the Device Part 1
1245 – 1330 Lunch
1330 – 1430 “Metro Style” Apps – The Power of the Device Part 2
1430 – 1445 Break
1445 – 1545 “Metro Style” Apps – The Power of the Cloud Part 1
1545 – 1600 Break
1600 – 1700 “Metro Style” Apps – The Power of the Cloud Part 2
1700 – 1730 Wrap Up and Close

Click here to register now.

Book: Introducing .NET 4.0: With Visual Studio 2010 by @alexjmackey

Introducing .NET 4.0: With Visual Studio 2010 is a book that many day-to-day developers will benefit from. It provides a great overview of what’s new in .NET 4.0 and Visual Studio 2010 – an obvious statement I know, however what sets this book apart is the fact that it makes reference to the new 4.0 content with references to both the earlier 3.5, 2.0 and 1.1 material. You’ll also find that the author chooses to refer to the Microsoft Developer Network (MSDN) documentation using URLs as opposed to either copying the information verbatim or paraphrasing it some way: a refreshing change. This means that for much of this book, you are presented with straight-to-the-point information about the highs, the lows and the gotchas to look out for when you are building applications using Visual Studio 2010 and the .NET 4.0 platform. If you need a book that covers the salient technical points without going into huge amounts of detail, this is the book for you.

Alex is an experienced developer, he discusses his own personal experiences with many of the .NET 4.0 technologies, providing us with an insight into their history, their strengths and weaknesses – it’s all valuable content that can be hard to source elsewhere. And what’s more, given that this is Alex’s first book, he has done a terrific job: his writing style is contemporary, elegant and is easy to read.

Why should I buy this book?
Don’t be put off by the use of “Introducing” in this book’s title. It’s a book all developers should buy, from beginners to seasoned professionals. Beginners will benefit from the coverage of features, Alex essentially provides a roadmap of the things you need to look at in .NET 4.0 in order to gain the most benefit.

What’s in it for me? What’s this “roadmap” you mention?
Alex covers all of the bases with chapters about the following topics: Visual Studio IDE and MEF, Languages and Dynamic Changes, CLR and BCL Changes, Parallel, Workflow Foundation 4, Windows Communication Foundation, Entity Framework, WCF Data Services, ASP.NET, Microsoft AJAX Library, jQuery, ASP.NET MVC, Silverlight Overview,WPF 4 and Silverlight 3 and Azure. This should provide you with a one-stop shop regarding the current .NET 4.0 technologies and tools: a great resource, especially for newbies, those developers moving to .NET 4.0 from the Java world, etc. and experienced developers looking to make use of new material in their applications.

One of the most common questions I get asked at developer events is “how do I get to know .NET?” – this book is a great source of up-to-date information, “newbies” and those moving to .NET 4.0 from other platforms should rush out and buy this book. Seasoned developers will enjoy the to-the-point writing style, the short code examples and the author’s reach out to “subject matter” experts from the field – if you need to know more, the links are there for newbies and long-in-the-tooth developers!

This book sits nicely in between Pro C# 2010 And The .NET 4.0 Platform 5th Edition by Andrew Troelsen (Hardcover – 3 Mar 2010) and Pro ASP.NET 4.0 In C# 2010 4th Edition by Matthew MacDonald (Paperback – 3 Mar 2010). Alex’s book provides all the groundwork you’ll need in order to be able to tackle the works of Troelsen and MacDonald – Alex’s book is available now!

What are you waiting for? Visual Studio 2010 will be released in a few months time! Get ahead now, buy this book, you won’t regret it!

Further links
Alex’s web-site
The APress web page for Alex’s book

C# Lists, updated to use LINQ

During 2006 I wrote a post about C# Lists. Of course, technology moves on, C# is no exception to that rule.

Whilst the examples I used in the 2006 blog entry still work today, LINQ heralds further levels of elegance and reduced the number of lines of code required to achieve the same results.

Here are the examples updated to use LINQ:

[code lang=”C#”]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
public class Person
{
public int age;
public string name;

public Person(int age, string name)
{
this.age = age;
this.name = name;
}
}

static void Main(string[] args)
{
Listpeople = new List();

people.Add(new Person(50, “Fred”));
people.Add(new Person(30, “John”));
people.Add(new Person(26, “Andrew”));
people.Add(new Person(24, “Xavier”));
people.Add(new Person(5, “Mark”));
people.Add(new Person(6, “Cameron”));

var unsorted = from p in people select p;
var sortedByAge = from p in people orderby p.age select p;
var theYoung = from p in people where p.age < 25 select p; var sortedByName = from p in people orderby p.name select p; foreach (var p1 in sortedByName) Console.WriteLine(string.Format("{0} {1}", p1.name,p1.age)); Console.ReadLine(); } } } [/code] On line 38, simply replace sortedByName with any of the other result sets. The use of LINQ in this simple example does demonstrate increased readability - the LINQ expressions are easier to understand than those present in the 2006 blog entry. If lines of code are your metric (and for some they are!), the LINQ version's conciseness does mean a reduction in the LOC count.

Open XML – Resources

This post serves as a placeholder for my Open XML links, resources, etc. I will update it from time to time.

History
04/11/2008 – I’ve updated the demo code to include the code used in my screencast demonstrating Word 2007 Content Controls.

03/11/2008 – I’ve updated the demo code to include examination of the customXML file that is populated by the content control example (ContentControl.docx). Demo 5 shows how we can inject our own XML into the content controls.

Demo 6 presents the few lines of code required to extract the XML (as populated by the content controls) into an XmlDocument. Once the customXML is in an XmlDocument we are free to access the nodes as required.

Thus we are now in a position were we can create a document with custom data present, pass it to a user, the user can amend the custom data, save the document and send it back to us. We can then extract that custom data for subsequent processing. I will prepare a short screencast to demonstrate this – watch this space.

28/10/2008 – Posted pre-VBUG Newcastle inaugural delivery of An Introduction to Open XML. Download the slides and Visual Studio 2008 / Open XML SDK 2 CTP1 demo code. It’s likely that I will update this code to reflect further CTP releases.

**

Eric White’s blog entry about the first CTP of the Open XML SDK V2.

Microsoft’s primary Open XML portal, OpenXMLDeveloper.org.
Microsoft’s on-line forum for Open XML

OpenXML Code Snippets (for Visual Studio 2005) (Managing code snippets)

Blogs
Brian Jones
Mauricio Ordonez
Doug Mahugh
Kevin Boske
Erika Ehrli
Gray Knowlton’s OpenXML content

Product/Technology Blogs
XPS
Word
Excel

Videos
Open XML File Formats

Using Word 2007 Content Controls
Matthew Scott: Application Development using the Open XML File Formats
Matthew provides an excellent explanation of Word 2007’s content controls and customXML parts. Before OpenXML you probably found yourself using Word bookmarks to leave placeholders inside a Word document – content controls essentially replace those.

Andrew Coates has some excellent information about using Content Controls in conjunction with Matthew’s Word Content Control Toolkit (available on CodePlex).

Technorati Tags: , , , , , , , , , ,

Implementing GetEmailAddressFromExchange in C#

As developers we often find ourselves writing small one off applications to perform a specific “here and now” requirement. The task was to produce a list of e-mail addresses from a Microsoft Outlook folder. I’m reasonably happy with my understanding of the Microsoft Outlook object model, well, happy enough that I’ve managed to get it to do what I need it to do. I am by no means an expert, however since I’ve been making reasonable progress with my “duplicate e-mail remover” application, I figured that iterating over an Outlook folder extracting the e-mail address on they way couldn’t be too hard.

Indeed, for SMTP e-mail addresses, it’s fairly straightforward – a mail message in Outlook has a SenderEmailAddress property that holds the e-mail address in the format name@domain.com.

In a corporate environment you may find X400 formatted addresses similar to this one:

/O=/OU=GLOBAL/CN=RECIPIENTS/CN=FBUTCHER76409312

The aforementioned SenderEmailAddress is also used to store this address, so if you were expecting an SMTP address, too bad!

However, mail messages also have a string property SenderEmailType which returns EX for mail items that use Exchange Server addressing. Here’s how you might use it:

               // Catch e-mails sitting on an Exchange Server...
                            if (oMsg.SenderEmailType == "EX")
                            {                                
                                display = GetEmailAddressFromExchange(oMsg.SenderName);
                            }
                            else
                                // Otherwise, assume SMTP addresses
                                display = string.Format("{0}", oMsg.SenderEmailAddress);

The eagle-eyed reader will have noticed the call to GetEmailAddressFromExchange. I really wanted an SMTP address for all the mail items in the folder(s) in question. A little bit of searching revealed this well-written article by Julian Biddle at An Original Idea.

Julian’s article explained how to get an e-mail address from an Exchange Server address using Visual Basic in .NET. I prefer to use C#, so set about converting Julian’s code (which was known to work). There are other flavours of this code floating on the Internet, this one works for me, your mileage may vary.

The entire application can be downloaded here. This little application is crude, but it solved a problem for me at the time of writing. It demonstrates how to iterate over Microsoft Outlook folders (not just the Inbox) building a treeview on the way. It also demonstrates how to save the contents of a ListView control to a CSV file.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.Outlook;
using System.Runtime.InteropServices;
using System.IO;

namespace OutlookEmailAddressExtractor
{
    public partial class frmExtractEmailAddresses : Form
    {
        public frmExtractEmailAddresses()
        {
            InitializeComponent();
        }

        const int S_OK = 0;

        [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrGetOneProp@12")]
        private static extern void HrGetOneProp(IntPtr pmp, uint ulPropTag, out IntPtr ppProp);

        [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrSetOneProp@8")]
        private static extern void HrSetOneProp(IntPtr pmp, IntPtr pprop);

        [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "MAPIFreeBuffer@4")]
        private static extern void MAPIFreeBuffer(IntPtr lpBuffer);

        [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
        private static extern int MAPIInitialize(IntPtr lpMapiInit);

        [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
        private static extern void MAPIUninitialize();

        const string IID_IMAPIProp = "00020303-0000-0000-C000-000000000046";
        const uint PR_SMTP_ADDRESS = 972947486;

        struct SPropValue
        {
            public uint ulPropTag;
            public uint dwAlignedPad;
            public long Value;
        }

        Microsoft.Office.Interop.Outlook.Application oApp;
        NameSpace oNS;


        private string GetEmailAddressFromExchange(string emailName)
        {
            MailItem loDummyMsg = (MailItem)oApp.CreateItem(OlItemType.olMailItem);
            Recipient loAddress = loDummyMsg.Recipients.Add(emailName);
            loAddress.Resolve();
            string SMTPAddress = GetMAPIProperty(loAddress.AddressEntry.MAPIOBJECT, PR_SMTP_ADDRESS);

            return SMTPAddress;
        }


        private string GetMAPIProperty(object oMAPIObject, uint uiPropertyTag)
        {
            if (oMAPIObject == null)
            {
                return "";
            }

            string sProperty = "";
            IntPtr pPropValue = IntPtr.Zero;

            IntPtr IUnknown = IntPtr.Zero;
            IntPtr IMAPIProperty = IntPtr.Zero;

            try
            {
                MAPIInitialize(IntPtr.Zero);

                IUnknown = Marshal.GetIUnknownForObject(oMAPIObject);

                Guid guidMAPIProp = new Guid(IID_IMAPIProp);

                if (Marshal.QueryInterface(IUnknown, ref guidMAPIProp, out IMAPIProperty) != S_OK)
                {
                    return "";
                }

                try
                {
                    HrGetOneProp(IMAPIProperty, uiPropertyTag, out pPropValue);

                    if (pPropValue == IntPtr.Zero)
                    {
                        return "";
                    }

                    SPropValue propValue = (SPropValue)Marshal.PtrToStructure(pPropValue, typeof(SPropValue));

                    sProperty = Marshal.PtrToStringAnsi(new IntPtr(propValue.Value));
                }
                catch (System.Exception ex)
                {
                    throw ex;
                }
            }
            finally
            {
                if (pPropValue != IntPtr.Zero)
                {
                    MAPIFreeBuffer(pPropValue);
                }

                if (IMAPIProperty != IntPtr.Zero)
                {
                    Marshal.Release(IMAPIProperty);
                }

                if (IUnknown != IntPtr.Zero)
                {
                    Marshal.Release(IUnknown);
                }

                MAPIUninitialize();
            }

            return sProperty;
        }

        

        void _PopulateFolderList(MAPIFolder oFolder, TreeNode node)
        {
            foreach (MAPIFolder folder in oFolder.Folders)
            {
                string s =String.Format("{0} ({1}) [{2}]", 
                                        folder.Name, 
                                        folder.Folders.Count, 
                                        folder.Items.Count);
                
                TreeNode thisNode = node.Nodes.Add(s);

                thisNode.Tag = folder;

                if (folder.Folders.Count > 0)
                {
                    _PopulateFolderList(folder, thisNode);
                }
            }
        }

        private void btnGetFolders_Click(object sender, EventArgs e)
        {
            oApp = new Microsoft.Office.Interop.Outlook.Application();
            oNS = oApp.GetNamespace("MAPI");

            progressBar.Minimum = 0;
            progressBar.Maximum = oNS.Folders.Count;
            progressBar.Value = 0;

            this.Cursor = Cursors.WaitCursor;

            foreach (MAPIFolder f in oNS.Folders)
            {
                TreeNode node = tvOutlookFolders.Nodes.Add(f.Name);

                if (f.Name != "Public Folders" && f.Name != "Internet Calendars")
                    _PopulateFolderList(f, node);

                progressBar.Value++;
            }

            progressBar.Value = 0;
            this.Cursor = Cursors.Arrow;
        }


         

        private void btnGetEmailAddresses_Click(object sender, EventArgs e)
        {
            TreeNode nodeSelected = tvOutlookFolders.SelectedNode;
            MAPIFolder folder = (MAPIFolder)nodeSelected.Tag;

            this.Cursor = Cursors.WaitCursor;

            lvEMailInSelectedFolder.Items.Clear();

            if (folder != null)
            {
                progressBar.Maximum = folder.Items.Count;
                progressBar.Minimum = 0;
                progressBar.Value = 0;

                string sClassComp = "IPM.Note";

                Items oItems = folder.Items;

                label1.Text = oItems.Count.ToString();

                MailItem oMsg = (MailItem)oItems.GetFirst();

                while (oMsg != null)
                {
                    if (oMsg.MessageClass == sClassComp)
                    {

                        if (oMsg.Body != null)
                        {
                            string display;

                            // Catch e-mails sitting on an Exchange Server...
                            if (oMsg.SenderEmailType == "EX")
                            {                                
                                display = GetEmailAddressFromExchange(oMsg.SenderName);
                            }
                            else
                                // Otherwise, assume SMTP addresses
                                display = string.Format("{0}", oMsg.SenderEmailAddress);

                            bool okToAdd = true;
                                
                            if (cbIgnoreDuplicates.Checked)
                                okToAdd = lvEMailInSelectedFolder.FindItemWithText(display) == null;

                            if (okToAdd)
                            {
                                ListViewItem item;
                                item = lvEMailInSelectedFolder.Items.Add(display);

                                item.SubItems.Add(oMsg.SenderName.ToString());

                                if (oMsg.Subject != null)
                                    item.SubItems.Add(oMsg.Subject.ToString());
                                else
                                    item.SubItems.Add(" ");

                                item.SubItems.Add(oMsg.SenderEmailType);
                            }
                        }
                    }

                    bool exceptionRaised = true;

                    while (exceptionRaised)
                    {
                        try
                        {
                            oMsg = (MailItem)oItems.GetNext();
                            progressBar.Value++;
                            exceptionRaised = false;
                        }
                        catch
                        {
                            exceptionRaised = true;
                        }
                    }
                }

                lvEMailInSelectedFolder.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);

                btnSaveToCSV.Enabled = true;

                progressBar.Value = 0;

                this.Cursor = Cursors.Arrow;
            }
        }

        private void btnSaveToCSV_Click(object sender, EventArgs e)
        {
            StringBuilder listViewContent = new StringBuilder();

            foreach (ListViewItem item in this.lvEMailInSelectedFolder.Items)
            {
                listViewContent.Append("\"");
                listViewContent.Append(item.Text);
                listViewContent.Append("\"");

                listViewContent.Append(",");

                listViewContent.Append("\"");
                listViewContent.Append(item.SubItems[1].Text);
                listViewContent.Append("\"");
               
                listViewContent.Append(Environment.NewLine);
            }

            saveFileDialog.FileName = "e-mail addresses.csv";
            saveFileDialog.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*";
            saveFileDialog.ShowDialog();

            if (saveFileDialog.FileName != "")
            {
                TextWriter tw = new StreamWriter(saveFileDialog.FileName);

                tw.WriteLine(listViewContent.ToString());

                tw.Close();
            }
        }

        private void tvOutlookFolders_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (tvOutlookFolders.SelectedNode != null)
            {
                btnGetEmailAddresses.Enabled = true;
            }
        }
    }
}

Technorati Tags: , , , , , , , , , , , ,

The importance of calling .Close()

Courtesy of Andrew Westgarth, via IM, I found myself look at Visual Basic code last week. Andrew’s “designer” was having problems editing some files that made up an application that Andrew was developing…seemed that something was keeping a lock on the files such that they couldn’t be edited. I suggested a couple of things, including hard-coding the filename (avoiding use of Server.MapPath) just to see what happened.

However, after a little experimentation, it turns out that the XmlReader instance wasn’t being closed and as such was keeping a lock on the XSL/T file in question. The solution was to call the .Close() method. It’s obvious now, however sometimes whilst in thick of it, it’s very easy forget to call such methods, nobody’s perfect.

Andrew provides a full write-up over here:

***warning contains VisualBasic code***
Can’t Save your XSL/T File? Have You Closed Your XMLReader?/a>

Technorati Tags: , , , ,

Implementing Excel’s STDDEVP in C#

I have been adding functionality to one of my applications. Without going into huge amounts of detail, it’s a C# application that pushes data out to Microsoft Excel – end users like Excel! The functionality that I’m adding was prototyped inside Microsoft Excel using simulated data and…the Excel Analysis Toolpak. To cut a long story short, I really wanted to remove the reliance on the Toolpak. In fact, I really wanted as much of the control element pulled back into the C# application, i.e. I wanted Excel doing more presentation of data and less scripting.

Part of that functionality involved replicating a few of Excel’s statistical functions, most notably STDDEVP (more details here)

Of course, it’s very likely that there’s a .NET implementation available in the .NET Framework…however my brief search was inconclusive, so I set about writing my own. The code you see below will compile and run using Visual Studio 2005. If you are using Visual Studio 2008 you can take advantage of the built in Sum, Average and Count methods (e.g. total = n.Sum(); instead of the foreach…total+=num loop)

[C#, compiled and tested using Visual Studio 2005]

class Program
{
    static public double STDDEVP(params double[] n)
    {
        double total = 0, average = 0;

        foreach (double num in n)
        {
            total += num;     
        }
  
        average = total / n.Length;
        
        double runningTotal = 0;

        foreach (double num in n)
        {
            runningTotal += ((num - average) * (num - average));
        }

        double calc = runningTotal / n.Length;
        double standardDeviationP = Math.Sqrt(calc);

        return standardDeviationP;
    }

    static void Main(string[] args)
    {
        double s = STDDEVP(1, 2, 3, 4, 5, 6, 7);
        Console.WriteLine(s);
        Console.ReadLine();
    }
}

This worked for me – your mileage may vary.

Technorati Tags: , , ,

[Ireland, Dublin] Event – Irish Microsoft Technology Conference 2008

What:
The IMTC 2008, is an 8 track, 40 session extravaganza covering a breadth of Microsoft’s latest emerging technologies. Throughout the festival there will be numerous networking opportunities, coffee and session re-runs.

Now in its third year, the IMTC 2008 is the second of seven major technology conferences in IrishDev.coms IxTC Series 2008. Co-organised with the Irish Microsoft Technology User Group and First Port Jobs, it’s an event by the Irish technology community for the Irish technology community.

The IMTC 2008 is being run over one evening and two action packed days – this is yet another Irish tech conference you cannot afford to miss!

When:
Begins 7.00pm Wednesday 2nd April with Keynotes, 40 technology sessions on Thursday and Friday 3rd and 4th, concluding with post conference drinks.

It’s not free, but at €189 for two days and an evening of technical content, it’s excellent value!

I’ll be speaking at this event – Test-Driven Development and Code Coverage using Visual Studio 2008 Professional.

Further information:
http://imtc.firstport.ie/

Technorati Tags: , , , , , , , , , ,

Free Microsoft Press E-Book (Introducing Microsoft LINQ)

Via the MSDN Ireland blog and Mick Lohan, I discovered an e-Book and some sample chapters are available for free download.

Introducing Microsoft LINQ
by Paolo Pialorsi and Marco Russo
ISBN: 9780735623910

Chapter 1: LINQ Introduction
Chapter 2: C# Language Features
Chapter 3: Visual Basic 9.0 Language Features
Chapter 4: LINQ Syntax Fundamentals
Chapter 5: LINQ to ADO.NET
Chapter 6: LINQ to XML

Introducing Microsoft ASP.NET AJAX
by Dino Esposito
ISBN: 9780735624139

Chapter 1: The AJAX Revolution
Chapter 5: The AJAX Control Toolkit

Introducing Microsoft Silverlight 1.0
by Laurence Moroney
ISBN: 9780735625396

Chapter 1: Silverlight and User Experience
Chapter 5: Programming Silverlight with JavaScript

Here’s the link you’ll need:

http://blogs.msdn.com/ireland/archive/2008/01/21/free-microsoft-press-e-book-introducing-microsoft-linq.aspx

Original post via Ronan Geraghty.

Technorati Tags: , , , , , , , , , , , , , ,

Free C# 3.0 Training

I am pleased to announce that InnerWorkings, one of the sponsors for DDD6 last November are keeping their free training offer open for a little longer! Huge thanks to InnerWorkings for their generosity!

InnerWorkings has teamed up with DDD 6 to offer you 1 hour of completely FREE training on Visual Studio 2008. So if you want to know more about the important new features in C# 3.0, check out the following hands-on learning material:

Anonymous types and Object and Collection initializers (30 minutes)
Basic LINQ queries (30 minutes)

To claim your free training, please visit this page:
http://www.innerworkings.com/promotions/120/ddd-offer

InnerWorkings also offer trials of their other training:

Object Oriented Programming with Visual C# 2005
Object Oriented Programming with Visual Basic 2005
ASP.NET Web Development with Visual C# 2005
ASP.NET Web Development with Visual Basic 2005
Programming with Visual C# 2003
Programming with Visual Basic 2003
Using ASP.NET AJAX Extensions with Visual C# 2005
Using ASP.NET AJAX Extensions with Visual Basic 2005

Catch up with the InnerWorkings blogs over here.

Technorati Tags: , , , , , , ,