Programming Office 365 Jump Start 2

In this series, I will talk about how to start programming with Office 365 in shortest investment of time. I assume my audience will be .NET developers who do not have prior knowledge of Office 365.

Prerequisite: Programming Office 365 Jump Start 1

Exchange Online

Microsoft released Exchange Web Services Managed API SDK for programming messaging solutions for Exchange Online. The SDK is a class library that you can reference in your application and use its methods to connect to Exchange Online and consume its services. Version 1.1 is available at http://bit.ly/z1EY06, but version 1.2 is soon to be released of which documentation can be found here: http://bit.ly/yHcqVE. After installing the SDK, an assembly is available at C:\Program Files\Microsoft\Exchange\WebServices\1.1\Microsoft.Exchange.WebServices.dll for accessing Email, Calendar, Tasks and Contacts hosted in the cloud.

Authenticating to Exchange Online

Using the SDK, authenticating to Exchange Online with admin username and password is fairly easy:

var exchange = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
{
     Credentials = new System.Net.NetworkCredential()
     {
          UserName = "admin@mycompany.onmicrosoft.com",
          Password = "passw0rd!"
     }
};

exchange.AutodiscoverUrl(primaryUser, url => true);

If the user is already logged on to that domain, username and password are not required. Use exchange.UseDefaultCredentials = true instead.

Querying User Availability

Prior to scheduling an appointment among two or more attendees, it is better to check whether they are free/busy at that time. Otherwise, it may result in conflict with other appointments.

var attendees = new List<AttendeeInfo>
{
    new AttendeeInfo()
    {
        SmtpAddress = "attendee1@mycompany.onmicrosoft.com",
        AttendeeType = MeetingAttendeeType.Organizer
    },

    new AttendeeInfo()
    {
        SmtpAddress = "attendee2@mycompany.onmicrosoft.com",
        AttendeeType = MeetingAttendeeType.Required
    }
};

var results = exchange.GetUserAvailability(attendees,
     new TimeWindow(DateTime.Now, DateTime.Now.AddDays(3)),
     AvailabilityData.FreeBusyAndSuggestions);

The code above returns whole bunch of information on availability and suggestions (responsible flag for this was AvailabilityData.FreeBusyAndSuggestions) according to availability of the attendees for next three days. You can go ahead and explore by yourself various types of properties this method reveals, but let us take a look at how we can get access to the suggestions that it made:

foreach (var time in results.Suggestions.SelectMany(suggestion =>
     suggestion.TimeSuggestions))
{
     Console.WriteLine(time.MeetingTime + "\t" + time.Quality);
}

It is also capable of calculating conflicts automatically and return as part of the TimeSuggestion object.

Creating an Appointment

Now that we have learned how to query user’s availability, let us pick up a suggested time and create an appointment:

var appointment = new Appointment(exchange)
{
     Subject = "Discuss Exchange migration",
     Body = "Let us find a migration process that will
              cause least downtime of the service.",
     Start = appointmentTime,
     End = appointmentTime.AddMinutes(30)
};

appointment.RequiredAttendees.Add(
    "attendee2@mycompany.onmicrosoft.com");

appointment.Save(); 

Sending an Email

The quality indicator of a good SDK is that it gives a solid object model and makes it fairly easy to consume services such as sending email while taking care of the underlying complexities associated with communications all by itself:

var email = new EmailMessage(exchange)
{
     Body = "Hello from my cool C# demo.",
     Subject = "Email by code"
};

email.Attachments.AddFileAttachment("c:\\mypic.jpg");
email.ToRecipients.Add("user@mycompany.onmicrosoft.com");
email.Send();

Accessing Folders

In this example, we will get access to a folder and delete all its contents including sub-folders:

var folder = Folder.Bind(exchange,
    WellKnownFolderName.DeletedItems);

folder.Empty(DeleteMode.HardDelete, true);

If we wanted to search for folders that contain certain string, instead of well known folders, we can do so as well. First of all we have to decide our search criteria, then call ExchangeService’s FindFolders method, which takes a folder root to search from, search criteria (filter) and maximum how many folders we are interested in getting in return:

var filter = new SearchFilter.ContainsSubstring(
    FolderSchema.DisplayName, "Reports");

var results = exchange.FindFolders(
    WellKnownFolderName.MsgFolderRoot,
    filter, new FolderView(10));

foreach (var folder in results)
{
    Console.WriteLine(folder.DisplayName);
    // If we have three folders contain 'Reports', output:
    // Annual Reports
    // Monthly Reports
    // Report formats
}

Scheduling Out of Office

Let us schedule an Out of Office automatic reply starting from now for five days, which will send message to people at work only (Internal):

var oofSettings = new OofSettings
{
    InternalReply =
        new OofReply("Hi, thank you for your email, but I am
              out of office."),

    Duration = new TimeWindow(DateTime.Now,
                    DateTime.Now.AddDays(5)),
    State = OofState.Scheduled
};

exchange.SetUserOofSettings(
    "admin@mycompany.onmicrosoft.com", oofSettings);

Notification Streaming

Exchange Web Service SDK allows to listen for change notifications whether it’d be new email arrival, Free/Busy status changed, item created/deleted and so on. Let us see how we can listen for new email arrival:

var subscription = exchange.SubscribeToStreamingNotifications(
    new FolderId[] { WellKnownFolderName.Inbox },
    EventType.NewMail);

var connection = new StreamingSubscriptionConnection(exchange, 30);

connection.AddSubscription(subscription);
connection.OnNotificationEvent += (s, a) =>
    {
        foreach (var item in a.Events.Select(
             notification => notification as ItemEvent))
        {
            Console.WriteLine(string.Format(
                 "Type: {0}, ItemId: {1}",
                 item.EventType, item.ItemId.UniqueId));
        }
    };

connection.Open();

Streaming subscription connection does not allow to persist more than 30 minutes. In order to extend the period of listening time, you will have to subscribe to OnDisconnect event which will be fired upon timeout and then you can invoke connection.Open() once again to establish reconnection and keep listening to the subscribed events.
 

Conclusion

There are countless many things that you can do with the object model. I hope this post has enough exercises to get you started with Exchange Online programming.

Programming Office 365 Jump Start 1

In this series, I will talk about how to start programming with Office 365 in shortest investment of time. I assume my audience will be .NET developers who do not have prior knowledge of Office 365.

Programming Office 365 Jump Start 2

Office 365 Overview

Office 365, publicly made available on June 28, 2011, is a cloud hosted Software + Services offering from Microsoft that includes online versions (read: cloud hosted version) of Exchange Online, and Lync Online, SharePoint Online. Office Web Apps and Office Professional Plus are also included as per plan.

Office 365 is a complete business productivity solution which includes platforms such as SharePoint. Microsoft’s yearly revenue from SharePoint alone is nearly $2B, which gives us a glimpse of the magnitude of success SharePoint has managed to achieve in past 10 years. Because SharePoint is a web application platform, IT Pros and Devs around this industry comprise even bigger of an economics than just that. That also begs a question what is your worth as a developer if you have Office 365 or SharePoint skill in your bag? Office365

Microsoft Exchange is one of the most popular Email, Calendar and Contacts hosting choice for the enterprise. On the other hand, Microsoft Lync, which was formerly known as Microsoft Office Communication Server, is the biggest push from Microsoft to establish itself as an automatic choice in the Unified Communication space. Being the cloud citizen Office 365 offers additional addons to fulfill scaling needs as business grows or shrinks.

Office 365 Plans

As we have just mentioned earlier it is one size fits all, there are three plans to choose from:

  • Professional and small businesses
  • Midsize business and enterprises
  • Education

Enterprises enjoy an additional benefit though, which is being able to offer Office 365 to kiosk users. Some of the scenarios they may cover depending on of course how you use it are Timesheet entry, keep track of schedule on Calendar, Inventory, Request workflows and lookup policies.

Before your company or you decide to go for Office 365, which is as low as $6/user/month, you can always signup for a 30-day trial, which we will use throughout this series for our development work, too.

Full details about plans: http://bit.ly/yIly6l 
How you can deploy to private cloud: http://bit.ly/Aal6LR 
Cost estimator: http://tinyurl.com/78gk5r5

As soon as you have signed up for trial and activated, it gives you control over complete feature-set if you would have purchased a paid subscription as well:

Admin

You can administer everything very easily from this control panel, including user, services, subscriptions, licenses management, etc.

Office 365 Infrastructure Layer

It is hosted on Windows Azure, Microsoft’s cloud, administered via Windows Intune. Windows Intune is a cloud based update and security patches management solution via Web Browser, which by the way, we do not have to worry about, because it is done by Microsoft to keep their Azure infrastructure up-to-date. One of the key benefits of going cloud is that the infrastructure is free from maintenance at consumer level. On top of that, Microsoft guaranties financially backed 99.9% uptime of the service. Therefore, it offers ultimate reliability as well as enterprise-grade security. That said, Microsoft collects no data or put up ads, no document scanning for analytics/mining or improve their service, complete data portability and 5 layers of security: Data, Application, Host, Network and Physical.

All are hosted and configured to work right after your signup, so there is no deployment or configuration really is involved. Furthermore, you can access the same services across different form-factors, such as PC/Mac, Mobile: Windows Phone, Blackberry, iPhone, Android and Symbian. So, according to Forrester survey it came up about more than 300% ROI from Office 365.

Software + Services

Office 365 enjoys generic benefits of going cloud associated with it. However, as a developer you need to know how it is treated in the cloud. In the beginning I have mentioned that Office 365 is a cloud hosted Software + Services offering, before we look into that aspect, let us quickly recap some of the conventional hosting models that we are most familiar with.

Traditional

In traditional Client-Server system, there is a stack of servers for clients to connect over network or internet. As business grows, new servers are to be purchased and as business shrinks servers are needed to be offloaded.

Traditional Cloud/Software as-a Service (SaaS) model solves the problem with scaling up, out and down on business demand. Everything’s hosted in a cloud vendor’s datacenter. If it is Windows Azure, Microsoft has megastructures of datacenters across different continents of the world, which confirms nuclear-bomb-proof part of the cloud feature.

PreCloud

As you can see from the diagram, software is replaced with Cloud based SaaS websites which are accessibly via Web Browser, and rest of the client applications use On-premise servers, ie. locally hosted Lync, Exchange and SharePoint servers.

Software + Services offers best of both worlds, minus the need of network connectivity (managed hosting). Sure, you can use SaaS via Web Browser, but additionally, there are programmable API endpoints, which let Client Applications (App that you will write) to connect and consume services. In this case Exchange, Lync, and SharePoint Online.

S S

Your Apps live on the Client machines, enjoy the faster local data access and processing power, while syncing necessary selective data over the wire from/to the Cloud. These are the kind of apps that we will see how we can write in later posts in this series.

PinPoint: Office 365 Marketplace

Once you have built an app, it is time to go global. You can get yourself listed as vendor as well as your apps as products in the Office 365 Marketplace. Head over to http://pinpoint.com or for detailed guide: http://bit.ly/eMVqaf. Potential customers can then discover your apps and purchase from there, or perhaps even better contact your company for further customization or support. PinPoint allows your company to acquire global reach.

Windows Phone 7.5 Apps In Record Time

I have started writing an evolving micro eBook “Windows Phone 7.5 Apps In Record Time.” It was written as briefly as possible to act as a jump starter for those who have intermediate level of practical experience in C#. However, I can’t call it cheatsheet either, because it’s vision is different than that. I have never thought of writing it until attendees of the 3-hour long workshop that I host on Building Windows Apps weekly at Microsoft Bangladesh demanded so. However, this is not the final edition. I will keep on revising and adding content to it as many as 20 or so pages.

Windows Phone 7.5 Apps In Record Time

I hope this micro eBook will help in a particular way, because it targets a very common and specific audience and speaks to the point without much jibber jabber. By the way, on the 40th Victory Day of my beloved country, Bangladesh, I couldn’t give any better gift than this! Long live Bangladesh.

Installing Bangla in Android

The other day I was trying to install Bangla in Galaxy Mini, which lacks indic support, and cannot render Bengali characters as a result. I have heard of Sony Ericsson Android phones that have built-in support for that. Unfortunately, most phones don’t. Certainly it was time to root this particular phone. Rooting is the process of getting the administrator access to the phone.

Unfortunately, sometimes it looks terrible even after installing Bangla, probably for those which are incompatible with SolaimanLipi that I have used:

SC20111013-191531 SC20111013-191758

However, in response to many of your requests, here are the steps that I have followed to install Bangla in Galaxy Mini:

  1. Install Samsung Kies in your PC, which is the management software including drivers for the phone.
  2. Enable USB Debugging: Go to Settings > Applications > Development > USB Debugging on your Android phone
  3. Connect your phone to the PC
  4. Run SuperOneClick.exe
  5. Make sure your phone’s lock screen is unlocked. Click “Root”. Wait for rooting process to be finished. Allow it install Busy Box.
  6. Reboot phone
  7. Meanwhile, download this SolaimanLipi font that I have chosen. Copy the font to your SD card (inside your phone). I have put it inside a folder, Zim-Exp in my SD card.
  8. Now on your PC, run Command Prompt with Administrative privilege
  9. Now its time to execute some commands. If you know DOS commands, for example cd, go to SuperOneClick folder. Then type the following commands to install the font:
    adb shell <enter>
    su <enter> Wait till $ sign turns into # 
    mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system <enter>
    chmod 4755 /system/fonts/DroidSansFallback.ttf <enter>
    dd if=/sdcard/Zim-Exp/DroidSansFallback.ttf of=/system/fonts/DroidSansFallback.ttf <enter>
  10. Reboot the phone and open a Bangla website in the native browser or Opera Mini

Hope this helps.

Disclaimer: Try it at your own risk. This may void handset warranty. :)

NoBrainer: My New Open Source project

Yesterday we had an electrifying event “Open Source in .NET | Open Day” in collaboration with Microsoft Bangladesh, that I have posted earlier about. In my second session I unveiled my shiny new Open Source project “NoBrainer” which is the topic of this post. The presentation can be viewed here:

NoBrainer is an MVC + CMS Framework, as its name suggests for low-fi developers and savvy business stakeholders. It provides developers the flexibility of MVC as well as the control of WebForm, resulting in a testable and content manageable WebForm infrastructure for you application. NoBrainer currently supports only Web at the launch, however it can easily be extended to work with Desktop as well as Mobile. That way your logic and test code remain the same across different UI layers. Take time and flip over the slides. You will get the understanding what I have tried to achieve with this project. This Framework is used by one of the largest Enterprises and it is serving several millions of their users pretty well.

The Motivation

Converting your WebForms project into ASP.NET MVC is not always a suitable option for you. There is a huge cost associated with conversion, which is in ideal case totally dependent on decision from business stakeholders. On the other hand, if you are one of the business guys and you maintain a pool of developers for your project, chances are that you may want to convert your project into an ASP.NET MVC project. But, when your developers become reluctant to change, and to learn a whole new paradigm of development, you have no choice but stick to the old WebForm, until you use NoBrainer. So, you need a Framework that slowly guides your developers to the MVC practice without sacrificing the convenience of rich and drag & drop designer of WebForms.

Note: This Framework addresses a particular need – it does not necessarily replace the ASP.NET MVC in all aspects.

image

Figure: Data validation and automatic error binding: CMS-driven MVC Framework in action

The project itself is easy to setup and the Sample is concise, so that one who wants to learn can follow easily. This step-by-step walkthrough is also included (as you can see in the Documentation part) in the project.

Note: This project assumes that you have general idea about Model-View-Controller pattern.

Easy Setup

NoBrainer takes a novel approach – WebForm is totally rethought to use with MVC. Follow the steps:

(1) Reference NoBrainer.dll in your web project.
(2) Add the following in your web.config:

<appSettings>
   <!-- Any folder path you want. A folder inside your web project is preferred. -->
   <add key="CmsXmlDirectory" value="D:NoBrainerNoBrainer.SampleContent"/>
</appSettings>

(3) Add this to your Global.asax:

void Application_Start(object sender, EventArgs e)
{
    // Ignite NoBrainer engine.    
    Engine.Boot(() => new NoCache(),
    ConfigurationManager.AppSettings["CmsXmlDirectory"], "xml", "html, htm");
}

Done! Now you are free to choose which WebForm inside your project, you would prefer to convert to MVC pattern.

NoBrainer makes it a breeze to make your WebForm CMS-driven MVC style

Magic of NoBrainer is that you can very slowly start converting your project into MVC. You can take one WebForm at a time. Let us see how we can implement MVC in our Login.aspx page. Follow the steps:

1. Model

Let’s create a Model for our MVC that will be used to hold necessary data to transfer back and forth from and to View and Controller. Notice that the Model was derived from ModelBase which is the base class from NoBrainer to indicate that the class which extends it is actually a Model.

public class AccountModel : ModelBase
{
     public string UserName { get; set; }
     public string Password { get; set; }
     public string Email { get; set; }
     public bool PersistentCookieEnabled { get; set; }
}

2. View (HTML)

Now let’s create the View. Notice that the HTML tags here have several highlighted non-standard attributes. Some of them matches the properties of the Model that we created earlier. Ex. UserName, Password, PersistentCookieEnabled. NoBrainer automatically maps these Model properties without requiring any hand written code.

<!-- Example: Model(you can also say View)-wide common error message -->
 <span runat="server" class="failureNotification" Model="ErrorMessage"></span>

<fieldset class="login">
     <legend>Account Information</legend>
    <p>
        <asp:TextBox runat="server" ID="UserName" CssClass="textEntry" Model="UserName">
                 </asp:TextBox> 

        <!-- Example: automatic error binding from Model to View -->
         <span runat="server" class="failureNotification" Model-Error="UserName"/>
    </p>
    <p>
        <asp:TextBox runat="server" ID="Password" CssClass="passwordEntry" TextMode="Password"
Model="Password"></asp:TextBox> 

        <!-- Example: 
            1. HTML-attribute level CMS capability 
            2. Show/hide CMS driven error message by Cms-Error
        -->
        <span runat="server" class="<%# Cms[&quot;spnPasswordError&quot;].CssClass%>"
                   Cms-Error="Password">

            <!-- Example: strongly typed Model -->
            <%# Cms["spnPasswordError"].Content %>
        </span>
    </p>

    <p>
        <asp:CheckBox runat="server" ID="RememberMe" Model="PersistentCookieEnabled"/>
        <asp:Label ID="RememberMeLabel" runat="server" AssociatedControlID="RememberMe"
                 CssClass="inline">Keep me logged in</asp:Label>
    </p>
</fieldset>

Model-Error is an amazing feature that automatically maps error message sent from Controller to the UI. For example, if user has typed wrong password, NoBrainer will find HTML element having Model-Error = “Password” and update its content to the error message associated with Password.

Cms is a page level dictionary which allows you to put CMS content which come from XML (we will cover that in a while).

Our Model did not have ErrorMessage property. Where did it come from? Well, No Brainer provides bunch of really useful extensions and default properties to help you write MVC friendly WebForm. ErrorMessage is one of them, which contains View-wide generic error message occured. For example: Incorrect username/password combination.

As you can see there is no MVC specific change in WebForm design. You can use your same old WebForm practice, drag and drop controls from the Toolbox, use design-view, etc. whatever you like. However, to make automatic control mapping work, you will have to map Model properties. Even that’s optional too, if you prefer to do that WebForm way. Example: model.UserName = txtUserName.Text in your code-behind file. NoBrainer gives you absolute freedom.

3. View (code-behind)

Let’s take a look at the code-behind of this page. First thing you are going to notice is that the View does not inherit System.Web.UI.Page, rather it does from ViewBase which is the base class for Views provided by NoBrainer. It takes two parameters. First is the Controller name which has the driving logic for this View and the Model type that the Controller and View both will be dealing with. We have declared AccountModel earlier, but AccountController (our Controller) will be implemented in the next step.

public partial class Login : ViewBase<AccountController, AccountModel>
 {
    protected void Page_Load(object sender, EventArgs e)
    {
        if(IsPostBack)
        {
            InvokeController(v => Controller.Login(Model));        

            if(Model.IsValid)
            {
                FormsAuthentication.RedirectFromLoginPage(Model.UserName, Model.PersistentCookieEnabled);
            }
        }
        else
        {
            if(Request.IsAuthenticated)
            {
                Response.Redirect("~/Account/Manage.aspx");
            }
        }
    }
 }

You will also notice that there is a method named InvokeController which is a native NoBrainer method inferred from ViewBase. This method allows you to map View => Model and pass that Model to the designated method you have written in your Controller (in here: Login is a method written inside AccountController. We will see that in a while.). Then the Controller method performs some actions (such as Validation, etc.) and returns the modified Model to the View. The View (web layer/WebForm) then examines the Model and decides what to do next. That way we leave NoBrainer to do the mapping work, and seperate the logic to our Controller.

4. Controller

Now that our Model and View are complete, let’s talk about Controller. We will talk everything via interfaces. Why? Because one of the advantages of using interfaces is that it will allow us to make the Controllers unit testable.

public interface IAccountController
{
    AccountModel Login(AccountModel user);
}

public class AccountController : ControllerBase, IAccountController
{
    public AccountModel Login(AccountModel user)
    {
        /* 
            Example: how Models can be validated and 
            error messages can be sent from Controllers.
        */
        // Example: how error messages can be set from the Controllers 
        if (string.IsNullOrEmpty(user.UserName))
            user.ErrorMessages["UserName"] = "UserName cannot be empty.";

        // Example: how to enable/disable CMS based error messages to the UI
        if (string.IsNullOrEmpty(user.Password))
            user.CmsErrorMessages["Password"] = true;
         if(string.IsNullOrEmpty(user.UserName)
            || string.IsNullOrEmpty(user.Password))
        {
            user.ErrorMessage = "There are errors. Please fix them and try again.";
        }
        else
        {
            if (!Membership.ValidateUser(user.UserName, user.Password))
            {
                user.ErrorMessage = "UserName/Password combination is incorrect.";
            }
            else
            {
                FormsAuthentication.SetAuthCookie(user.UserName, user.PersistentCookieEnabled);
                user.IsValid = true;
            }
        }
        return user;
    }
 }

First thing you are noticing here is that it inherits ControllerBase as well as IAccountController. AccountController has to implement the method (for our case: Login) that we called earlier from View. As you can see it takes an instance of AccountModel, which is later validated whether there’s any error message and then returned the same object in the end after necessary modification.

If you need to set an error message specific to certain property (in here: UserName) of the Model, you should use the Model’s in-built dictionary ErrorMessages to do that. However, should you require to make the error message CMS driven, in other words, your business stakeholders want it to hand-written by themselves outside the application, you should use the other dictionary named CmsErrorMessages. You will create a CMS collection which we will discuss in the last step of this tutorial, that should hold a text representing user.CmsErrorMessages["Password"]. What this piece of code will do is it will turn on/off the text’s visibility (recall: Cms-Error=”Password”). We will look at that later.

Now about the Membership.ValidateUser and use of FormsAuthentication. You can use them. That’s fine! But, if you would like to make your MVC to work across different form factors of computing devices such as Desktop/Mobile, you will have to move it to web layer or plug it from somewhere else to make the Model and Controllers device independant. Because these classes belong to ASP.NET which you do not want to use in Desktop/Mobile.

5. CMS XML

That’s it! Oh, one last thing, because this View (as we have written) requires us to define a CMS variable “spnPasswordError” (see View HTML) for this particular View, we need to define it inside our Content (move to the beginning of this document where we defined CmsXmlDirectory) folder. Let’s create TanzimSaqib.NoBrainer.Sample.Controllers.StaticPageController.xml, which matches the Controller namespace we have in this project. This namespace mapping is important. Put the following XML inside of that.

<?xml version="1.0" encoding="utf-8" ?>
<!-- Example of content injection aka CMS capability -->
<Views>
  <View pageName="AccountLogin.aspx">
    <Content id="spnPasswordError" cssClass="failureNotification">
          Password cannot be empty.</Content>
  </View>
</Views>

As you can see this XML file contains all possible Views that this Controller can handle. For our example of Login screen, we are specifying our View page path as AccountLogin.aspx, inside of that we are defining our CMS variable spnPasswordError, its cssClass as well as the content. These data are modifiable as CMS data as well as injected while rendering the page by NoBrainer.

02 backdrop_net_12x5 

Figure: Open Source in .NET | Open Day, at which NoBrainer was launched

Conclusion

That way you make your logic seperate from the UI layer, which also makes it unit testable, and deployable to many different form factors of computing devices. It also facilitates the power of CMS. You do not have to give business stakeholders full freedom on your code. Just give them FTP access to the Content folder if you will, and they will take it from there. They will never call you up at the dead night to make some changes to the content just because that’s important to their business, rather they could do it by themselves.