Sunday, May 4, 2014

Transaction in SQL Server, ADO.Net and LINQ (1)

Transactions in SQL Server and ADO.NET

Sometimes we need multiple SQL statements to be executed all or none. We need to make sure that if one statement failed none of the others is executed. We can do this manually by checking whether any fail and if a statement fail we undo the previous statements. This approach isn't efficient because it is time consuming and more importantly it since databases are multi-users, then a user can access the data at the instance just after the failing of the statement and before undoing the action.

The solution is using transactions.

In Transact-SQL, we have the following commands:

  1. BEGIN TRANSACTION ,
  2. COMMIT TRANSACTION ==> to commit the transaction to the database, 
  3. ROLLBACK TRANSACTION ==> to undo any previous commands.
To use transaction in coding using ADO.Net we have the following class

  • System.Data.SqlClient.SqlTransaction 

Let's see the following example code to show how to use it.
I have a Database called Bookie, with a table called Books(BookID,BookName,ImageURL,BookCost).

            SqlConnection db = new SqlConnection("ConnectionString Here");
      SqlTransaction transaction;

         db.Open();
      transaction = db.BeginTransaction();          LINE 1
      try 
      {
         new SqlCommand("INSERT INTO Books " +
            "(BookName,BookCost) VALUES ('nb1',0);", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO Books " +
            "(BookName,BookCost) VALUES ('nb2',10);", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO Books " +
            "(BookName,BookCost) VALUES ('nb3',20);", db, transaction)
            .ExecuteNonQuery();
         transaction.Commit();              LINE 2
      }  
      catch (SqlException sqlError) 
      {
          Response.Write(sqlError.Message);
         transaction.Rollback();
      }
      db.Close();

In the previous code, we  first create an object of SqlTransaction.
After opening the connection, we BeginTransaction as in LINE 1. This makes any SqlCommand executed on the connection, executed within a transaction. So it won't be applied to the database unless CommitTransaction is executed. If we forget this line, nothing happens.

Note that when creating a SqlCommand we used the constructor overload that takes the string, SqlConnection, SqlTransaction. If we forgot to add the transaction to the SqlCommand, an exception occurs as in the following image.


Then we work with ADO commands normally, doing all needed db manipulation inside a try block.

The previous example works fine, with no exceptions occurring, and 3 rows are added when LINE 2 is executed as this commands order the engines to commit all changes done and write in permanently to the db.

Look at this code:
SqlConnection db = new SqlConnection("ConnectionString Here");
      SqlTransaction transaction;

         db.Open();
      transaction = db.BeginTransaction();          LINE 1
      try 
      {
         new SqlCommand("INSERT INTO Books " +
            "(BookName,BookCost) VALUES ('nb1',0);", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO Books " +
            "(BookName,BookCost) VALUES ('nb2',10);", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO Books " +
            "(BookName,BookCost) VALUES ('nb3','no cost');", db, transaction)
            .ExecuteNonQuery();                LINE 3
         transaction.Commit();                 LINE 2
      } 
      catch (SqlException sqlError) 
      {
          Response.Write(sqlError.Message);
         transaction.Rollback();               LINE 4
      }
      db.Close();

Now, in LINE 3 an exception will occur due to incorrect format, since BookCost is a decimal and provided value is a string 'no cost'.

When executing this, we get an exception and the catch block is executed printing a message to the page.

Cannot convert a char value to money. The char value has incorrect syntax.

then the transaction is rolled back as in LINE 4 and no changes happen to the db.

Behavior of the transaction depends on the isolation level.  The default value is READ COMMITTED. It specifies that statements cannot read data that has been modified but not committed by other transactions. Data can be changed by other transactions between individual statements within the current transaction, resulting in nonrepeatable reads or phantom data.


LINQ to SQL supports  distinct transaction models.
When SubmitChanges is called, if the Transaction property is set to a (IDbTransaction) transaction, the SubmitChanges call is executed in the context of the same transaction.

It is your responsibility to commit or rollback the transaction after successful execution of the transaction. The connection corresponding to the transaction must match the connection used for constructing the DataContext. An exception is thrown if a different connection is used.



Thanks,
Nerdy Geeky J!


References:
http://www.codeproject.com/Articles/10223/Using-Transactions-in-ADO-NET
http://technet.microsoft.com/en-us/library/ms173763.aspx

Friday, May 31, 2013

Using WCF and Entity Framework with PhoneGap

I blogged before about using VS to edit PhoneGap applications and use chrome emulator to test it. Now we will use jQuery in PhoneGap application to access WCF services and return objects in JSON.

First we created a phonegap application

Then we hosted it on IIS and open in VS
File==>Open Website ==> Local IIS ==> create a new virtual directory
                                                                       Give Alias Name
                                                                         Browse to the project to the folder of the phonegap


Next we will create a new Website in another VS instance, to host the WCF service. It must be created on IIS to be tested on the emulator. So don't create it in the FileSystem must use HTTP.


No I have HelloService created on my IIS.
Delete the Service.svc created by default and then Add new Item to the project ==> Ajax Enabled WCF Service.


Now we have HelloService.svc


Now we will modify the DoWork function to return string


I added [WebGet] attribute to the method to be called using 'GET' method, so that we can test it in the browser. If it is not added and we typed the URL to the method in the browser we get "Method not allowed" error.

Now when tested it gets
The string is sent in a json format, in a member called d.

So now we need to call it from ajax function in PhoneGap app.

The following code does this

First, I used deviceready event from phonegap api. It fires once Cordova has fully loaded. After the device has fired, you can safely make calls to Cordova function.
In its call back function, I used jQuery.ajax method (don't forget to add jQuery library).

 In the url option, you put the url to your WCF service. Do not use localhost, you must use an IP. Since localhost to the emulator means itself.

Now when running the code on the emulator, You must also use IP in the URL to the application.
for example: http://192.168.1.103/Hello/assets/www/index.html




Now if we have an object we need to retrieve.
I created a simple book database and created a new ADO.Net Entity Data Model and called it BookModel.edmx

And used it to return to the application a list of books. Next is the code written in the service method and after it is shown the return when called in the browser.


Next is the javascript code added to the success callback of the ajax request. It took the returned array and created table rows to show the BookId and BookName

The result is


It is better to create light weight versions of the Model objects to send. Since I need only the ID and Name, it is a waste to send all the rest of the data to mobile application. In mobile applications, data send or received means money paid, so we need to be careful .

For example:

class LightBook{
                         int bookId{set; get;}
                         string bookName{set;get;}
}


Thanks,
Nerdy Geeky J!







Thursday, May 30, 2013

Developing for Phone Gap using Visual Studio on TFS

Being used to visual studio development and starting with development for Phone Gap. I was successful to start working with eclipse and created my projects and loaded them to TFS.

It wasn't easy to work on eclipse and the emulator was too slow on my machine. The intelli-sense and editor of eclipse even after downloading Web Page Editor, wasn't comfortable to me.

After some trials and research, I found that we can use Visual Studio as an IDE and Ripple Emulator on Chrome browser.

So after creating your Phone Gap project and uploading it to TFS,you go to VS2012
==> Open website ==>Source Control

==> Select Source Control Project
then Choose your application from the Team Explorer

then choose a local folder to work in
and choose Run as IIS Web site
and choose the URL to host on IIS

Now you have 


Now to test your application on an emulator we need Google Chrome browser and Ripple Emulator 
after downloading them, you will have a ripple icon in the browser  toolbar as follows


Next after enabling Ripple, we can try by going to visual studio and choosing index.html and right-click ==> View in Browser(Chrome).

If Chrome is not default, use File ==> Browse With and choose Chrome (Set as Default), 
You will find a black page with multiple choice of platforms chooseApache Cordova 2.0,
And the you will find your page shown on the emulator which you can change and choose any device or platform as follows


Now you can edit and add you HTML, JS and CSS files in VS and test it in the chrome emulator.
Next I will write an article on accessing WCF webservices using jQuery in Phone Gap.

But to test the application on a device, we need eclipse and to finalize the application we need eclipse too. Take care that some PhoneGap features are not yet supported on Ripple. An example of such features is FileTransfer.

Thanks,
Nerdy Geeky J!







Monday, May 20, 2013

A simple solution when connecting to TFS everywhere from eclipse fails

To connect your eclipse project to TFS

http://msdn.microsoft.com/en-us/library/hh301122.aspx
http://msdn.microsoft.com/en-us/library/jj155782.aspx
http://msdn.microsoft.com/en-us/library/hh568708.aspx


Sometimes connecting to TFS fails, the authentication service is not accessible, a solution maybe 
Open Internet Browser ==> Tools ==> Internet Options ==> Delete Browsing History

Even if you are not using IE.

Thursday, May 9, 2013

Link to Images in ASP.NET Theme folder

To link your image html tag to an image file in the asp.net theme folder, we need to create the image path. The variable part of the path is the theme name. This can be retrieved from the code in different ways:

If we have the following file organization:

App_Themes
      Default
           Images
               logo.jpg

In a class method,

namespace MyUtility
{
      class Utility
     {

                   public static string GetImageUrl(string relativeImageUrl)
                  {
                                 System.Web.UI.Page currentPage = HttpContext.Current.CurrentHandler as              System.Web.UI.Page;
                                 string url = relativeImageUrl;
                                 if (currentPage != null)
                                 {
                                      string pageTheme = currentPage.Theme;
                                      if (!String.IsNullOrEmpty(pageTheme))
                                                     url = "App_themes/" + pageTheme + "/" + relativeImageUrl;
                                 }
                                 return url;
                    }
        }
}

In ASPX
<img src="<%= MyUtility.Utility.GetImageUrl("Images/logo.jpg") %>"/>

Or simply we can do it directly in ASPX
<img src="App_Themes/<%=Page.Theme%>/Images/logo.jpg"/>

               


 Thanks,
Nerdy Geeky J!

Saturday, May 4, 2013

Encrypting Connection strings in ASP.NET

 To secure your connection string you can easily encrypt your connectionStrings section of the web.config.

Open command prompt from visual studio tools menu in startup menu, Run as Administrator



Then print, if you use website on local IIS
aspnet_regiis -pe "connectionStrings" -app "/websitename"

Example:


Or if you are using a web application use
aspnet_regiis.exe -pef “connectionStrings”   "C:\path to application on local disk"

to decrypt use 
aspnet_regiis -pd "connectionStrings" -app "/websitename"

Or

aspnet_regiis.exe -pdf “connectionStrings”   "C:\path to application on local disk"

This can be applied to other sections of the web.config.

But note that if you will host your application on a shared host this will not be useful at all and it will not work.

You can use it on a dedicated server or your local server.


Thanks,
Nerdy Geeky J!

Saturday, April 27, 2013

Setting PhoneGap for Android Development

Trying to set up the development environment for PhoneGap android development, I was faced with many errors. The Documentation on PhoneGap Website made you think everything was straight forward but to a newbie to java like me it wasn't.

I work on Windows 7, and here I will present a detailed description on how to set the environement and get ready to start.

1- To start you need to set up Java SDKJRE and Ant. For Ant just unzip the downloaded binary and add to c:\Ant
2- Set Environment Variables:
     Right click Computer (from Startup Menu) ==> Properties
                                                          Advanced system Settings
                                                          Environment Variables
                                                          New

Variable Name: JAVA_HOME
Variable Value: C:\Program Files\Java\jdk1.7.0_21   ===> path of JDK on your system

Add also add


Variable Name: ANT_HOME
Variable Value: C:\Ant   ===> path of Ant on your system

3-  Include %JAVA_HOME%\bin to your PATH as well.  Also Include %ANT_HOME%\bin to your PATH.

Environment Variable ==> in System Variables choose Path  ==> Edit
                                 In Edit System Variables add to the end of Variable Value ; then

                                  C:\%ANT_HOME%\bin ; C:\%JAVA_HOME%\bin

Don't forget to substitute %ANT_HOME% and %JAVA_HOME% with your path to each of them.


To test that everything is fine till now
Open cmd  ==> java -version ==> you'll get the version of java installed
                          javac -version ==> you'll get the version again
                          ant   ==> you'll get a message : 'Buildfile: build.xml does not exist!  Build Failed'
                                         Ignore it, this means it is working :)

4- Create a folder for all the setup for me I called it  C:\AndroidDevelopment

7- Download and install ADT Bundle for Windows.


Unzip the ZIP file (named adt-bundle-<os_platform>.zip) in our folder.
Open adt-bundle-<os_platform>/eclipse/  ==>  eclipse.exe

Now the IDE is  loaded with the Android Developer Tools plugin and the SDK is ready to go.


Now add the path to your Android SDK platform-tools and tools directory. Like before edit Path system variable to add the path of the directory the SDK is installed in.

;C:\Android Development\adt-bundle-windows-x86-20130219\sdk\platform-tools;C:\Development\android-sdk-windows\tools

To test this open cmd ==> adb

                                      Then android
                                       Android SDK manager window opens



7- Download the latest copy of PhoneGap and extract it to our folder.
8- Create your Hello World application

Open Start ==> cmd (command Prompt)
                         navigate to the bin directory within the android subfolder of the PhoneGap folder
                         cd C:\Android Development\phonegap-2.6.0\lib\android\bin

                         Then type /create <project_folder_path> <package_name> <project_name>
          for example:      /create C:\AndroidProjects\HelloWorld com.Android.HelloWorld HelloWorld


<project_folder_path> is the path to your new Cordova Android project
<package_name> is the package name, e.g. com.YourCompany.YourAppName
<project_name> is the project name, e.g. YourApp (Must not contain spaces)

Now you have a folder created for you with your first Android project HelloWorld folder..................Hurray!

9- Launch Eclipse from the adt folder (C:\Android Development\adt-bundle-windows-x86-20130219\eclipse). You can create a shortcut for easier start next time.

Select menu item New Project then Android ==> Android Project from Existing Code


Select the directory you used for <project_folder_path>
Click Finish.

If your project has a red X indicating there is a problem follow these additional steps:

Right click on the project folder.
In the Properties dialog that is displayed select Android from the navigation pane.
For the project build target select the highest Android API level you have installed.
Click OK
Then from the Project menu bar item select Clean.
This should correct all the errors in the project.

Now you can run the project on emulator
Run ==> Run As ==> Android Application
From Android Device Chooser
              Launch a new Android Virtual Device    => then press Manager
              In Android Virtual Device Manager ==>  New
                      Create a new AVD to be used.

Since PhoneGap is used to develop HTML 5 applications for Mobiles we need HTML and JavaScript editor.

This is not available in the installed eclipse we need to install WebPageEditor plugin.
Help ==> Install New Software
In work with choose the Juno release
then choose Web, XML,Java EE and OSDI Enterprise Development
           then choose Web Page Editor

then download it. You will be asked to restart eclipse, Do so.

When opened, in Window ==> Preferences
               General ==> Editors ==> fileassociation

Choose *.html and set Web Page Editor as default
repeat for all other extensions (.html, Css, JS,.....)


Thanks,
Nerdy Geeky J!