Andri Yadi

A geeky technopreneur, trying to do something big with his startup

March 2010 - Posts

  • Preparing SMTP Service for Sending Alert in SharePoint 2010

    OK, posting cepat aja supaya gak kelupaan.

    To send email-based alerts on SharePoint, you need to configure outgoing e-mail settings first. Sebenarnya cukup mudah untuk men-setting outgoing email pada SharePoint 2010. Buka SharePoint 2010 Central Administration, klik quick launch System Settings, and you’ll find following screen.

    image

    Clicking Configure Outgoing e-mail settings, and you’ll find this screen:

    image

    Just type Outgoing SMTP Server host/IP address, From email address, Reply-to email address, and select Character set. DONE. Now, the real challenge is preparing SMTP service to be used for sending emails from SharePoint, including alerts.

    Basically, you can use any SMTP server. But to me, I prefer to use the built-in SMTP Server in Windows Server 2008 R2. Akan tetapi, SMTP Server dalam Windows Server, yang biasa dikenal sebagai IIS SMTP Service, is not full-fledge mail server. In this case, I will use this IIS SMTP Service as a relay to Gmail. This walkthrough should be the same for other mail server, other than Gmail.

    Installing SMTP Server feature

    AFAIK, SMTP Server is not installed by default in Windows Server 2008 R2, probably in previous Windows Server as well. To make sure it’s installed or not, open Server Manager, click Features, you should see this screen if it’s installed.

    image

    If not, just click Add Features, then select SMTP Server. Will show the question to activate other features that SMTP Server has dependency with, e.g. IIS 6.0 Manager. Just accept them all unless you know what you’re doing. Supposed to be easy task.

    And make sure your paranoid firewall don’t block incoming connection to port 25.

    Configuring SMTP Server

    I assume the SMTP Server is installed successfully, tibalah saatnya untuk mengkonfigurasinya. As I said, I will use this SMTP Server as a relay to Gmail mail server.

    1. Open IIS 6.0 Manager

    image

    2. ‘Singkapkan’ (ckckck…singkap…) hostname dimana SMTP service berjalan (ingat2 hostname/IP address host ini untuk konfigurasi di SharePoint nanti), sehingga muncul “SMTP Virtual Server #1”. Click kanan padanya –> click Properties, dan tampillah:

    image

    3. Click Access Tab, you’ll find:

    image

    Click Authentication button, you’ll find Authentication dialog as above. Make sure you select Anonymous access, karena akan membuat hidup Anda lebih mudah ketika berhubungan dengan SharePoint. Seperti dapat dilihat pada gambar kedua di atas, tidak ada input untuk memasukkan data authentication.

    4. Click Relay button, and you’ll find Relay Restrictions dialog. Here you can specify which computers that are able to use this SMTP Server as relay, by selecting “All except the list below” and adding computers’ IP address. I leave it empty for now.

    image

    5. Now, get you mouse to Delivery tab. I prefer this settings for Outbound.

    image

    Click Outbound Security. Then select Basic authentication. Type your username and password for authenticating to relay mail server. For Gmail, input your Gmail email address and password. Also for Gmail, make sure to check “TLS encryption”. Click OK.

    image

    Back to Delivery tab, now click “Outbound connections”. You’ll have screen as follow. For Gmail, use TCP port 587. Click OK.

    image

    Now, back to Delivery tab, click “Advanced…” button. Type you FQDN mail domain. For Gmail, make sure to type smtp.gmail.com for Smart host.

    image

    That’s it.

    5. Go to SharePoint Central Administration for updating Outgoing email settings with this SMTP service host/IP address.

    image

    Ya seperti yang ditulis di atas, input IP address/hostname where the SMTP Server is running. Also input “From address” and “Reply-to address”. Make sure to use available email address in Gmail. It would be good if you use the same email address as inputted on Outbound Security - Basic authentication.

    For more details about outgoing email settings, refer to: http://technet.microsoft.com/en-us/library/cc263462(office.14).aspx#section1

    6. Testing alert

    Now setup your alert in SharePoint (I won’t show you how). Trigger it. Hopefully the alert email is sent. If not, go back and make sure you follow the walkthrough carefully, and use your developer/IT pro’s instinct to solve the problem.

    That’s it. Good luck.

    Share this post: | | | |
  • WCF Data Services for Office Business Application & Mobile Development

    That’s the title of my speaking on an event entitled “SMILE 2.0”. SMILE 2.0 was held at Universitas Pendidikan Indonesia, Bandung, on March 13, 2010, which is a successor of the first SMILE held a year ago.

    Yes, my name and topic is not on the banner since I was told to speak just a week earlier. But I can prove you that I was there and talked on the event by these photos :)

    _MG_7246 copy

    _MG_7251

    _MG_7255
    The audience

    _MG_7277 copy
    The speakers and committee

    Let’s jump to the topic. Honestly, it’s quite heavy to be consumed by college students. It’s not fun at all, contrary with the tagline of the event, “Microsoft for fun” (I think it’s supposed to be “Microsoft technologies for fun”). However, I think it’s my responsibility as IT practitioner and entrepreneur to update them with the latest trends in IT business, that is hopefully encouraging them to prepare for the future. I focused on one of IT trends in 2010 (and years before), which is cloud computing. Anyway, I did demoing something fun to close the show, which is developing mobile application to work with WCF data service.

    Back to cloud computing, it is all about on-demand internet-based computing which enables users and developers to produce and consume services without the knowledge of, or having to spend efforts and costs to maintain the technological infrastructure that supports those services. Take for example Microsoft’s cloud computing platform, Windows Azure, which offers among other things a data service through its Windows Azure Storage. It allows developer to produce and consume data services without having to know how to actually store and manage the data. One of supported data is Windows Azure Table which is the structured storage supporting massively scalable tables in the cloud. One of its enabler technology, used for exposing and consuming the table data, is Windows Communication Foundation (WCF) Data Services.

    WCF Data Services is formerly called ADO.NET Data Service, which formerly called Astoria. It is basically a Microsoft’s RESTful implementation for data-centric services on the web. In fact, it’s the first Microsoft’s technology that fully embrace REST architecture and implement the latest standard for data sharing over the web, “OData” or Open Data Protocol. WCF Data Services allows other technologies like Microsoft SharePoint 2010 to publish its list and libraries in RESTful way.

    100313120300 - Astoria (dragged) 1

    Why changing the name you ask? Read here. WCF Data Services naming will be formally used with the release of .NET 4.0 and Visual Studio 2010. So, you’ll expect WCF Data Service when you add a new item on a web project. It’s there on Visual Studio 2010 RC, I think it’s not there on Beta 2.

    Some new features of WCF Data Services on .NET 4.0, and also currently publicly available on .NET 3.5 SP1 by applying Data Services Update for .NET 3.5 SP1, can be watched here. I write the list here:

    • Projections: This feature extends the WCF Data Services URI format by adding the $select query option to enable clients to explicitly define the properties to be returned. 
    • Data Binding:  The data services client library for the .NET Framework 3.5 SP1 has been extended to support two-way data binding. 
    • Row Count: As the feature name suggests, it allows returning the total number of entities in a set by counting it on the server-side, instead of retrieving the entities to the client and counting it on client-side.
    • Feed Customization (aka "Web Friendly Feeds").
    • Server Driven Paging (SDP).  
    • Enhanced BLOB Support: This feature enhances the BLOB support provided in V1 to enable data services to stream arbitrarily large BLOBs, store binary content separate from its metadata, easily defer the loading of BLOB content when its metadata is requested, etc. 
    • Request Pipeline   
    • New "Data Service Provider" Interfaces for Custom Provider Writers.

    OK, let’s get started to create a WCF Data Service. In my speaking, I did a showcase that uses architecture like this:

    100313120300 - Astoria (dragged) 3 

    Are you wondering what icon on the left side of Data Services Client? More story about that later.

    Creating WCF Data Service

    As described above, WCF Data Service is about data service over the web. So, to create one you need to create website/web application project on Visual Studio. I’ll use VS 2010 RC. Walkthrough:

    1. Create a Web Application project

    File –> New –> Project

    image

    VS 2010 will create a Web Application project with a bunch of folders and files you might not need them, including Account folder (for storing login pages), Style folder (CSS file) Site.master (master page), . Don’t be scare to erase them as right now we only focus to WCF Data Services.

    2. Create an Entity Data Model

     

    Right Click on your project in Solution Explorer and select ‘Add New Item’, choose ‘ADO.NET Entity Data Model’ and give your model a name:

    image

    You’ll face a Wizard to generate entity from database or creating empty model. Select the first one and Next. then, select the database and specify connection string name to be stored in web.config. I’ll use the “Northwind” database, and NorthwindEntities for connection string name which will be also used as the name of main entry class to work with database using ADO.NET Data Framework.

    image image

    Select the database objects to generate for your model, for example: Categories, Customers, Order Details, Orders, Products, and Shippers. Give the namespace for generated model classes, I’ll use Northwind.Model.

    image

    Done. You’ll have Entity Data Model for Northwind database.

    3. Create a WCF Data Service

     

     

     

     

    Again, “Add New Item” to the project. This time, select WCF Data Service and name it Northwind.svc, for example.

    image

    It will generate two files: Northwind.svc and Northwind.svc.cs. Northwind.svc.cs contains a class which represents the skeleton of data service. Change it to something like this:

       1: using System.Data.Services;
       2: using System.Data.Services.Common;
       3:  
       4: namespace WcfDataServiceTest
       5: {
       6:     public class Northwind : DataService<NorthwindEntities>
       7:     {
       8:         // This method is called only once to initialize service-wide policies.
       9:         public static void InitializeService(DataServiceConfiguration config)
      10:         {
      11:             // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
      12:             // Examples:
      13:             config.SetEntitySetAccessRule("*", EntitySetRights.All);
      14:             //This is new in ADO.NET Data Service v1.5 and WCF Data Services in .NET 4.0
      15:             config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
      16:             config.UseVerboseErrors = true; //for debugging-purpose only
      17:         }
      18:     }
      19: }

    4. Now, test the Service

    Right click to Northwind.svc file and View in Browser. You should have something like this:

    image

    Let’s test to query data by writing this URL on IE address bar: “http://localhost:1281/Northwind.svc/Categories”. You’ll have:

    image

    Consuming the Data Service

    Now, the service is up and running, it’s time to consume it from client. Several months ago, I posted an Excel-based Office Business Application (OBA) to work with WCF Data Services. For this demo, and I showed on my speaking, I’ve written a sample Microsoft Word 2010-based OBA/VSTO. The app looks like this:

    image

    When I click to an input or content control beside the Customer ID, a customer data grid view will be displayed on action pane . Selecting a row on that data grid view will fill the content control. By this mechanism, I don’t have to fill Customer ID input by typing it. That is the good way to implement list of values inside office application.

    image

    When I click to Product Table, a Product data grid will be shown on action pane. I can use it to select ordered product. By clicking a product row, Product Table will be filled with Product ID, Product Name, and Unit Price. All you have to type is Quantity. Cool huh? :)

    image

    I will not write the detail about how to implement this application. Please download the source code below and start to play around with it.

    Presentation slide:

    I’ll write more postings about consuming the WCF Data Service from other platform/technologies. Just stay tune.

    Share this post: | | | |
  • DateTimePicker Control for Excel-based Application using VSTO

    I recently did a Proof of Concept (PoC) at one of the largest plantation company in Indonesia. The PoC was about creating an Excel-based Office Business Application (OBA) using VSTO for managing their vehicles usage. Can’t say much about the app. One thing I can tell you about and I’ll write in this post is there’s a need to select/pick date and time from within Excel worksheet. Off course, you can just type in the date and time value and Excel will validate it, and certainly it will tell you if there’s error in typed value. But, what about if I want to select the value from a date/time picker, how do I create that functionality using VSTO?

    The easiest way is using Windows Forms control’s DateTimePicker. I assume you’ve create the VSTO Excel project. Open Excel worksheet, and drag the control. Then, you have the picker. Let’s run it.

    image

    Well, it works.

    image

     

    Now, let’s change zoom level to a bigger or less than 100%, then click the DateTimePicker, what happens? I’m sure you’ll get this message.

    image

    As far as my VSTO kung-fu goes, there’s nothing we can do about it. If somebody knows how to cheat it, please share. Then your kung-fu is certainly better than mine :)

    So, should we give up? No way. Instead, let’s change the way to accomplish the same things and start working the workarounds. I’ve managed to create a some kind of control for this purpose. I’ll explain some main parts of the control, and you can always skip it to download the source code.

    The Control

    The control is a date time picker for selecting a date/time and filling the selected date/time to a specified target cell. The control will be displayed by double clicking the cell, like the nature of Excel behavior if you want to edit a cell value. Off course, the control should be displayed at exact position as the target cell. The control is basically a Windows Form like below.

    image

    Let’s see what is behind the scene. Make sure you add reference to .NET libraries shown above.

    Properties and Constructors

    Some properties and constructors added in the form class:

       1: /// <summary>
       2: /// Get the selected date time value
       3: /// </summary>
       4: public DateTime SelectedDateTime
       5: {
       6:     get { return TheDateTimePicker.Value; }
       7: }
       8:  
       9: /// <summary>
      10: /// Reference to worksheet. Used for getting some values when positioning this form
      11: /// </summary>
      12: public Tools.Worksheet Worksheet { get; set; }
      13:  
      14: /// <summary>
      15: /// Reference to target cell/range where the control should be displayed.
      16: /// </summary>
      17: public Excel.Range TargetCell { get; set; }
      18:  
      19: public DateTimePickerForm()
      20: {
      21:     InitializeComponent();
      22:     //Default format
      23:     TheDateTimePicker.CustomFormat = System.Threading.Thread.CurrentThread.CurrentUICulture.DateTimeFormat.ShortDatePattern + "  HH:mm";
      24:     this.Load += new EventHandler(DateTimePickerForm_Load);
      25: }
      26:  
      27: public DateTimePickerForm(Tools.Worksheet Worksheet, Excel.Range TargetCell): this() {
      28:     this.Worksheet = Worksheet;
      29:     this.TargetCell = TargetCell;
      30: }

    Location, location, location

    I tell you something, creating the control is easy. When it come to position it on Excel worksheet, it is the real challenge. I want the control to be positioned at exact position where the target cell is located. How do I do that?

    The logic should be simple. Just get the Left (x) and Top (y) position of the target cell, and assign them to form’s Left and Top properties. It’s quite right, but let’s change the zoom level, you’ll get unexpected result. For that, we need to take zoom value into account, as shown in below code.

       1: void DateTimePickerForm_Load(object sender, EventArgs e)
       2: {
       3:     ChangeFormPosition();
       4: }
       5:  
       6: private void ChangeFormPosition()
       7: {
       8:     int relativeLeft = 0;
       9:     int relativeTop = 0;
      10:     //Get current worksheet zoom, so the form will be positioned correctly againts any zoom value
      11:     int zoom = Convert.ToInt32(Worksheet.Application.ActiveWindow.Zoom);
      12:  
      13:     for (int index = 1; index < TargetCell.Column; index++)
      14:     {
      15:         relativeLeft += Convert.ToInt32(Math.Round((double)((Excel.Range)Worksheet.Cells[1, index]).Width * 4 * zoom / 300, 
      16:                                                     MidpointRounding.AwayFromZero));
      17:     }
      18:  
      19:     //Convert cell left position (in point) to pixel
      20:     int left = Worksheet.Application.ActiveWindow.PointsToScreenPixelsX(relativeLeft);
      21:  
      22:     for (int index = 1; index < TargetCell.Row; index++)
      23:     {
      24:         relativeTop += Convert.ToInt32(Math.Round((double)((Excel.Range)Worksheet.Cells[index, 1]).Height * 4 * zoom / 300, 
      25:                                                     MidpointRounding.AwayFromZero));
      26:     }
      27:  
      28:     int top = Worksheet.Application.ActiveWindow.PointsToScreenPixelsY(relativeTop);
      29:  
      30:     this.Left = left; 
      31:     this.Top = top;
      32: }

    Event handlers

    The rest of the control’s code is about handling events, especially ‘Enter’ and ‘Escape’ key press. Here we go:

       1: private void TheDateTimePicker_KeyDown(object sender, KeyEventArgs e)
       2: {
       3:     DateTimePickerForm_KeyDown(sender, e);
       4: }
       5:  
       6: private void DateTimePickerForm_KeyDown(object sender, KeyEventArgs e)
       7: {
       8:     //Detect 'Enter' key press. If it does, set dialog result as OK and close the form.
       9:     if (e.KeyData == Keys.Enter)
      10:     {
      11:         this.DialogResult = DialogResult.OK;
      12:         this.Close();
      13:     }
      14:     else if (e.KeyData == Keys.Escape)
      15:     {
      16:         this.DialogResult = DialogResult.Cancel;
      17:         this.Close();
      18:     }
      19: }
      20:  
      21: private void linkLabelOK_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      22: {
      23:     this.DialogResult = DialogResult.OK;
      24:     this.Close();
      25: }
      26:  
      27: private void linkLabelCancel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      28: {
      29:     this.DialogResult = DialogResult.Cancel;
      30:     this.Close();
      31: }

     

    How to Use It?

    The control should be usable in any VSTO Excel project. Here is the walkthrough to use it.

    1. Create a Excel project, let’s say a Excel Workbook project. A Excel workbook should be created and opened. Add reference to the control assembly, in this case I name it “DyCode.VSTO.Controls”. Yes, DyCode is my company :)

    2. Click a target cell where you want to date/time value to fill and where the DatePickerControl to show. Then name it as “DateTime_Cell”, for example.

    image

    3. With the target cell is still selected, look at the Properties window, switch to event view. Double click to BeforeDoubleClick event to add code for its handler

    image

    4. Add code to implement BeforeDoubleClick event handler, something like this. The code should be self-described.

       1: private void DateTime_Cell_BeforeDoubleClick(Microsoft.Office.Interop.Excel.Range Target, ref bool Cancel)
       2: {
       3:     //Cancel it.
       4:     Cancel = true;
       5:  
       6:     //Instantiate the date picker form and pass the Worksheet reference and target cell
       7:     DateTimePickerForm f = new DateTimePickerForm(this, Target);
       8:  
       9:     //If target cell contains value, assign it to the picker.
      10:     DateTime currentValue = DateTime.Now;
      11:     if (DateTime.TryParse((String)Target.Text, out currentValue))
      12:     {
      13:         f.TheDateTimePicker.Value = currentValue;
      14:     }
      15:  
      16:     //Get the selected date/time value
      17:     DialogResult r = f.ShowDialog();
      18:     if (r == DialogResult.OK)
      19:     {
      20:         Target.Value2 = f.SelectedDateTime;
      21:     }
      22: }

    5. Let’s run the project. Double click to the target cell (DateTime_Cell) and you’ll get:

    image

    Not bad, isn’t it? Just grab the source code and play with it and let me know what you think. The source code for both control and project sample is here:

    That’s it.

    Share this post: | | | |
    Posted Mar 07 2010, 09:00 PM by andriyadi with no comments
    Filed under: ,