Wednesday, September 19, 2012

How to pass parameters into a Silverlight Application

After spending some quality time in Colombo SharePoint camp, today I am going to write about how to pass parameters to a Silverlight application. This of course can be really useful even in SharePoint where let's say for an example, a different Silverlight page should be displayed based on the requested page. In such cases generally what comes to our mind is using 2 xaps,  but it is not possible with a Silverlight application, because a single Silverlight application can create only one xap file. So another thing we can do is creating a separate Silverlight application for the other view which is not a good practice.

So the best approach would be passing parameter to the Silverlight application when it is loading. There are variety of ways to achieve it and here, I will be showing only the most used ways.

I have created a Silverlight Application and I have a Web Project to host my Silverlight Application. I will be passing the parameters using following ways.
    1. Adding to Resources
    2. Constructor Overloading
  1. Query String
InitParams

In the Silverlight application, in the App.xaml there is a event which is Application_Startup(object sender, StartupEventArgs e). This will be triggered when an application is started and when the application is starting up Silverlight application Processes initialization retrieved from the InitParams property of the StartupEventArgs object that is passed to the Startup event handler. The initialization parameters are passed as the initParams parameter when you embed the Silverlight plug-in in a Web page like below.
    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
          <param name="source" value="ClientBin/SilverlightApplicationParam.xap"/>
          <param name="onError" value="onSilverlightError" />
          <param name="background" value="white" />
          <param name="minRuntimeVersion" value="5.0.61118.0" />
          <param name="autoUpgrade" value="true" />
          <param name="initParams" value="param1=FromInitParams" /> <%--my customer init parameter--%>
          <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
               <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
          </a>
        </object>
        <iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>
    </div>
In here as you can see, I have created a init parameter. The input format of this parameter starts as a single string with individual parameters delimited using a comma (,), and keys delimited from values using an equal sign (=). For example, "key1=value1,key2=value2,key3=value3". The delimiters are processed so that this API can provide them as a dictionary. So I pass multiple parameters like this.
<param name="initParams" value="param1=FromInitParams,param2=FromInitParams2,param3=FromInitParams3" />
So when we pass init params this way, we can consume these from the Application_Startup(object sender, StartupEventArgs e) event in the App.xaml. From that event either we can save this in global resources dictionary for later use or we can overload the initial page constructor and pass to it. Let’s see this in action.

App.xaml
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            var _message = "";

            // way 1
            // save in global resources dictionary 
            if (e.InitParams != null)
            {
                // reading all initparams and adding it to global resources dictionary
                foreach (var item in e.InitParams)
                {
                    this.Resources.Add(item.Key, item.Value);
                }
            }
            this.RootVisual = new MainPage();

            // way 2
            // overload the initial page constructor
            if (e.InitParams != null)
            {
                // check for a specfic key from the initparams
                if (e.InitParams.ContainsKey("param1"))
                {
                    // getting the value of a specific key
                    _message = e.InitParams["param1"];
                }
            }
            // passing parameter to intial page constructor
            this.RootVisual = new MainPage(_message);
        }
MainPage.xaml
        private string _message = "";

        // way 1
        public MainPage()
        {
            InitializeComponent();
            _message = GetParameterValueFromKey("param1");
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        // find the key in global resources dictionary and
        // return the value of it
        private string GetParameterValueFromKey(string key)
        {
            if (Application.Current.Resources[key] != null)
            {
                return Application.Current.Resources[key].ToString();
            }
            else
            {
                return string.Empty;
            }
        }

        // way 2
        public MainPage(string message)
        {
            InitializeComponent();
            _message = message;
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
And in the MainPage_Loaded event I am showing the value in a message box.
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(_message);
        }

Query String

Let’s say I have a button to redirect my page to the page which hosts the Silverlight Application. I am passing some parameter via query string to that page.
        protected void btnSilverlight_Click(object sender, EventArgs e)
        {
            Response.Redirect("~/SilverlightApplicationParamTestPage.aspx?param1=FromQueryString");
        }
I can consume this value from MainPage.xaml in the following way.
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            IDictionary<string, string> qString = HtmlPage.Document.QueryString;
            foreach (KeyValuePair<string, string> keyValuePair in qString)
            {
                if (keyValuePair.Key == "param1")
                    _message = keyValuePair.Value;
            } 
            MessageBox.Show(_message);
        }
So isn't this nice.

Happy Coding.

Regards,
Jaliya

Tuesday, September 18, 2012

WCF Data Services with Silverlight

Last week I wrote a post about Introduction to WCF Data Services and OData and I said I will write a post showing how to access an OData feed from a Silverlight application and this is it.

I will start off by creating a Silverlight Application and I am creating a new web project to host my Silverlight application. I have NuGet installed in my Visual Studio and since I need OData library, in the Package Manager Console I am running the following command.
PM> Install-Package Microsoft.Data.Services –Pre
oData0
Package Manager Console
oData0.1
Install OData Library
And then I can see the following references are added to my web project.
  1. Microsoft.Data.Edm
  2. Microsoft.Data.OData
  3. Microsoft.Data.Services
  4. Microsoft.Data.Services.Client
reference0.2
References
Now I am adding a ADO.NET Entity Data Model to my web project (right click and add new item ) and I am naming it as DBEntities. Please note that I have a sample table to store Customer information and has following columns.
  1. CUSTOMER_ID (int) – Primary Key
  2. CUSTOMER_FIRST_NAME (string)
  3. CUSTOMER_LAST_NAME (string)
DBEntities3
ADO.NET Entity Data Modal : Choose Data Connection
Tables4
ADO.NET Entity Data Modal : Choose Database Objects

Now I am adding a WCF Data Service to my web project and I am naming it as DBService.
DBService6
Add WCF Data Service

I will be getting something like this.
Untitled1
Modify WCF Data Service
I can see some errors, because there is ambiguous reference and that’s because System.Data.Services and System.Data.Services.Client are included in OData library. So I need to delete   System.Data.Services and System.Data.Services.Client from references.
referenceremove0.3
Remove References
Now I am modifying the class as follows.
   public class DBService : DataService<DBEntities>
   {
       // This method is called only once to initialize service-wide policies.
       public static void InitializeService(DataServiceConfiguration config)
       {
           // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
           // Examples:
           config.SetEntitySetAccessRule("CUSTOMERs", EntitySetRights.All);
           // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
           config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
       }
   }
In here I have put DBEntities as “ /* TODO: put your data source class name here */ ” and I have uncommented config.SetEntitySetAccessRule method. Here “CUSTOMERs” is a ObjectSet created for my table “CUSTOMER”. You can check it by examining the code file of your created ADO.NET Entity Data Model. I have changed EntitySetRights.AllRead to EntitySetRights.All, because I am planning to Read and Write to the entity.

Now I am pretty much done modifying the items in the web project and now I am starting to modify my Silverlight Application.

First I will add a Service Reference to the DBService in my web project.

Untitled2
Service Reference
Now I am modifying my MainPage.xaml. I have created some controls.

Untitled3
Sample Application
Here there is a Busy Indicator in the top, a Combo Box, two Text Boxes and three buttons for Adding, Updating and Deleting. My requirement is I can Add a customer, I should be able to list existing customers in combo box and I should be able to Update/Delete selected customer.

My combo box is binded and other controls are just there. XAML code for binding the combo box is,
<!--I am binding the combobox and the display field should be customer ID-->
        <ComboBox Height="23" ItemsSource="{Binding}" DisplayMemberPath="CUSTOMER_ID" HorizontalAlignment="Left" Margin="101,109,0,0" Name="cboCustomer" VerticalAlignment="Top" Width="165" SelectionChanged="cboCustomer_SelectionChanged" />
Now I am writing the code in the code behind of the MainPage.xaml. Rather explaining one by one, I am pasting the code here with comments.
using System;
using System.Data.Services.Client;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using WCFDataServicesSilverlightApp.svcDBService; // service referencenamespace WCFDataServicesSilverlightApp
{
    public partial class MainPage : UserControl
    {
        // DataServiceContext
        DBEntities oDBEntities;

        // dynamic entity collection of customers
        DataServiceCollection<CUSTOMER> resultColl;

        // relative path of the service
        private const string ServiceUri = "/DBService.svc";

        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // in Page load I am retrieving the existing customer list and 
            // filling up my combo box.
            LoadCustomers();
        }

        private void LoadCustomers()
        {
            // create the DataServiceContext using the service URI.
            oDBEntities = new DBEntities(new Uri(ServiceUri, UriKind.Relative));

            // linq query to retrieve all the customers.
            var query = from c in oDBEntities.CUSTOMERs
                        select c;

            resultColl = new DataServiceCollection<CUSTOMER>();

            // I am loading the collection asynchronously because I don't need
            // my page to be stucked while loading customers.
            resultColl.LoadAsync(query);

            // while loading the customer I am showing a busy indicator.
            busyIndicator1.IsBusy = true;

            // event to be raised when the loading is completed.
            resultColl.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(ResultColl_LoadCompleted);

            // DataContext for binding the combobox.
            DataContext = resultColl;
            cboCustomer.DataContext = DataContext;
        }

        private void cboCustomer_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            oDBEntities = new DBEntities(new Uri(ServiceUri, UriKind.Relative));

            // when selected index is changed, I am retrieving the information of the
            // selected the customer.
            var query = from c in oDBEntities.CUSTOMERs
                        where c.CUSTOMER_ID == ((CUSTOMER) cboCustomer.SelectedValue).CUSTOMER_ID
                        select c;

            resultColl = new DataServiceCollection<CUSTOMER>();

            // I am loading the collection asynchronously.
            resultColl.LoadAsync(query);

            // event to be raised when the loading is completed.
            resultColl.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(ResultColl_LoadCompleted);
        }

        void ResultColl_LoadCompleted(object sender, LoadCompletedEventArgs e)
        {
            // loading completed.
            busyIndicator1.IsBusy = false;

            // if loading is cancelled or if there is an error show some message.
            if (e.Cancelled || e.Error != null)
            {
                MessageBox.Show("Error loading customer.");
            }
            else
            {
                if (resultColl != null)
                {
                    if (cboCustomer.SelectedValue != null)
                    {
                        // setting up the information.
                        txtFirstName.Text = resultColl[0].CUSTOMER_FIRST_NAME;
                        txtLastName.Text = resultColl[0].CUSTOMER_LAST_NAME;
                    }
                }
            }
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            CUSTOMER customer;

            // adding a customer.
            // Create always needs a Primary Key.
            // Since my ID column is an Identity Column in SQL, ID is auto generated and auto incremented
            // I am passing some integer value.
            customer = CUSTOMER.CreateCUSTOMER(-1);

            // set property values.
            customer.CUSTOMER_FIRST_NAME = txtFirstName.Text;
            customer.CUSTOMER_LAST_NAME = txtLastName.Text;

            AddRecord(customer);    
        }

        private void btnUpdate_Click(object sender, RoutedEventArgs e)
        {
            // get selected customer.
            CUSTOMER customer = resultColl[0];

            // changing the property values.
            customer.CUSTOMER_FIRST_NAME = txtFirstName.Text;
            customer.CUSTOMER_LAST_NAME = txtLastName.Text;

            UpdateRecord(customer);
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            // get selected customer.
            CUSTOMER customer = resultColl[0];

            DeleteRecord(customer);
        }

        private void AddRecord(CUSTOMER customer)
        {
            // add the new customer to the customer entity set.
            oDBEntities.AddToCUSTOMERs(customer);

            // asynchronously start saving and OnChangesSaved will be called when completed.
            oDBEntities.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, oDBEntities);
        }

        private void UpdateRecord(CUSTOMER customer)
        {
            // update selected customer in the customer entity set.
            oDBEntities.UpdateObject(customer);

            // asynchronously start saving and OnChangesSaved will be called when completed.
            oDBEntities.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, oDBEntities);
        }

        private void DeleteRecord(CUSTOMER customer)
        {
            // delete selected customer from customer entity set.
            oDBEntities.DeleteObject(customer);

            // asynchronously start saving and OnChangesSaved will be called when completed.
            oDBEntities.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, oDBEntities);
        }

        private void OnChangesSaved(IAsyncResult result)
        {
            // this will be showed when asynchronous BeginSaveChanges is completed.
            MessageBox.Show("Done.");
        }
    }
}
And that's it. Hope this helps.

Happy Coding.

Regards,
Jaliya

Friday, September 14, 2012

What’s new in Visual Studio 2012

Yesterday was one of the special days in this year and that’s because yesterday Microsoft had their Virtual Launch of the newest version of Visual Studio which is Visual Studio 2012. The new Visual Studio 2012 family of products includes the commercial Visual Studio 2012 Professional, Premium, Ultimate and the Team Foundation Server 2012.

Following are some of the new features available with this new release of Visual Studio 2012.
  • User Interface - The User Interface is slightly different when compared to previous versions of Visual Studio.
Untitled3
User Interface

  • Windows 8 Metro Style Applications - Can create Windows 8 Metro Style applications and this is one of most featured things in Visual Studio 2012 and not to mention it is one of things I am missing in Visual Studio 2010.
  • LightSwitch - LightSwitch for Visual Studio 2012 – Previously Microsoft Visual Studio LightSwitch was a separate product and with the new Visual Studio 2012, it is included in default.
Untitled2
LightSwitch

  • Solution Explorer - Now with the new Solution Explorer we can browse our project’s objects and drill down into methods and properties. It also gives us the ability to search and preview files, objects and external items.
Solution Explorer

  • SQL Server Object Explorer - With previous versions of Visual Studio we couldn’t manage objects in instances of the Database Engine through Visual Studio. Now with the newly introduced SQL Server Object Explorer, it gives us same feeling as using the Object Explorer in SQL Server Management Studio.
SQL Server Object Explorer

  • IIS Express - Previous versions of Visual Studio used its own ASP.NET Development Server as the default web server for locally running and testing web applications. Visual Studio 2012 uses IIS Express as the default local web server. But of course you can change it anytime.
IIS Express

  • Debugging Browser - Visual Studio gives us another nice feature which is, now we can select the browser to debug/browse our web application. For example if your default browser is Google Chrome, your web application will be debugged using Google Chrome in default. But if you are debugging a Silverlight application you specifically need Internet Explorer. Now we don’t have to change the default browser, we only have to change debugging browser.
Untitled7
Debugging Browser

There are a lot of other things included in the new .NET Framework 4.5. Sometime back I wrote a post about What's new in C# 5.0 and now you can find these features in the .NET Framework 4.5.

Jason Zander, who is the Corporate Vice President for the Visual Studio team in the Developer Division at Microsoft has published a nice post about Visual Studio 2012 and .NET Framework 4.5 and you can check it out for more information.

For more information visit,

Happy Coding.

Regards,
Jaliya

Thursday, September 13, 2012

Introduction to WCF Data Services and OData

WCF Data Services (formerly known as ADO.NET Data Services and codename is “Astoria”) is a platform for what Microsoft calls Data Services. This is a component of the .NET Framework that enables you to create services that use the OData(Open Data Protocol) to expose and consume data over the web or intranet by using the semantics of Representational State Transfer (REST).

Before moving forward let me give a introduction to OData first.

OData(Open Data Protocol)

The Open Data Protocol is a Web protocol for querying and updating data. OData does this by applying and building upon Web technologies such as HTTP, Atom Publishing Protocol (AtomPub) and JSON to provide access to information from a variety of applications, services, and stores. OData is being used to expose and access information from a variety of sources including, but not limited to, relational databases, file systems, content management systems and traditional Web sites.

What happens in OData is Servers hosts data and Clients can consume/manipulate or update these data. The end point on the server is also known as a Service. The protocol is HTTP based and we can use standard HTTP verbs of GET, PUT, POST, and DELETE to interact with the service. The data is send between the Server and Client using Atom Publishing Protocol (AtomPub - a set of standards for exchanging and updating data as XML) and JavaScript Object Notation(JSON - a text-based data exchange format used extensively in AJAX application) notations. Since the protocol is HTTP based, any application written in any programming language which has HTTP stack can communicate with this service.

Now how WCF Data Services and OData comes together is WCF Data Services uses the OData protocol for addressing and updating resources. In this way, you can access these services from any client that supports OData. WCF Data Services also includes a set of client libraries, one for general .NET Framework client applications and another specifically for Silverlight-based applications. These client libraries provide an object-based programming model when you access an OData feed from environments such as the .NET Framework and Silverlight.

I am hoping to show you how to access an OData feed from a Silverlight application in a coming post.

Happy Coding.

Regards,
Jaliya

Wednesday, September 12, 2012

Visual Studio IntelliTrace

We are exactly 1 day before the Microsoft Visual Studio 2012 Virtual Launch and now I am going to explain one of the nicest features in Visual Studio 2010.

In every application we write, there are bugs. It can be a small one which is easy to find or it can be a tough one which can take days to find. So to find the bug normally what we do is, we are putting break points in the code where we suspect problem is and we start debugging. We are pressing F10 and F11 and we keep going on line by line. Sometimes because of our eager to find the bug, we are going faster and suddenly we are passing and missing the bug. Then what we do is, again starting the debugging from the beginning.

Sometimes this can be a real headache when we are fixing a bug on an application where we have to supply a lot of inputs for the bug to raise. Every time we debug the application, we have to supply those values and it is very troublesome. So that’s where this IntelliTrace comes in.

IntelliTrace was introduced with Visual Studio 2010 and it is only available in the Ultimate edition of Visual Studio 2010. IntelliTrace has the ability to go back through the past states of an application and view those states. If you did not understand what I meant by past states of an application, let me explain it taking a simple example.

I have a windows forms application which has only a single form. Form contains a single button and I have two variables which are “i” and “j” and they are initialized to 0. Now in the form load method and the button click event I am changing the values of these variables. My requirement is to trace the value changing of my two variables. (Of course, in the following example there is nothing to debug, I just want you to get the idea behind it.)

Following is the code I have and I have set two breakpoints in Form1_Load and btnGetSum_Click events.
        private int i = 0;
        private int j = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            i = 10;
            j = 20;

            lblI.Text = string.Format("i is {0}", i);
            lblJ.Text = string.Format("j is {0}", j);
        }

        private void btnGetSum_Click(object sender, EventArgs e)
        {
            i = 30;
            j = 40;

            lblSum.Text = string.Format("Sum is {0}", i + j);
        }
First I have opened the IntelliTrace settings from Visual Studio (Tools->Options->IntelliTrace) and I have selected “IntelliTrace events and call information.” under “Collect the following IntelliTrace information while debugging:”.

By selecting this I am telling IntelliTrace to collect both event information and call stack information. The call stack information can include method names, method parameters, and return values. But a thing to note here  is by selecting this option, it can lead to performance issues with the application. The default selection which is “IntelliTrace events only” will only collect information related to IntelliTrace events such as opening file, writing to registry etc.

Untitled1
IntelliTrace Opions

Now I have started debugging and I have gone through both breakpoints and for some reason I couldn’t check the variable values in each event. Now normally what I will have to do is again starting the debugging from the beginning. Now with Visual Studio IntelliTrace, you don’t have to start the debugging again any more. What you have to do is, while the application still running, go or open the IntelliTrace window and click on “Break All”.
Untitled2
IntelliTrace Window
Now you can see the all the event and call information through out your application in the IntelliTrace window.

Untitled3
IntelliTrace Window

When I click on second and forth item which are the Form1_Load and btnGetSum_Click events, I can see the following.

Untitled4
IntelliTrace Window
Untitled5
IntelliTrace Window
It will show me before coming in to the Form1_Load event, the values of  “i” and “j” is 0 and 0 respectfully.   Before control going into btnGetSum_Click event the values of  “i” and “j” is 10 and 20 respectfully. So now I can see what the values of each variable are before and after methods/events. Simply what IntelliTrace does here is, it provides all the information in each of the application’s states. Now I believe you all got a good understanding in what I meant by “IntelliTrace has the ability to go back through the past states of an application and view those states.”.

This is one thing that is available with IntelliTrace. There are a lot of things that can be done using IntelliTrace and for more information on Visual Studio IntelliTrace ,visit following sites.


I am pretty sure, with the release of Visual Studio 2012, Microsoft will gift us some new features which we did not even imagine.

Happy Coding.

Regards,
Jaliya

Thursday, September 6, 2012

Object Serialization and Deserialization in C#

Serialization is the process of converting an object into a stream of bytes in order to persist it to memory, a database, a file or even can be sent over a network. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called Deserialization. When we serialized an object, the object is serialized to a stream, which carries not just the data, but information about the object's type, such as its version, culture, and assembly name.

To object to be serialized, we should apply [Serializable()] attribute. If we don’t want any property to be serialized, we can apply [NonSerialized()] attribute.

Microsoft .NET Framework provides two types of Serialization.
  1. Binary Serialization
    • Binary serialization uses binary encoding to produce compact serialization for uses such as storage or socket-based network streams.
  2. XML Serialization
    • XML serialization serializes the public fields and properties of an object, or the parameters and return values of methods, into an XML stream that conforms to a specific XML Schema definition language (XSD) document. XML serialization results in strongly typed classes with public properties and fields that are converted to XML. You can apply attributes to classes and class members in order to control the way the XmlSerializer serializes or deserializes an instance of the class.
There are few differences between these two types of Serialization.

Binary Serialization
XML Serialization

Basic Serialization

The only requirement in basic serialization is that the object has the [Serializable()] attribute applied. The [NonSerialized()] can be used to keep specific fields from being serialized.

When you use basic serialization, the versioning of objects may create problems, in which case custom serialization may be preferable. Basic serialization is the easiest way to perform serialization, but it does not provide much control over the process.

Custom Serialization

In custom serialization, you can specify exactly which objects will be serialized and how it will be done. The class must be marked [Serializable()] and implement the ISerializable interface. If you want your object to be deserialized in a custom manner as well, you must use a custom constructor.

Now let’s see how this works. I am using Binary Serialization here. I have a class which is “Employee” and I am going to serialize it using Basic Serialization and Custom Serialization.

Basic Serialization using Binary Serialization
    [Serializable()] //this class is serializable
    public class Employee
    {
        public int EmpId;
        public string FirstName;
        public string LastName;

        [NonSerialized()] public string Address; //this field will not be serialized

        public Employee()
        {

        }
    }
What this code snippet does is, I have a class which is “Employee” and it is ready to be serialized. But I don’t want the address field to be serialized.

Now in my method, I am doing the serialization and deserialization.
   class Program
   {
       static string file = "MyObject.abc";

       static void Main(string[] args)
       {
           Assembly assembly = Assembly.GetExecutingAssembly();
           string directoryName = Path.GetDirectoryName(assembly.Location);
           string fileName = Path.Combine(directoryName, file);

           Employee writeEmployee = new Employee();
           writeEmployee.EmpId = 1;
           writeEmployee.FirstName = "Jaliya";
           writeEmployee.LastName = "Udagedara";
           writeEmployee.Address = "Kandy";
           Serialize(writeEmployee, fileName);
           Console.WriteLine("Completed. Press enter key to read.");
           Console.ReadLine();

           Employee readEmployee = Deserialize(fileName);
           Console.WriteLine("Employee Id: {0}", readEmployee.EmpId);
           Console.WriteLine("Employee First Name: {0}", readEmployee.FirstName);
           Console.WriteLine("Employee Last Name: {0}", readEmployee.LastName);
           Console.WriteLine("Employee Address: {0}", readEmployee.Address);
           Console.WriteLine("Completed.");
           Console.ReadLine();
       }

       //method for serialization
       private static void Serialize(Employee employee, string fileName)
       {
           Stream stream = File.Open(fileName, FileMode.Create);
           BinaryFormatter binaryFormatter = new BinaryFormatter();

           Console.WriteLine("Writing Employee Information...");
           binaryFormatter.Serialize(stream, employee);
           stream.Close();
       }

       //method for deserialization
       private static Employee Deserialize(string fileName)
       {
           Employee employee = null;
           Stream stream = File.Open(fileName, FileMode.Open);
           BinaryFormatter binaryFormatter = new BinaryFormatter();

           Console.WriteLine("Reading Employee Information...");
           employee = (Employee)binaryFormatter.Deserialize(stream);
           stream.Close();
           return employee;
       }
   }
In here what happens is, I will be creating a file named “MyObject.abc” and it will store my serialized object. I have two method for serialization and deserialization. Since I am using BinaryFormatter, to serialize my object, I am passing a stream and the object to it’s Serialize() method. And finally to deserialize, I am using Deserialize() method of BinaryFormatter, and for that I am passing again a stream to the Deserialize() method. For better understanding I am using writeEmployee and readEmployee which are two different objects of same class. So in here my output would be,

Untitled
Output

As you can see from above output, everything is serialized except the address field, Because in my program, I have set address field as a non serializable field. Now let’s see how Custom Serialization works.

Custom Serialization using Binary Serialization
    [Serializable()] //this class is serializable
    public class Employee : ISerializable
    {
        public int EmpId;
        public string FirstName;
        public string LastName;
        public string Address;

        public Employee()
        {

        }

        //Custom Deserialization
        public Employee(SerializationInfo info, StreamingContext ctxt)
        {
            EmpId = (int)info.GetValue("EmpId", typeof(int));
            FirstName = (String)info.GetValue("FirstName", typeof(string));
            LastName = (String)info.GetValue("LastName", typeof(string));
        }

        //Custom Serialization
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("EmpId", EmpId);
            info.AddValue("FirstName", FirstName);
            info.AddValue("LastName", LastName);
        }
    }
In here I have implemented the ISerializable interface and I need to write the GetObjectData method which is for serialization and the Employee constructor which is for deserialization. If you notice that, in here I have not applied [NonSerialized()] attribute to address field even though I don’t want it to be serialized. But instead I have not used address field in serialization and deserialization.

In here SerializationInfo stores all the data needed to serialize or deserialize an object. StreamingContext is a structure describing the source and destination of a given serialized stream. Now when you run this code you will also get the same output as in Basic Serialization.

Hope you got a good understanding about Object Serialization and Deserialization in C#.

Happy Coding.

Regards,
Jaliya

Business Intelligence with Syncfusion

These days Business Intelligence(BI) is a pretty decent topic in all kind of organizations. One of the nice features of BI would be ability to create Ad-Hoc reports. Ad-Hoc reporting is the process of creating reports on the fly with little or no training of reporting. This has been a major advantage of BI, because end users can create their own reports without taking much time.

Today I am going to write about one of the nice BI tools/controls which I have came across. Syncfusion Essential Studio Business Intelligence Edition is a part of Syncfusion product suite. Syncfusion main product suite which is Syncfusion Essential Studio provides some nice controls to work with various areas in Microsoft .NET framework. Since I am mainly focusing on Business Intelligence, I will be only talking about Syncfusion Essential Studio Business Intelligence Edition here.

Syncfusion Essential Studio Business Intelligence Edition has some nice controls for following areas.
My favorite control is Syncfusion Olap Client which supports Ad-Hoc reporting. What you only have to do is simply pass in the connection string to an SQL Server Analysis Services(SSAS) database or any XML for Analysis(XMLA) provider and the database name, and the Olap Client has the ability to retrieve all the cubes available within that database, the different dimensions, measures, and KPIs that are in the cube, and display them in an easily navigable tree.

Because of the Syncfusion Essential Studio Business Intelligence Edition's features, it comes with a price. And that is the only bad thing I have seen in this product until now.

Happy Coding.

Regards,
Jaliya

Wednesday, September 5, 2012

jQuery UI - Modal Message

I was always not good in designing nice web sites, but this jQuery UI JavaScript library is there to help me on that. Today I am going to write about how to show a nice message box, which is a modal using jQuery UI.

First I need to have jQuery and jQuery UI libraries installed on my web application. I can easily use NuGet to do the installation.

Untitled
Installing jQuery library

Untitled1
Installing jQuery UI library

Then I have selected a theme from jQuery UI Themes. There are a lot of themes available and even you can customize the themes. I have downloaded a theme and put it into themes folder under Content folder.
Untitled2
Adding a theme
Then I have added following lines to the master page.
    <script src="Scripts/jquery-1.7.2.js" type="text/javascript"></script>
    <script src="Scripts/jquery-ui-1.8.20.js" type="text/javascript"></script>
    <link href="Content/themes/redmond/jquery-ui-1.8.22.custom.css" rel="stylesheet" type="text/css" />
I am adding a div to my page, and it will be the modal.
    <div id="dialog-alert" title="Message">

    </div>
I am writing a method in the code behind file which will contain the JavaScript function.
        private void ShowJqueryMessage(string message)
        {
            try
            {
                //Initialize the stringbuilder object to append javascript
                StringBuilder sb = new StringBuilder();
                sb.Append("$(function() { ");
                sb.Append("$('#dialog-alert').empty();");
                sb.Append("$('#dialog-alert').append('" + message + "');");
                sb.Append(" $('#dialog-alert').dialog({");
                sb.Append("    width: 350,");
                sb.Append("buttons: {");
                sb.Append("'Close': function () {");
                sb.Append("$('#dialog-alert').dialog('close');");
                sb.Append("}");
                sb.Append("   }");
                sb.Append(" });");
                sb.Append("});");
                //Register the script on page startup
                ClientScript.RegisterStartupScript(typeof(Page), "myscript", sb.ToString(), true);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Then in my button click event I am calling the method.
        protected void Button1_Click(object sender, EventArgs e)
        {
            ShowJqueryMessage("Message.");
        }
Untitled3
Message in the modal

That's it. Hope this helps.

Happy Coding.

Regards,
Jaliya

Tuesday, September 4, 2012

SQL Server Transactions

Transactions can be really important when we are working with databases. For example let’s say you need to execute two or more SQL commands sequentially and if any statement fails, all other statements should not be executed. To achieve this, we can use Transactions.

Mainly transactions has these four properties which are abbreviated as ACID.
  1. Atomic
    • Atomic means that all the work in the transaction is treated as a single unit. That is either all statements in the unit must execute, or no statement in the unit must execute.
  2. Consistent
    • Consistent means that a completed or roll backed transaction leaves the database in a consistent internal state. A transaction will convert the database from a known starting state to a known ending state. If the transaction commits, the database will be at the known ending state. If the transaction fails, the database will be at the known starting state.
  3. Isolated
    • Isolations means that the transaction sees the database in a consistent state. If two transactions try to update the same table, one will go first and then the other will follow. Transactions are committed independently from each other and they are transparent to each other.
  4. Durability
    • Durability means that the results of the transaction are permanently stored in the system and ensures that the result or effect of a committed transaction persists in case of a system failure.
There are couple of transaction types.
  1. Autocommit Transactions
    • Autocommit mode is the default transaction management mode of the SQL Server Database Engine. Every Transact-SQL statement is committed or rolled back when it completes. If a statement completes successfully, it is committed; if it encounters any error, it is rolled back.
    • But here there is something to note. That is sometimes Database Engine has rolled back an entire batch instead of just one SQL statement. This happens if the error encountered is a compile error, not a run-time error. A compile error prevents the Database Engine from building an execution plan, so nothing in the batch is executed. Let’s the following examples.
    • In this example, there is a compile time error in the third line. So the error prevented anything in the batch from being executed.
      INSERT INTO TestTable VALUES (1, 'aaa');

      INSERT INTO TestTable VALUES (2, 'bbb');

      INSERT INTO TestTable VALUSE (3, 'ccc');  -- Syntax error. 


      SELECT * FROM TestTable ;  -- Returns no rows.
    • In this example, there is a run time duplicate primary key error in he third line. The first two INSERT statements are successful and committed, so they remain after the run-time error.
      INSERT INTO TestTable VALUES (1, 'aaa');

      INSERT INTO TestTable VALUES (2, 'bbb');

      INSERT INTO TestTable VALUES (1, 'ccc');  -- Duplicate key error.


      
      
      SELECT * FROM TestTable -- Returns rows 1 and 2.
  2. Explicit Transactions
    • An explicit transaction is one in which you explicitly define both the start and end of the transaction. DB-Library applications and Transact-SQL scripts use the BEGIN TRANSACTION, COMMIT TRANSACTION, COMMIT WORK, ROLLBACK TRANSACTION, or ROLLBACK WORK Transact-SQL statements to define explicit transactions.
      • BEGIN TRANSACTION
        Marks the starting point of an explicit transaction for a connection.
      • COMMIT TRANSACTION or COMMIT WORK
        Used to end a transaction successfully if no errors were encountered. All data modifications made in the transaction become a permanent part of the database. Resources held by the transaction are freed.
      • ROLLBACK TRANSACTION or ROLLBACK WORK
        Used to erase a transaction in which errors are encountered. All data modified by the transaction is returned to the starting state which it was in at the start of the transaction. Resources held by the transaction are freed.
  3. Implicit Transactions
    • When a connection is operating in implicit transaction mode, the instance of the SQL Server Database Engine automatically starts a new transaction after the current transaction is committed or rolled back. If there is an INSERT statement running as an Implicit Transaction, then a separate transaction is created for that. If it was an explicit transaction, several INSERTs would be wrapped together in one transaction. Also for an Implicit Transaction, SQL Server needs to write the transaction log to disk every time . The session running the Implicit Transaction will remain open until a COMMIT/ROLLBACK transaction command is issued.
  4. Distributed Transactions
    • At times you might have to execute transactions that span more than one server. These transactions can only be executed if all servers involved have MS Distributed Transaction Coordinator (MS DTC) installed and running. Distributed transactions are also very difficult to debug, so use them sparingly.
Hope this helps.

Happy Coding.

Regards,
Jaliya