Friday, September 28, 2012

Configuring SQL Server 2008R2 Reporting Services Email Delivery with Gmail SMTP

This is how you can configure SQL Server 2008R2 Reporting Services email with Gmail SMTP server. Please note that my operating system is Windows Server 2008R2.
  1. Go to Server Manager and Add feature “SMTP Server”.
    Untitled1
    Add Feature SMTP Server
  2. Go to Administrative Tools and open Internet Information Services (IIS) 6.0 Manager.
  3. Right Click on SMTP Virtual Server and select Properties.
    Untitled2
    SMTP server properties
  4. Under the General tab select your IP Address.
    Untitled3
    IP Address
  5. Under the Access tab click on Relay and do as follows.
    Untitled4
    Relay
  6. Under the Delivery tab you will get something like this.
    Untitled5
    Delivery Tab
  7. Now under the Delivery tab click on Outbound Security and type your gmail email address and the password. Remember to tick on "TLS encryption".
    Untitled6
    Outbound Security
  8. Again under the Delivery tab click on Outbound Connections and do as follows.
    Untitled7
    Outbound Connections
  9. Again under the Delivery tab click on Advanced and fill values as below.
    Untitled8
    Advanced
  10. Now you are done with the SMTP properties. Now make sure SMTP Server is started.
    Untitled9
    Start SMTP Server
  11. Go to Reporting Services Configuration Manager under Configuration Tools in All Program's Microsoft SQL Server 2008 R2. As Sender address, type your gmail address and as SMTP Server, type your IP address.
    Untitled10
    Reporting Services Configuration Manager
  12. Go to "C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer" and open "rsreportserver.config" file. Make sure your Report Manager URL is inside UrlRoot tags and Report Server Email Extension tag is filled as below with your details. If you find your tags empty, make a backup of "rsreportserver.config" file and fill the tag values as below.
            <UrlRoot>http://jaliya-pc/ReportServer</UrlRoot>
------------------------------------------------------------------------------------------------
            <Extension Name="Report Server Email" Type="Microsoft.ReportingServices.EmailDeliveryProvider.EmailProvider,ReportingServicesEmailDeliveryProvider">
                <MaxRetries>3</MaxRetries>
                <SecondsBeforeRetry>900</SecondsBeforeRetry>
                <Configuration>
                    <RSEmailDPConfiguration>
                        <SMTPServer>192.168.10.107</SMTPServer>
                        <SMTPServerPort>
                        </SMTPServerPort>
                        <SMTPAccountName>
                        </SMTPAccountName>
                        <SMTPConnectionTimeout>
                        </SMTPConnectionTimeout>
                        <SMTPServerPickupDirectory>
                        </SMTPServerPickupDirectory>
                        <SMTPUseSSL>
                        </SMTPUseSSL>
                        <SendUsing>2</SendUsing>
                        <SMTPAuthenticate>
                        </SMTPAuthenticate>
                        <From>jaliya.udagedara@gmail.com</From>
                        <EmbeddedRenderFormats>
                            <RenderingExtension>PDF</RenderingExtension>
                        </EmbeddedRenderFormats>
                        <PrivilegedUserRenderFormats>
                        </PrivilegedUserRenderFormats>
                        <ExcludedRenderFormats>
                            <RenderingExtension>HTMLOWC</RenderingExtension>
                            <RenderingExtension>NULL</RenderingExtension>
                            <RenderingExtension>RGDI</RenderingExtension>
                        </ExcludedRenderFormats>
                        <SendEmailToUserAlias>True</SendEmailToUserAlias>
                        <DefaultHostName>
                        </DefaultHostName>
                        <PermittedHosts>
                        </PermittedHosts>
                    </RSEmailDPConfiguration>
                </Configuration>
            </Extension>
------------------------------------------------------------------------------------------------
That's it. Now you can test your email delivery by creating a Data-driven Subscription. You can find the Reporting services log file under the following location. It will contain all the logs related to this email sending.

"C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\LogFiles"

I am hoping to write a post about programmatically creating a Data-driven Subscription in a coming post and hope this helps.

Happy Coding.

Regards,
Jaliya

Tuesday, September 25, 2012

Calling WCF Service using ChannelFactory from a Silverlight Application

Today I am going to write about consuming a WCF service using Channel Model. As you might know there are several ways to create WCF client. One is letting the Visual Studio create the proxy using adding service reference. In this way, there is kind of a disadvantage which is, if the service changes for any reason you have to regenerate it.

Now I am going to create a WCF client (which is a Silverlight application) using this ChannelFactory method. ChannelFactory is most useful when you are dealing with a known Interface. If you can share the contract assemblies (interface) between the service and the client, ChannelFactory would be the ideal solution to consume the web service. If you did not understand what I meant by sharing the interface, let’s start off with the code then you can get the picture clearly.

First I am creating a Silverlight application and I am creating a web project to host my Silverlight application. Then I am adding a WCF Service Application (MyWcfServiceApp) to my solution. I am deleting the default service and it’s interface and I am creating a new WCF service which is “MyService.svc”.

MyService.svc
    public class MyService : IMyService
    {
        public string  DoWork(string s)
        {
            return s;
        }
    }
IMyService.cs
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        string DoWork(string s);
    }
Now I am modifying the web.config file in the MyWcfServiceApp project and I am adding bindings to my created web service. After that I am getting the web.config file as follows. The ones I have added are marked in Bold text.
<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
      <bindings>
          <customBinding>
              <binding name="binaryHttpBinding">
                  <binaryMessageEncoding />
                  <httpTransport maxReceivedMessageSize="2147483647" />
              </binding>
          </customBinding>
      </bindings>
      <services>
          <service name="MyWcfServiceApp.MyService">
              <endpoint address="" binding="customBinding" bindingConfiguration="binaryHttpBinding"
              contract="MyWcfServiceApp.IMyService" />
          </service>
      </services>
      
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  
</configuration>
So after completing that step I am moving to my Silverlight application. First I need to add a reference to “System.ServiceModel.dll”.

Untitled2
Adding reference to System.ServiceModel
Now comes the most interesting part. Since I am using ChannelFactory, first let’s get to know what this really is. What MSDN says about ChannelFactory is as follows.

ChannelFactory<TChannel> Class
  • A factory that creates channels of different types that are used by clients to send messages to variously configured service endpoints.
  • TChannel : The type of channel produced by the channel factory. This type must be either IOutputChannel or IRequestChannel.
So which means the Channel Factory class is used to construct a channel between the client and server without creating a Proxy. So the channel would be the contract of the service which is the interface. So moving back to our example, I am modifying MainPage.xaml file in my Silverlight application as follows. In here the endpoint address is the address of my service.
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            Binding customBinding = new CustomBinding(
                new BinaryMessageEncodingBindingElement(),
                new HttpTransportBindingElement { MaxReceivedMessageSize = 2147483647 }
                );

            EndpointAddress address = new EndpointAddress("http://localhost:3289/MyService.svc");
            ChannelFactory<IMyService> clientChannel = new ChannelFactory<IMyService>(customBinding, address);
        }
    }
I have created the ChannelFactory of type IMyService. Now I am facing a problem here, because the contract IMyService cannot be found in the Silverlight Application. Because It’s in the WCF Service Application and even I can’t add a reference to MyWcfServiceApplication from My Silverlight application because only Silverlight projects can be referenced to a Silverlight application.

Untitled3
Add project reference

So what I would do now is, I am creating a IMyService interface in my Silverlight Application. After that my code will refer the interface I have created just now. And that’s what I meant by using ChannelFactory with a known interface and sharing the interface between client and the server.

Now I am modifying the above code as follows to call my DoWork method in my WCF service.
    public partial class MainPage : UserControl
    {
        private IMyService _imyService;

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

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            Binding customBinding = new CustomBinding(
                new BinaryMessageEncodingBindingElement(),
                new HttpTransportBindingElement { MaxReceivedMessageSize = 2147483647 }
                );

            EndpointAddress address = new EndpointAddress("http://localhost:3289/MyService.svc");
            ChannelFactory<IMyService> clientChannel = new ChannelFactory<IMyService>(customBinding, address);
            if (clientChannel == null)
            {
                throw new Exception("Failed to create channel.");
            }
            _imyService = clientChannel.CreateChannel();
            string s = _imyService.DoWork("Hello World");
        }
    }
Now when I run this, I am getting the following error message.

Untitled4
Synchronous operation
It's a pretty clear error message, because synchronous operations are not supported in Silverlight. We should make everything asynchronous. So I am modifying my service contract as follows. Please note that here I am modifying the “IMyService” interface in my Silverlight application. I don’t have to change “IMyService” interface in MyWcfServiceApp.
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginDoWork(string s, AsyncCallback callback, object state);

        string EndDoWork(IAsyncResult result);
    }
Now I am modifying MainPage.xaml as follows. I have added a textbox to show the return value from the WCF service and I am calling Dispatcher.BeginInvoke in the callback method.  This is necessary because we’re accessing the UI thread, omitting this will result in an invalid cross thread access exception.
    public partial class MainPage : UserControl
    {
        private IMyService _imyService;

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

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            Binding customBinding = new CustomBinding(
                new BinaryMessageEncodingBindingElement(),
                new HttpTransportBindingElement { MaxReceivedMessageSize = 2147483647 }
                );

            EndpointAddress address = new EndpointAddress("http://localhost:3289/MyService.svc");
            ChannelFactory<IMyService> clientChannel = new ChannelFactory<IMyService>(customBinding, address);
            if (clientChannel == null)
            {
                throw new Exception("Failed to create channel.");
            }
            _imyService = clientChannel.CreateChannel();
            IAsyncResult asyncResult = _imyService.BeginDoWork("Hello World", GetResult, _imyService);
        }

        // Implement the callback. 
        void GetResult(IAsyncResult asyncResult)
        {
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                txtResult.Text = ((IMyService)asyncResult.AsyncState).EndDoWork(asyncResult);
            });
        }
    }
Now when I run this, again I will get the following error which is “Attempting to access a service in a cross-domain way”.

Untitled1
Attempting to access a service in a cross-domain way
For that I have to create 2 xml files which are ClientAccessPolicy.xml and crossdomain.xml andI am placing them inside my WCF Service application project.

ClientAccessPolicy.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
    <cross-domain-access>
        <policy>
            <allow-from http-request-headers="SOAPAction">
                <domain uri="*"/>
            </allow-from>
            <grant-to>
                <resource path="/" include-subpaths="true"/>
            </grant-to>
        </policy>
    </cross-domain-access>
</access-policy>
crossdomain.xml
<?xml version="1.0"?>

<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
</cross-domain-policy>
That’s it. Now when I run this application, I am getting the result I have expected.

Untitled5
Result
Happy Coding,

Regards,
Jaliya

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