-1

I'm trying to fetch attachments from a particular folder in Outlook 2010 in a C# Windows Forms app. I have a class called MailInbox that contains the Outlook namespace, inbox, and message objects.

Here is the code for that class and its methods:

public class mailInbox
{
    //declare needed variables for outlook office interop
    public Outlook.Application oApp = new Outlook.Application();
    //public Outlook.MAPIFolder oInbox;
    public Outlook.MAPIFolder idFolder;
    public Outlook.NameSpace oNS;
    public Outlook.Items oItems;
    public Outlook.MailItem oMsg;
    public Outlook.MAPIFolder subFolder;
    public string subFolderName;

    public mailInbox()
    {
        //read the subfoldername from a text file
        using (StreamReader subFolderNameRead = new StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\SuperVerify\config\subfoldername.txt"))
        {
            subFolderName = subFolderNameRead.ReadLine().Trim();
        }

        oNS = oApp.GetNamespace("mapi");

        //oInbox = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);

        idFolder = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Folders[subFolderName]; // use the subFolderName string, read from the config text file, to get the folder from outlook

        oItems = idFolder.Items;
        //oMsg = (Outlook.MailItem)oItems.GetNext();
    }

    public void FetchEmail() // fetches the next email in the inbox and saves the attachments to the superverify folder
    {
        oNS.Logon(Missing.Value, Missing.Value, false, true); //login using default profile. This might need to be changed.
        oMsg = (Outlook.MailItem) oItems.GetNext(); //fetch the next mail item in the inbox
        if(oMsg.Attachments.Count > 0) // make sure message contains attachments **This is where the error occurs**
        {
            for (int i =0; i< oMsg.Attachments.Count; i++)
            {
                oMsg.Attachments[i].SaveAsFile(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\SuperVerify\images\" + oMsg.Attachments[i].FileName); //save each attachment to the specified folder 
            }
        } else //if no attachments, display error
        {
            MessageBox.Show("The inbox folder has no messages.", "TB ID Verification Tool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
    }

    public void changeSubFolderName(string newSubFolderName)
    {
        subFolderName = newSubFolderName;
    }
}

When I click the button that invokes the FetchEmail method, I get the error

System.NullReferenceException: 'Object reference not set to an instance of an object.'

oMsg was null. I thought that

public Outlook.MailItem oMsg;

instantiated the object and that

oMsg = (Outlook.MailItem) oItems.GetNext();

assigned it an Outlook MailItem, but it seems I don't understand what's going on here.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
Nathan
  • 97
  • 2
  • 9

1 Answers1

0

From the documentation which curiously references VB.NET's Nothing instead of null,

It returns Nothing if no next object exists, for example, if already positioned at the end of the collection.To ensure correct operation of the GetFirst, GetLast, GetNext, and GetPrevious methods in a large collection, call GetFirst before calling GetNext on that collection, and call GetLast before calling GetPrevious. To ensure that you are always making the calls on the same collection, create an explicit variable that refers to that collection before entering the loop.

So GetNext will return null if you're at the end of the folder. You'd have to check it for null before attempting to use it.

You can also use oItems.Count to determine that there are no items when you initially access the folder's items. But if Count is one or more you'd still have to check for null, because you're dealing with a collection that can change. Hypothetically someone could remove items from the folder while you're reading it, so you can't get the count up front and then rely on it.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • Hey thanks for the answer. I tried this same code but with GetFirst, and since there's only one message in the mailbox, that would explain why GetNext could fail, but GetFirst failed as well with the same error. Are you familiar enough with this to see if I've set everything up correctly to communicate with Outlook? I appreciate your input! – Nathan Jan 13 '18 at 07:09