Code!

Snippets from my blog where I tried to be a cool code blogger and failed miserably! (Ain't nobody got time for that)

Photo credits to Alexander Sollie

Ext JS hack to use Font Awesome (or any Icon Font Library) as Icon Class


April 16, 2013

Recently, I created a small hack to use the awesome Font Awesome library alongside Ext JS (3.4).

This allows Font Awesome icons to be served as good as the Ext JS icons for Tree Panels. The code sequences the function that removes x-tree-node-icon during the render event and adds the Font Awesome icons. Here is the code –

Ext JS code to replace default tree node class by Font Awesome class
Ext JS 3.4 jQuery
      
        // Add sequence to the render event to replace .x-tree-node-icon
        Ext.sequence(Ext.tree.TreeNode.prototype, 'render', function (treenode) {
            $('.x-tree-node-icon').removeClass('x-tree-node-icon').replaceWith(function () {
            if (typeof($(this).attr('class')) != 'undefined')
                return '<i class="' + $(this).attr('class') + '"/>';
            else
                $(this).addClass('.x-tree-node-icon');
            });
        });

        // Intercept setIconCls so font awesome icons can be set by setIconCls method too
        Ext.intercept(Ext.tree.TreeNode.prototype, 'setIconCls', function (cls) {
            $($(this)[0].ui.elNode).find('i').removeClass().addClass(cls);
        });
      
    

With this code hack, you can set Font Awesome icons like this from Ext Designer. Here is a screenshot -


Upload documents to Sharepoint using Web Services


August 17, 2012

If you're a rookie out there trying to dig your way through Sharepoint Web Services, here is some simple code to manage documents.

To manage documents, you will have to do the following -

Have a DTO (a Data Transfer Object – if necessary) to send the document information (if you are doing AJAX using jQuery or something)

A DTO class for files in a Sharepoint document library
C#
        
      public class DocLibDTO
      {
          public string Id { get; set; }            // ID of the document
          public string Index { get; set; }         // Index of the document
          public string FileName { get; set; }      // File Name
          public string FileTypeIcon { get; set; }  // File Type Icon
          public string CreatedOn { get; set; }     // Created On
          public string FileRef { get; set; }       // Sharepoint File Reference
      }
        
      

Before you upload the file, make sure the file doesn't exist in the document library.

Code to check if the file exists in the document library
C# CAML
        
      /// <summary></pre>
      /// Check if a file / folder exists
      /// </summary>
      /// <param name="FilePath">File Path</param>
      /// <returns>Boolean whether file exists or not</returns>
      public bool CheckFileExists(string FilePath)
             {
            Lists lists = new Lists();
            lists.Url = "https://yoursharepointsite.com/_vti_bin/lists.asmx";

            // Your Sharepoint credentials
            lists.Credentials = new System.Net.NetworkCredential("Username", "Password");

            XmlNode nodes;

            System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
            System.Xml.XmlElement query = xmlDoc.CreateElement("Query");
            System.Xml.XmlElement viewFields = xmlDoc.CreateElement("ViewFields");
            System.Xml.XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions");

            // Look for files whose ID is greater than 0
            query.InnerXml = "<Where><Gt><FieldRef Name=\"ID\" />" +
            "<Value Type=\"Counter\">0</Value></Gt></Where>";

            viewFields.InnerXml = "<FieldRef Name=\"Title\" /><FieldRef Name=\"Description\" />";

            queryOptions.InnerXml = "<ViewAttributes Scope=\"RecursiveAll\"/>";

            // Get List Items from the Sharepoint List Library "UploadList"
            nodes = lists.GetListItems("UploadList", null, query, viewFields, "5", queryOptions, null);

            foreach (System.Xml.XmlNode node in nodes)
            {
                if (node.Name == "rs:data")
                {
                    int index = 1;
                    for (int i = 0; i < node.ChildNodes.Count; i++)
                    {
                        if (node.ChildNodes[i].Name == "z:row")
                        {
                            if (node.ChildNodes[i].Attributes["ows_FileRef"].Value.Split('#')[1] == FilePath)
                            {
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        }
        
      

Depending on what you want to do - if you'd like to create a folder to upload documents, you can use this function. Totally optional!

Code to create a folder in the Document Library
C#
        
      /// <summary>
      /// Creates Folder Method
      /// </summary>
      /// <param name="FolderPath">Folder Path</param>
      /// <returns>Boolean whether success or failure</returns>
      public bool CreateFolder(string FolderPath)
             {
            Dws dws = new Dws();
            dws.Url = "https://yoursharepointsite.com/_vti_bin/dws.asmx";
            dws.Credentials = new System.Net.NetworkCredential("Username", "Password");

            if (!CheckFileExists(FolderPath))
            {
                dws.CreateFolder(FolderPath);
                return true;
            }
            else
            {
                return false;
            }
      }
        
      

Now to the main part - Uploading a file.

Code to upload a file to the Document Library
C#
        
      /// <summary>
      /// Upload File Method
      /// </summary>
      /// <param name="FormCollection">Form Collection from a POST Request</param>
      /// <returns>JsonResult with success & msg</returns>
      [AcceptVerbs(HttpVerbs.Post)]
      public JsonResult UploadFile(FormCollection)
             {
            bool success = false;
            string msg = "";

            if(Request.Files.Count > 0)
            {
                for(int i = 0; i < Request.Files.Count; i++)
                {
                    HttpPostedFileBase postedFile = Request.Files[i];
                    string fileExt = Path.GetExtension(postedFile.FileName).ToLower();
                    string fileName = Path.GetExtension(postedFile.FileName);

                    // With fileExt, you can make sure if you'd like the user to upload that type of file
                    byte[] postedFileBytes = new byte[postedFile.InputStream.Length];
                    postedFile.InputStream.Read(postedFileBytes, 0, (int)postedFile.InputStream.Length);

                    bool CanCreateFile = false;

                    Copy copy = new Copy();
                    copy.Url = "https://yoursharepointsite.com/_vti_bin/copy.asmx";
                    copy.Credentials = new System.Net.NetworkCredential("Username", "Password");

                    // This if condition is optional - Use if if you want to create a parent folder
                    if (!CheckFileExists("YourUploadList" + "/" + "AnyParentFolder"))
                        CanCreateFile = CreateFolder("YourUploadList" + "/" + "AnyParentFolder");
                    else
                        CanCreateFile = true;

                    // Upload the file, if everything looks good aka CanCreateFile
                    if (CanCreateFile)
                    {
                        string[] destinationUrl = { "https://yoursharepointsite.com/list/parentfolder/subfolder/" + fileName };
                        FieldInformation titleInfo = new FieldInformation
                        {
                            DisplayName = fileName,
                            InternalName = fileName,
                            Type = FieldType.Text,
                            Value = fileName
                        };

                        FileInfo file = new FileInfo(fileName);
                        string sourceUrl = file.FullName;
                        FieldInformation[] metaData = { titleInfo };

                        CopyResult[] result;
                        uint op = copy.CopyIntoItems(sourceUrl, destinationUrl, metaData, postedFileBytes, out result);

                        // Upload was successful
                        if(op == 0)
                        {
                            success = true;
                            msg = "Upload successful!"
                        }
                        // There was an error
                        else
                        {
                            success = false;
                            msg = "Couldn't upload file!"
                            break;
                        }
                    }
                    // Couldn't create folder - Optional
                    else
                    {
                        success = false;
                        msg = "Couldn't upload file!"
                        break;
                    }
                }

                return Json(new { success = success, msg = msg });
            }
            else
            {
                return Json(new { success = false, msg = "No files found!" });
            }
      }
        
      

Using Isolated Storage


October 26, 2010

Isolated Storage is nothing but a storage location in a user’s local filesystem where applications can store data. It is generally exploited by web applications to store information of any kind (application data, user data, session state etc).

The initial quota for a Isolated Storage is 1MB, which could be modified later using code.

The Isolated Storage data in Windows is usually located here - C:\Users\<User Profile>\AppData\Local\IsolatedStorage

Here is a simple code to show how Isolated Storage can be exploited -

A really simple way to use Isolated Storage
C#
              
        using System.IO.IsolatedStorage;

        private void SaveUserData(string UserName, string Pwd, int UserNumber)
        {
            var file = new XDocument(
                new XElement("UserNum", UserNumber,
                new XElement("UserName", UserName),
                new XElement("Password", Pwd))
            );

            using(IsolatedStorageFile isf = new IsolatedStorageFile.GetUserStoreForApplication())
            {
                IsolatedStorageFileStream isfs=new IsolatedStorageFileStream("File1", FileMode.Append, isf);
                file.Save(isfs);
            }
        }
              
            

In the above code, the GetUserStoreForApplication() method gets the next available storage location available for the application. In order to store data for the entire site, use GetUserStoreForSite().

You can increase the Isolated Storage space by doing something like the following -

Code to increase isolated storage space
C#
              
        int a = 2048000;

        // This will increase the space to 2MB
        isf.IncreaseQuotaTo(a);
              
            

Silverlight typically uses Isolated Storage. To view quotas of different Silverlight applications Right click the Silverlight Application > Select Silverlight > Application Storage
You'd see something like this -

Nested Data Binding - Silverlight


October 10, 2010

Data Binding in Silverlight is pretty cool. You can basically bind a UserControl to a collection of data.
A good example for data binding would be - Imagine a tree of depth say 1000. Instead of adding 1000 TreeViewItems manually, you can write a few lines of code to bind your TreeView to a Collection. Here is a basic example to bind a TreeView to a data source. For a nested binding (a node within a node), a DataTemplate uses another DataTemplate as it's ItemTemplate.

It's best practice to add the Template (DataTemplate or HierarchicalDataTemplate) to any UserControl’s Resource which is at a higher level and at a scope of visibility to the desired control. This facilitates code re-usability by the child controls.

As an example I created this sample application, where a HierarchicalDataTemplate uses another HierarchicalDataTemplate as ItemTemplate. The simplest example I could think of was a collection of Files and Folders.

Though the idea was something like an File Explorer. I used a simple File and Folder collection just to show how nested binding works. To make the application look like a File Explorer, I created a Grid with two columns containing a TreeView on the left pane and a ListBox on the right pane. Having created controls which can contain Items, I create two HierarchicalDataTemplates - one for files and the other for the folders. To keep it simple, I use a StackPanel which holds an Image and a TextBlock which has the File / Folder’s name as its Text.

Something like this -

Code for the file and folder template
XAML
            
          <common:HierarchicalDataTemplate x:Name="template2">
            <StackPanel Orientation="Horizontal">
                <Image x:Name="imgTemplate2" Source="Images/file-icon.png" Height="15" Width="15"></Image>
                <TextBlock x:Name="txtTemplate2" Text="{Binding FileName}"></TextBlock>
            </StackPanel>
          </common:HierarchicalDataTemplate>
          <common:HierarchicalDataTemplate x:Name="template1" ItemTemplate="{StaticResource template2}"
          ItemsSource="{Binding Files}">
            <StackPanel Orientation="Horizontal">
                <Image x:Name="imgTemplate1" Source="Images/Open-Folder-icon.png" Height="15" Width="15"></Image>
                <TextBlock x:Name="txtTemplate1" Text="{Binding FolderName}"></TextBlock>
            </StackPanel>
          </common:HierarchicalDataTemplate>
            
          

Having created the HierarchicalDataTemplates for the Files and Folders which can be used as ItemsSource for TreeView, create a HierarchicalDataTemplate for the ListBox.

Code for the ListBox template
XAML
            
          <common:HierarchicalDataTemplate x:Name="template3">
            <StackPanel Orientation="Horizontal">
                <Image x:Name="imgTemplate3" Source="Images/file-icon.png" Height="25" Width="25"></Image>
                <TextBlock x:Name="txtTemplate3" Text="{Binding FileName}"></TextBlock>
            </StackPanel>
          </common:HierarchicalDataTemplate>
            
          

After creating all the HierarchicalDataTemplates, create the TreeView and ListBox and bind them to their respective HierarchicalDataTemplates

Code for the TreeView and Listbox
XAML
            
          <controls:TreeView x:Name="TreeBind" ItemTemplate="{StaticResource template1}" ItemsSource="{Binding Folders}"
              SelectedItemChanged="TreeBind_SelectedItemChanged">
          </controls:TreeView>
          <ListBox x:Name="lstRight" Grid.Column="1" ItemTemplate="{StaticResource template3}" ItemsSource="{Binding Folders}"
              SelectionChanged="lstRight_SelectionChanged">
          </ListBox>

            
          

Create a class for FileInfo and FolderInfo and to populate the TreeView

Code to populate the TreeView
C#
            
      // Class for FileInfo
      public class FileInfo
      {
            private string _fileName;
            public string FileName
            {
                get { return _fileName; }
                set
                {
                    if (_fileName != value)
                    _fileName = value;
                }
            }
      }

      // Class for FolderInfo
      public class FolderInfo
      {
            private string _folderName;
            public string FolderName
            {
                get { return _folderName; }
                set
                {
                    if (_folderName != value)
                    _folderName = value;
                }
            }

            public ObservableCollection<FileInfo> Files { get; set; }
      }

      // Method to populate TreeView
      private void PopulateTreeView()
              {
            for (int i = 0; i < 10; i++)
            files.Add(new FileInfo() { FileName = "File" + i });

            for (int i = 0; i < 10; i++)
            {
                Folders.Add(new FolderInfo()
                {
                    FolderName = "Folder" + i,
                    Files = files
                });
            }

            TreeBind.ItemsSource = Folders;
      }
            
          

To make the application look like a File Explorer, create a SelectedItemChanged event for the TreeView and ListBox.

Code to get the selected item
C#
            
      /// <summary>
      /// LstRight SelectionChanged Event
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void lstRight_SelectionChanged(object sender, SelectionChangedEventArgs e)
              {
            FileInfo file = (FileInfo)lstRight.SelectedItem;
            MessageBox.Show("You selected " + file.FileName, "Sample MessageBox", MessageBoxButton.OK);
      }

      /// <summary>
      /// TreeBind SelectedItemChanged Event
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void TreeBind_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
              {
            Type tSelectedItem = TreeBind.SelectedItem.GetType();
            Type tFolders = typeof(FolderInfo);
            Type tFiles = typeof(FileInfo);

            if (tSelectedItem == tFolders)
            {
                FolderInfo folder = (FolderInfo)TreeBind.SelectedItem;
                lstRight.ItemsSource = folder.Files;
            }

            if (tSelectedItem == tFiles)
            {
                FileInfo file = (FileInfo) TreeBind.SelectedItem;
                MessageBox.Show("You selected " + file.FileName,"Sample MessageBox",MessageBoxButton.OK);
            }
      }
            
          

A Simple WCF app with Silverlight


July 25, 2010

I recently created a Silverlight application that consumes WCF services. You can get the Silverlight SDK here.

Also, get the Silverlight Web Platform installer and the Silverlight toolkit in case you haven’t done this previously.

I installed Silverlight 3 November 2009 tools for VS 2008 and think it's pretty stable. In case you find debugging errors saying you will need Silverlight Managed debugging package (I mean after installing the toolkit and the web platform installer). Something like this.



Try reinstalling the Silverlight Package (Visual Studio tools, SDK and Web Platform Installer or Silverlight Developer Runtime ). Though reinstalling the Silverlight 3 stuff will provide a straight forward solution, if you find the errors coming up again, do the following - Download the chainer package. Go to command line and then to the directory where you downloaded the chainer. Execute this command: silverlight_chainer.exe /x:SLChainer \Folder

The package gets extracted in the <currentDirectory>\SLChainer\Folder location.

Run the Silverlight 2.0 executable in case you have Silverlight 2.0 or less or the Silverlight SDK if you have Silverlight 2.0 installed. Try restarting and you should be fine.

After all these steps, you should be good to start a Silverlight Application hosted in a ASP.NET website. Open a new project and open MainPage.xaml. Create a TextBlock and a Button inside a StackPanel, which would look something like the following -
Template for MainPage.xaml
XAML
            
      <UserControl x:Class="WCFIntroduction.MainPage"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
        <Grid x:Name="LayoutRoot">
            <Grid.Background>
                <LinearGradientBrush>
                    <GradientStop Color="Azure" Offset="0.5" />
                    <GradientStop Color="White" Offset="0.2" />
                </LinearGradientBrush>
            </Grid.Background>
            <StackPanel x:Name="StackPanel">
                <TextBlock x:Name="txtblock"  Text="Text" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <Button Content="Click Me!" Click="btn1_Click"></Button>
            </StackPanel>
        </Grid>
      </UserControl>
            
          

Now add the WCF service to the ASP.NET web site by Right Click on project > Add > Add New Item > Silverlight Enabled WCF Service. Here is how the WCF Service looks -

WCF Service that prints time
C#
            
      using System;
      using System.Linq;
      using System.Runtime.Serialization;
      using System.ServiceModel;
      using System.ServiceModel.Activation;
      using System.Collections.Generic;
      using System.Text;

      namespace WCFIntroduction.Web
      {
            [ServiceContract]
            [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
            public class WCFService
            {
                    [OperationContract]
                    public string PrintTime(string txt)
                                                 {
                        return string.Format("The Time now is: {0}", DateTime.Now);
                    }

                    // Add more operations here and mark them with [OperationContract]
            }
      }
            
          

This code returns a string with a Time Stamp on it. Having created the Service, Build the solution and check for errors. When the service is error-free, right click the service and select View in Browser. This is essential because, if you miss this step, the port for the service will not be opened and you will encounter errors while adding the service to the Silverlight Application.

If your service is good, it should look something like this when you view it in a browser.



You can click the link, and view the WSDL code for the service you added.

Now its time to add the service to the Silverlight Application. In order to do that, right-click the SL Project or the Service Reference folder and select Add Service Reference. You should see the following dialog box -



Now click the Discover button to discover the services inside the Solution.

Note: The address in the address combo-box will be detected automatically if you view the Service in a web browser. If you find errors while discovering the solution, it means the port has not been opened for the web service. It will be resolved if you view the web service in the browser. Having added the service, add a reference to your MainPage.xaml.cs code, and write the code to wire up the Service to the SL Application. The basic steps to add a service to any project are -
  • Instantiate the Service client you just created.
  • Declare Event Handler(s) to the methods (or) Operational Contracts you created in the Service.
  • Call the Async method for the event you just added.
  • Define the event handler you declared previously.
The following code shows how you can wire up a service to an application (the SL Application in our case).
Wiring up WCF Service to button click
C#
            
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Net;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Documents;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Windows.Media.Animation;
      using System.Windows.Shapes;
      using WCFIntroduction.ServiceReference1;

      namespace WCFIntroduction
      {
            public partial class MainPage : UserControl
            {
                public MainPage()
                                    {
                    InitializeComponent();
                }

                private void btn1_Click(object sender, EventArgs e)
                                    {
                    WCFServiceClient client = new WCFServiceClient();
                    client.PrintTimeCompleted+=new EventHandler<PrintTimeCompletedEventArgs>(client_PrintTimeCompleted);
                    client.PrintTimeAsync(txtblock.Text);
                }

                private void client_PrintTimeCompleted(object sender, PrintTimeCompletedEventArgs e)
                                    {
                    txtblock.Text = e.Result;
                }
            }
      }
            
          

This basically prints something like this when you click the button -