Showing posts with label microsoft. Show all posts
Showing posts with label microsoft. Show all posts

Sunday, March 2, 2014

Creating right mobile icons sizes for Android, iOS and Windows applications.

I am developing a mobile application that will serve all Egyptians people for a critical national project.

It a service and management based mobile application which is related to Fuel locations finder and Customers fuel subsidy management card System.

It will be released soon by the middle of March in Google play for Android platform and by the end of March 2014 in Apple App Store for iOS application, followed by windows mobile platform in May 2014.

It is a hybrid mobile development rather than native development.

While designing the application I have faced many challenges performance, design, Architecture, cross-platform development, and Graphics especially the logo design. Designing icons especially for iOS platforms is a tricky a little bit.

There are different icons sizes related to resolution (normal and Retina’s displays), places, and naming conventions for applications targeting iOS 3, 4, 6, and 7.

However, it was easier developing the icons for Android platform, but anyway I will share icons sizes for both platforms. and Microsoft Windows mobile platform as well.

It is a good idea and practice to develop

the larger icon size first then export it to different sizes. I used Adobe Photoshop and Illustrator CC. Illustrator is a great tool for logos because it is vector based, so scaling the artwork are easier to scale without losing the artwork resolution.

Android platform

The following table show different icons for different displays resolutions in pixel:


Display


Launcher Icons


Action Bar Icons


Google Play


512x512


---


Double Extra High dpi (xhdpi)


---


96x96


Extra High dpi (xhdpi)


96x96


64x64


High dpi (hdpi)


72x72


48x48


Medium dpi (mdpi)


48x48


36x36


Low dpi (ldpi)


36x36


---

iOS platform

The following table shows different icons for different iDevices displays resolutions in pixel, note that iOS 7 iPhone and iPod has Retina's display support only, as all iOS 7 supported iDevices are iPhone from 4 to 5s, and 5th generation iPod touch.


OS/ Device/ Place


Standard Resolution


High Resolution (Retina Display)


iPhone and iPod Touch


iPad


iPhone and iPod Touch


iPad


iOS 6 platform


Home Screen Icon


57x57


72x72


114x114


144x144


Settings Icon


29x29


29x29


58x58


58x58


Spotlight Icon


29x29


100x100


58x58


50x50


App icon for the App Stores


1024x1024


512x512


1024x1024


1024x1024


iOS 7 platform


Home Screen Icon


---


76x76


120x120


152x152


Settings Icon


---


29x29


58x58


58x58


Spotlight Icon


---


80x80


80x80


40x40


App icon for the App Stores


---


512x512


1024x1024


1024x1024

Windows Phone

The following table shows different resolutions in pixel for Microsoft windows platform application and marketplace icons:


Application Place


Icon Size


Application


Icon


62x62


Tile Image


173x173


Marketplace


Application icon for Windows Phone Marketplace catalog (small)


99x99


Application icon for Windows Phone Marketplace catalog (large)


173x173


Desktop application icon for Windows Phone Marketplace catalog


200x200



Monday, January 13, 2014

Microsoft: Adding IntelliSense for jQuery in WebMatrix and Microsoft development tools.

I had the opportunity to work with HTML5 APIs and jQuery development inside Microsoft WebMatrix, it is a light IDE and installed with libraries and extensions that made development richer.

In order for WebMatrix to really be a useful as an editor for jQuery, I really wanted to have IntelliSense support for jQuery. However, the annoying issue is that WebMatrix does not have a built-in IntelliSense support for jQuery in and other JavaScript tools.

As jQuery is one of our focuses here in this post, adding IntelliSense for jQuery is extremely easy, therefor I am going to explain how to add the IntelliSense support for jQuery into WebMatrix or other Microsoft development tools in an easy step.

The idea
---------------
Microsoft's developer tools like WebMatrix, Visual studio 2008 SP1 and upper versions, allow you to add IntelliSense for any JavaScript library by adding a Reference Directives (.vsdoc JavaScript file) to your page.

The files that you would use for your reference directives are available at the same Microsoft CDN where you can get the jQuery library from at:
http://www.asp.net/ajaxlibrary/cdn.ashx

How to do it
-------------------
In order to use IntelliSense for jQuery, you need to download the appropriate jquery-n.n.n-vsdoc.js file for the version of jQuery that you are using and store that in your page.
  1. Your project structure should be as the following


  2. Add the reference directive (jquery-2.0.3-vsdoc.js) into your html page as the following


  3. You also can add it to you JavaScript library file, to get the power of IntelliSense for jQuery as the following


Result
-------------
Now you have added the library reference directives for jQuery version, into your IDE inside your page write jquery call by just jQuery or $ you will get:


Hit the .(dot) and you will also get


Conclusion
-----------------

Also as you notice in the previous pictures, the reference not just get the IntelliSense but more than this, it gives you the power of getting the methods documentation and parameters explanations on the fly, or by hover over the method after writing it.

Thanks to Microsoft reference directives.

References
----------------
1- Microsoft Ajax Content Delivery Network.

Friday, March 1, 2013

Browser: Microsoft IE10 is the first release supporting HTML5 Websockets API.

In my previous post "Microsoft has released IE 10 for windows 7", I have mentioned that this version comes with extensive support for HTML5 APIs, provided with a download link.

Among HTML5 APIs I was looking forward for the support of HTML5 Websocket API.

As I am a JCP member, working on Adopt-A-JSR program for testing the reference implementation (Tyrus) of Java API for WebSocket 1.0 (JSR 356), beside enhancing and validating the specification, that will be part of the next release of JEE7 (Java Enterprise Edition 7) which also includes a lot of server supports for HTML5 APIs as well as the cloud based applications.

I have tested my developed application on IE10 for communication with my endpoint deployed on Glassfish v4_b78 (The reference implementation for JEE7 specifications umbrella), and the result was successful, as the following Figure 1.






Figure 1: The testing results on IE10.

This means that IE10 is the first Microsoft browser version that supersedes previous versions 9- for HTML5 Websocket support.

Who Supports WebSockets Today?

The following table provides a brief summary of the support for WebSockets that most popular browsers provide at present.

Table 1 Browser Support for WebSockets

Browser

WebSockets Support

Internet Explorer

WebSockets is supported now in Internet Explorer 10. Metro applications written using JavaScript and HTML5 will support WebSockets as well.

Firefox

WebSockets are supported starting with version 6 of the browser released in mid-2011. Some very early support was offered in version 4 and then dropped in version 5.

Opera

Support for WebSockets has been removed in version 11.

Chrome

WebSockets are supported starting with version 14, which was released in September 2011.

Safari

Supports an earlier version of the WebSocket Protocol.

With the exception of Firefox, you can programmatically check for WebSockets support by looking at the window.WebSocket object.For Firefox, you should currently check the MozWebSocket object. It should be noted that most HTML5-related capabilities can be checked in browsers by means of a specialized library such as Modernizr (modernizr.com).

In particular, here’s the JavaScript code you need to write if you linked the Modernizr library to your page:


Now almost we have the chance to run all of HTML5 websocket based client's applications, on the majority of popular vendors browser.

Thursday, February 28, 2013

Browsers: Microsoft has released IE 10 for windows 7.

Working with HTML5 and targeting a specific specification to multiple customers who has different platforms, requires testing this development on all cross browsers vendors from IE, Safari, Chrome, Opera to Firefox as major browsers.

Microsoft IE was the least one supporting the HTML5 standard specification APIs than other browsers, but by releasing the IE10 hope to see more support for HTML5 and CSS3.

Microsoft has released the final version of Internet Explorer 10; with support for Web standards. Officials said "IE10 on all platforms add support for more than 30 new Web standards beyond what IE9 supported, including support for new HTML5, CSS3, DOM, Web Performance, and Web Application specifications".

Microsoft plans to begin auto-updating customers with Windows 7 Service Pack 1 and/or Windows Server 2008 R2 and higher with the IE10 "in the weeks ahead".

But this version is aimed to Support Windows 7 Service Pack 1, Windows Server 2008 R2 SP1 operating systems only. And it is already bundled with windows 8 and RT versions. And it comes in 95 languages flavor. But this means that Windows Vista & XP users will not have this version as auto update or download version.

When you run this version of IE10 on Win7 and 2008 RC2, you will find some differences from its peer running on Win8 & RT.

To download your X64/X86 platform version, with your preferred language, download it from Microsoft Download Center.

Saturday, June 2, 2012

JDK7: ProcessBuilder and how redirecting input and output from operating system's processes.

The java.lang.ProcessBuilder class has several new methods added into JDK7 that are useful for redirecting the input and output of external processes executed from a Java application. The nested ProcessBuilder.Redirect class has been introduced to provide these additional redirect capabilities.

To demonstrate this process, we are going to send command-line arguments from a text file to a DOS prompt and record the output in another text file.

Getting ready
----------------
In order to control input and output from external processes, you must:
  1. Create a new ProcessBuilder object.
  2. Direct the input and output of the process to the appropriate locations.
  3. Execute the process via the start method.

How to do it
---------------
1. First, create a new console application. Create three new file instances to represent the three files involved in our process execution: input, output, and errors as follows:

2. Create the file Commands.txt using the path specified for the file and enter the following text:
C:
dir
mkdir "Test Directory"
dir
3. Make sure that there is a carriage return after the last line.

4. Next, create a new instance of a ProcessBuilder, passing the string "cmd" to the constructor to specify the external process that we want to launch, which is the operating system command window. Call the redirectInput, redirectOutput, and redirectError methods with no arguments and print out the default locations:

5. Then we want to call the overloaded form of the previous methods, passing the respective file to each one. Once again, call the no argument form of each method executed using the toString method to verify that the IO sources have been changed:

6. Finally, call the start method to execute the process as follows:

7. Run the application. You should see output similar to the following:

8. Examine each of the text files. Your output file should have text similar to this:

9. Execute the program again and examine the contents of your error log. Because your test directory had already been created with the first process execution, you should now see the following error message:

How it works
---------------
We created three files to handle the input and output of our process. When we created the instance of the ProcessBuilder object, we specified the application to launch to be the command window. The information required to perform actions within the application was stored in our input file.

When we first called the redirectInput, redirectOutput, and redirectError methods, we did not pass any arguments. These methods all return a ProcessBuilder. Redirect object, which we printed. This object represents the default IO source, which in all three cases was Redirect.PIPE, one of the ProcessBuilder.Redirect.Type enumerations. A pipe takes the output of one source and sends it to another.

The second form of the methods that we used involved passing a java.io.File instance to the redirectInput, redirectOutput, and redirectError methods. These methods return a ProcessBuilder object as well, but they also have the function of setting the IO source. In our example, we then called the no argument form of each method once more to verify that the IO had been redirected.

The first time the program was executed, your error log should have been empty, assuming you used valid file paths for each File object, and you have write permissions on your computer. The second execution was intended to display how the capture of errors can be directed to a separate file.

If the redirectError method is not invoked, the errors will inherit the standard location and will be displayed in your IDE's output window. See the There's More... section for information about inheriting standard IO locations.

It is important to note that the start method must be called after the redirect methods. Starting the process before redirecting input or output will cause the process to disregard your redirects and the application will execute using the standard IO locations.

There's more
---------------
In this section, we will examine the use of the ProcessBuilder.Redirect class and the inheritIO method.

Using the ProcessBuilder.Redirect class

The ProcessBuilder.Redirect class provides another way to specify how the IO data is redirected. Using the previous example, add a new line prior to calling the start method:
pb.redirectError(Redirect.appendTo(errors));
This form of the redirectError method allows you to specify that the errors should be appended to the error log text file rather than overwritten. If you execute the application with this change, you will see two instances of the error when the process tries to create the Test Directory directory again:
A subdirectory or file Test Directory already exists.
A subdirectory or file Test Directory already exists.
This is an example of using the overloaded form of the redirectError method, passing a ProcessBuilder.Redirect object instead of a file. All three methods, redirectError, redirectInput, and redirectOutput, have this overloaded form.

The ProcessBuilder.Redirect class has two special values, namely, Redirect. PIPE and Redirect.INHERIT. Redirect.PIPE is the default way external process IO is handled, and simply means that the Java process will be connected to the external process via a pipe. The Redirect.INHERIT value means that the external process will have the same input or output location as the current Java process. You can also redirect the input or output of data using the Redirect.to and Redirect.from methods.

Using the inheritIO method to inherit the default IO locations

If you execute an external process from a Java application, you can set the location of the source and destination data to be the same as that of the current Java process. The ProcessBuilder class' inheritIO method is a convenient way to accomplish this. If you have a ProcessBuilder object pb, executing the following code:
pb.inheritIO()
Then it has the same effect as executing the following three statements together:
pb.redirectInput(Redirect.INHERIT)
pb.redirectOutput(Redirect.INHERIT)
pb.redirectError(Redirect.INHERIT)
In both cases, the input, output, and error data will be located in the same places as the current Java process' input, output, and error data.

References:
---------------
1.Class ProcessBuilder.
2.Java 7 New Features (by Richard M. Reese, Jennifer L. Reese)


Saturday, January 28, 2012

Java: Improvements to the client and desktop parts of Java SE 6 and Java SE 7 !!!


Client-Side Improvements in Java 6 and Java 7

Learn about the improvements to the client and desktop parts of Java SE 6 and Java SE 7, including the new applet plug-in, the Java Deployment Toolkit, shaped and translucent windows, heavyweight-lightweight mixing, and Java Web Start.

Introduction
Since the release of Java Platform, Standard Edition 6 (Java SE 6) in December of 2006, a lot of improvements have been made to the client and desktop parts of Java. In this article, we take a tour of Swing, and then we dive into some of the support technologies that let developers make great client apps, such as installation, Java Web Start, applets, and graphics improvements. Then we will take a peek at Java 7.

Friday, December 16, 2011

Weblogic: How to setup & test Oracle WebLogic Server 12c (a quick guide On Windows, Linus & Mac OS X)

Weblogic 12c = JEE6 full profile Edition.

Oracle WebLogic 12c is a, certified, full profile Java EE 6 server.

Here is a quick guide for downloading, configuring and installing Oracle weblogic 12c zipped file (size = 164M) development environment.

Steps:
  1. Download size of wls1211_dev.zip is 164 MB.
  2. Installation requires you to unzip the archive, run some scripts and set the following JVM options: -Xmx1024m -XX:MaxPermSize=256m (without setting the PermSize, the deployment didn't work) refer to  QUICKSTART.
  3. Disc size (server): 383 MB after installation
  4. Disc size (domain): 26 MB after installation
  5. Startup: execution of [DOMAIN-FOLDER]/startWebLogic.sh is fast (< 7 secs)
  6. Deployment: copy the ServerSmokeTest.war into [DOMAIN-FOLDER]/standalone/autodeploy/.
For Installation & configuration (On Windows, Linus & Mac OS X) follow the following steps:
The WLS zip distribution is intended for development use. It is supported on  Windows, Linux and Mac OS X systems. It contains the necessary artifacts to develop and test applications on WebLogic Server. 
An optional supplemental zip (wls1211_dev_supplemental.zip) is available as a separate download. The supplemental zip contains samples, evaluation database (Derby) and L10N console help files. 
The following instructions should help in quickly setting up WLS. Please refer to the general WLS documentation for detailed instructions. 
This version of WLS requires JDK 1.6 as a minimum. 
Ensure that you have the proper JDK version installed and ready for use. 

QUICKSTART
---------------------
Note: don't use any spaces in the paths referred in environment variables like JAVA_HOME, MW_HOME etc...
1. Extract the contents of the zip to a directory. This directory is referred to as MW_HOME (eg: /home/myhome/mywls).

2. Setup JAVA_HOME, JAVA_VENDOR, MW_HOME variables in the current shell as required for the target platform.
  
Linux
    $ export JAVA_HOME=/home/myhome/myjavahome
    $ export MW_HOME=/home/myhome/mywls
  
Mac
    $ export JAVA_HOME=
      /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home
    $ export USER_MEM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"       
    $ export MW_HOME=/home/myhome/mywls
  
Windows
    > set JAVA_HOME=C:\home\myhome\myjavahome
    > set MW_HOME=C:\home\myhome\mywls
    > set JAVA_VENDOR=[Sun|Oracle] 

  On Windows you must set JAVA_VENDOR to the JVM being used:
    If using HotSpot, use "Sun"
    If using JRockit, use "Oracle"

3. Run the installation configuration script in the MW_HOME directory.

This step is required to be run only once. If you move the installation to another location/machine, you need to rerun this step.

  Linux/Mac: $ ./configure.sh 
  Windows: > configure.cmd

  On Windows, this step retains the WLS environment settings for the current shell. 
  So, the next step can be omitted.

4. Setup WLS environment in the current shell. 
   Linux: $ . $MW_HOME/wlserver/server/bin/setWLSEnv.sh 
   Mac:   $ . $MW_HOME/wlserver/server/bin/setWLSEnv.sh 
   Windows: > %MW_HOME%\wlserver\server\bin\setWLSEnv.cmd

5. Create a new WLS domain and start WLS.
   
It is recommended that you create domains outside the MW_HOME.
   
Linux
    $ mkdir /home/myhome/mydomain
    $ cd /home/myhome/mydomain
    $ $JAVA_HOME/bin/java $JAVA_OPTIONS -Xmx1024m -XX:MaxPermSize=128m weblogic.Server
  
Mac
    $ mkdir /home/myhome/mydomain
    $ cd /home/myhome/mydomain
    $ $JAVA_HOME/bin/java $JAVA_OPTIONS -Xmx1024m -XX:MaxPermSize=256m weblogic.Server
   
Windows
    > mkdir C:\home\myhome\mydomain
    > cd C:\home\myhome\mydomain
    > %JAVA_HOME%\bin\java.exe %JAVA_OPTIONS% -Xmx1024m -X:MaxPermSize=128m weblogic.Server

Once the domain is created, you can shutdown WLS and restart it with the scripts provided in the newly created domain.

Note: You can also create the domain by invoking the GUI configuration wizard (Run MW_HOME/wlserver/common/bin/config.[sh|cmd]).

6. If you already have an existing domain that you want to run with this installation, edit the DOMAIN_HOME/bin/setDomainEnv.sh script and change the WL_HOME to point to the new installation - ${MW_HOME}/wlserver/.

Note: If the existing domain has samples configured, the server will issue failures during startup as samples are not included in the zip distribution.

7. Start a browser and open up url - 'http://localhost:7001/console' to administer the server.

8. If you need samples, evaluation database (Derby) or console help files for non-english locales, you can download the supplemental zip and extract it under MW_HOME. Follow instructions in README_SUPP.txt to properly setup samples. this file can be found in WLS extracted folder.


WHAT IS NOT INCLUDED
---------------------------------------
The following components are not available in the zip distribution.

  • Coherence libraries
  • WebServer plugins
  • Native JNI libraries for unsupported platforms
  • Samples, evaluation database (Derby), non-english console help (can be added by using the WLS supplemental zip)

CLEANUP
---------------
Delete the MW_HOME directory. Note that this will delete everything under MW_HOME. If you have created domains or extracted supplemental zip those files will be removed as well. Ensure that you don't create domains or applications under MW_HOME directory for easier migration. 


UPGRADE
----------------

  • In-place upgrade of installation is not supported in the zip distribution. 
  • Download the new version of zip distribution and extract it to a new location. 
  • Change the MW_HOME to point to the new location and update the startup scripts in your domains to point to the new MW_HOME.

KNOWN ISSUES
--------------------------

  • [MAC OS X] Memory settings have to be explicitly defined using the USER_MEM_ARGS variable prior to running any domain scripts.
  • [MAC OS X] The config wizard does not recognize a Mac OS X JDK installation and issues a warning. But, it successfully creates a domain and should not cause any issue running servers in the domain.
  • [MAC OS X] The zip distribution has limited support for functionality requiring native support. JMS C clients, auto stack-dumps, auto privileged port binding are not supported.
  • [ALL OS] Smart update tool is not supported in a zip distribution.
  • [ALL OS] The zip distribution should not be extracted to an existing MW_HOME
  •   or BEA_HOME which had been created by a regular installers. Doing so will conflict with already installed products and is unsupported.
  • [ALL OS] JAVA_HOME cannot contain directory names with space characters.


General impression:
  1. Installation is a bit more complicated, comparing it to GlassFish, JBoss, TomEE or Siwpas. All Java EE 6 servers so far can be installed just by unzipping the archive. WebLogic requires you to run some scripts after unzipping. However: the installation can be performed in a few minutes.
  2. The server is lean and fast. Startup and deployment performance is good.
  3. The admin console http://localhost:7001/console is fast, clean and usable. WebLogic comes with extensive monitoring capabilities.


Friday, November 25, 2011

OS: How to Delete/Create/Stop/Start a Windows Service in Windows 7, Vista or XP

 If you are a fan of tweaking your system and disabling services, you might find that over time your Windows Services list becomes huge and unwieldy with a large number of services in the list that will never be enabled.
Instead of just disabling a service, you can alternatively completely delete the service. This technique can be especially helpful if you’ve installed some piece of software that doesn’t uninstall correctly, and leaves an item in the service list.
Important Note: Once you delete a service, it’s gone, and it’s going to be a pain to add it back. Use with caution.
Deleting a Service
The first thing you’ll need to do is identify the name of the service, so open up Services through the start menu or control panel, and then find the service in the list that you want to delete.
You’ll want to open up the properties by double-clicking on the service name, and then highlight the “Service name” value and copy it to the clipboard. This is what we’ll need to disable it.
You’ll need to open up a command prompt, and if you are using Windows 7 or Vista you’ll need to right-click the command prompt and choose Run as Administrator. We’ll use the sc command to actually do the work.
The syntax used to delete a service is this:
sc delete ServiceName
If your service name has spaces in it, you’ll need to wrap the service name in quotes, like this:
sc delete “Adobe LM Service”
Note that I’m not recommending deleting this particular service, it’s just an example.
Now if you use the F5 key to refresh your Services list, you’ll see that the service is gone.
I’ve found that using this technique (carefully) can make your Services list a lot more useful, since you don’t have to weed through dozens of items you will never have enabled.
Note: You should think long and hard before deleting a service, because it’s very difficult to get them back once they are gone.
For more information you can have a look at here.
You can also view services existing on the system or even delete them from this registry key :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services


Thursday, June 16, 2011

Microsoft: Build a .NET Application on the Oracle Database with Microsoft Visual Studio 2010

Learn the basic yet essential processes involved in building a .NET application that uses an Oracle database.
With the popularity of Microsoft's .NET Framework, many developers are hungry for information about the best means of integrating .NET applications with Oracle—not only in terms of basic connectivity, but also in relationship to effective and efficient application development using Microsoft Visual Studio 2010. (The Visual Studio 2005/2008 version of this article is found here. )
In this article, I'll explain the basic yet essential processes involved in building a C# or Visual Basic .NET application that uses an Oracle database, including:
  • How to add project references to support Oracle class libraries in your .NET project
  • How to create Oracle Database connection strings
  • How to work with Connection, Command, and DataReader objects

You will have the opportunity to apply what you have learned in three practice labs, ranging in difficulty from the relatively simple to the more complex. If you are already familiar with building .NET applications for Oracle Database with Visual Studio 2005/2008, the experience with Visual Studio 2010 is very similar.
For information and labs about how to secure your application, see my article "Securing a .NET Application on the Oracle Database." (Also, see the OTN .NET Developer Center for technical articles covering a range of Oracle .NET application lifecycle issues.)
Note that the free Oracle Developer Tools for Visual Studio, available for download from OTN, provides a Visual Studio add-in that makes the development of .NET apps on Oracle much easier and more intuitive. That subject is beyond our scope here, however; see the Oracle Developer Tools for Visual Studio Product Center for more information.


.NET Data Provider


In addition to basic Oracle client connectivity software, .NET applications require the use of what is known as a managed data provider (where "managed" refers to code managed by the .NET framework). The data provider is the layer between the .NET application code and the Oracle client connectivity software. In almost every case, the best performance is achieved by using a provider optimized for a specific database platform instead of the generic .NET OLE DB data provider.

Oracle, Microsoft, and third-party vendors all offer .NET data providers optimized for an Oracle database. Oracle and Microsoft make their Oracle data providers available for free. Microsoft's provider for the .NET Framework is deprecated. Oracle continues to support and develop their .NET data provider, Oracle Data Provider for .NET (ODP.NET). In this article, we will use ODP.NET, which is included with the Oracle Database or as a separate download.

ODP.NET provides standard ADO.NET data access, while exposing Oracle database-specific features, such as XML DB, data access performance optimizations, and Real Application Clusters load balancing and fast connection failover. The current ODP.NET version, 11.2, supports connecting to Oracle Database 9i Release 2 servers and higher versions. The database server can be on Windows, Linux, UNIX, or any other operating system platform Oracle database supports.

When ODP.NET and Oracle client software are installed, application development using Visual Studio can begin. It's a good idea to confirm client connectivity before starting development. If you can connect to Oracle Database using Oracle client software, such as SQL*Plus on the same machine as Visual Studio, then your Oracle client-side software is properly installed and configured.

If you are new to Oracle, see the section "Installing .NET Products" in the Oracle Database 2 Day Developer's Guide for background information regarding installing and configuring ODP.NET specifically, or to the Oracle Database Documentation Library for general information about Oracle Database.


Creating a Project in Visual Studio 2010


Let’s create an ODP.NET application that retrieves data from the Oracle database. Later, we’ll see how to perform error handling with ODP.NET and handle an additional data retrieval scenario.
After starting Visual Studio, the first task is to create a project. You can either click New Project as shown below or select File | New | Project.
vs2010-oracle-dev-f1
Figure 1
Creating a new project in Visual Studio 2010

A New Project dialog box appears. On the left side of the dialog box under Installed Templates, select the programming language of your choice. In our example, Visual Basic was chosen. On the middle of the dialog, choose a project template. To keep things simple, a Windows Forms Application is selected.
vs2010-oracle-dev-f2
Figure 2
Using the New Project dialog

You'll want to specify meaningful names for the project name (we used OraWinApp) and the solution name (we used OraWinApp). A solution contains one or more projects. When a solution contains only one project, many people use the same name for both. Notice that there is a dropdown list box allowing you to specify which version of the .NET Framework you want to target. If you are writing applications for an older version of the .NET Framework, you should select the appropriate version from the dropdown list. Click the Ok button to continue.

Adding a Reference
Because our project must connect to an Oracle database, it is necessary to add a reference to the ODP.NET DLL containing the data provider of our choice. Within the Solution Explorer on the right side of Visual Studio, select the project name, right click and select Add Reference. Alternatively, you can go to the menu bar and select Project and then select Add Reference.
vs2010-oracle-dev-f3
Figure 3
Adding a reference

The Add Reference dialog box appears. Select the .NET tab. Visual Studio will construct a list of .NET components available for you to add to your project. This may take several seconds. When complete, you can click on the Component Name column to alphabetize the component list.
vs2010-oracle-dev-f4
Figure 4
Selecting the ODP.NET Managed Data Provider for .NET 4

ODP.NET is found under the Oracle.DataAccess component name. Select Oracle.DataAccess from the list, then click the OK button to make the ODP.NET data provider known to your project. Be sure to select the correction version. Since this is a .NET 4 project, the 4.112.2.0 version of Oracle.DataAccess was chosen here, but you can chose any ODP.NET version beginning with 4.


Visual Basic/C# Statements
After adding references, it is standard practice to add Visual Basic Imports statements or C# using statements. Technically, these statements are not required, but they do allow you to refer to database objects without using lengthy, fully qualified names.
By convention, these statements appear at or near the top of a code file, before the namespace or class declaration.

Imports Oracle.DataAccess.Client ' Visual Basic ODP.NET Oracle managed provider
using Oracle.DataAccess.Client; // C# ODP.NET Oracle managed provider

If you added the reference, Intellisense will help you complete the addition of an Imports or using statement as shown in Figure 5.
vs2010-oracle-dev-f5
Figure 5
Adding an Imports statement in Visual Basic

Connection Strings and Objects
An Oracle connection string is inseparable from Oracle names resolution. In this article, we will connect to Oracle’s sample HR schema with user id “hr” and password “hr”. The tnsnames.ora file is an Oracle network configuration file that defines database addresses for establishing connections. Suppose we had a database alias of OraDb defined in a tnsnames.ora file as follows:
OraDb=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521))
)
(CONNECT_DATA=
(SERVER=DEDICATED)
(SERVICE_NAME=ORCL)
)
)


The OraDb alias defines the database address connection information for the client. To use the OraDb alias defined in the tnsnames.ora file shown above, you would use the following syntax:

Dim oradb As String = "Data Source=OraDb;User Id=hr;Password=hr;" ' Visual Basic
string oradb = "Data Source=OraDb;User Id=hr;Password=hr;"; // C#

You can modify the connection string to obviate the need for the tnsnames.ora file, however. Simply replace the name of the alias with how it would be defined in a tnsnames.ora file. The database alias in this article is specific to my database setup. (Click here for more information about creating a database alias for your database.)

' Visual Basic
Dim oradb As String = "Data Source=(DESCRIPTION=" _
+ "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521))" _
+ "(CONNECT_DATA=(SERVICE_NAME=ORCL)));" _
+ "User Id=hr;Password=hr;"

// C#
string oradb = "Data Source=(DESCRIPTION="
+ "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521))"
+ "(CONNECT_DATA=(SERVICE_NAME=ORCL)));"
+ "User Id=hr;Password=hr;";


As you can see above, the username and password are embedded in the connection string in clear text. This is the simplest approach to creating a connection string. However, the clear text approach is undesirable from a security perspective. In particular, you must understand that compiled .NET application code is only marginally more secure than the clear text source code files. It is very easy to decompile .NET DLL and EXE files and view the original clear text contents. (Encryption is in fact the appropriate solution, but that subject would be a quite lengthy digression from our discussion here.)
Next, you must instantiate a connection object from the connection class. The connection string must be associated with the connection object.

Dim conn As New OracleConnection(oradb) ' Visual Basic
OracleConnection conn = new OracleConnection(oradb); // C#

Notice that the connection string is associated with the connection object by being passed through the object's constructor, which is overloaded. The constructor's other overload allows the following alternative syntax:

Dim conn As New OracleConnection() ' Visual Basic
conn.ConnectionString = oradb

OracleConnection conn = new OracleConnection(); // C#
conn.ConnectionString = oradb;


After associating a connection string with a connection object, use the Open method to make the actual connection.

conn.Open() ' Visual Basic
conn.Open(); // C#

We'll cover error handling later.


Command Object
The command object is used to specify the SQL command text that is executed, either a SQL string or a stored procedure. Similar to the connection object, it must be instantiated from its class and it has an overloaded constructor. In this sample, ODP.NET will perform a SQL query to return the department_name from the departments table where the department_id is 10.
Dim sql As String = "select department_name from departments where department_id = 10" ' Visual Basic
Dim cmd As New OracleCommand(sql, conn)
cmd.CommandType = CommandType.Text

string sql = " select department_name from departments where department_id = 10"; // C#
OracleCommand cmd = new OracleCommand(sql, conn);
cmd.CommandType = CommandType.Text;


Using different overloads, the syntax can be structured slightly differently. The command object has methods for executing the command text, which will be seen in the next section. Different methods are appropriate for different types of SQL commands.

Retrieving a Scalar Value
Retrieving data from the database can be accomplished by instantiating an OracleDataReader object and using the OracleCommand’s ExecuteReader method, which returns an OracleDataReader object. Returned data is accessible by passing either the column name or zero-based column ordinal to the OracleDataReader.
Dim dr As OracleDataReader = cmd.ExecuteReader() ' Visual Basic
dr.Read()

Label1.Text = dr.Item("department_name") ' retrieve by column name
Label1.Text = dr.Item(0) ' retrieve the first column in the select list
Label1.Text = dr.GetString(0) ' return a .NET data type
Label1.Text = dr.GetOracleString(0) ' return an Oracle data type


C# developers must use accessor type methods for retrieving data. There are typed accessors for returning .NET native data types and others for returning native Oracle data types, all of which are available in C#, Visual Basic, or any other .NET language. Zero-based ordinals are passed to the accessors to specify which column to return.
OracleDataReader dr = cmd.ExecuteReader(); // C#
dr.Read();

label1.Text = dr["department_name"].ToString(); // C# retrieve by column name
label1.Text = dr.GetString(0).ToString(); // return a .NET data type
label1.Text = dr.GetOracleString(0).ToString(); // return an Oracle data type


In this simplified example, the returned value of department_name is a string and is used to set the value of the label control's text property, which is also a string. But if department_id, which is not a string, had been retrieved instead, there would be a data type mismatch. The .NET runtime attempts to implicitly convert from one data type to another when the source and destination data types don't match. Sometimes the data types are incompatible and the implicit conversion fails, throwing an exception. But even when it works, it's still better to use explicit data type conversions instead of implicit data type conversion.

An explicit cast to integer is shown below:

Label1.Text = CStr(dr.Item("department_id")) ' Visual Basic integer to string cast

C# is not as forgiving as Visual Basic on implicit conversions. You'll find yourself doing explicit conversions:

label1.Text = dr.GetInt16("department_id").ToString(); // C#

You can explicitly cast scalar values as well as arrays.
Close and Dispose
Either the connection object's Close or the Dispose method should be called to close the connection to the database. The Dispose method calls the Close method implicitly.
conn.Close() ' Visual Basic
conn.Dispose() ' Visual Basic

conn.Close(); // C#
conn.Dispose(); // C#


You don't have to explicitly call Close or Dispose if you use VB's Using keyword or C#'s using keyword.

using (OracleConnection conn = new OracleConnection(oradb)) // C#
{
conn.Open();

OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "select department_name from departments where department_id = 10";
cmd.CommandType = CommandType.Text;

OracleDataReader dr = cmd.ExecuteReader();
dr.Read();

label1.Text = dr.GetString(0);
}


In addition, OracleCommand includes a Dispose method; OracleDataReader includes a Close and Dispose method. Closing and disposing .NET objects free up system resources, ensuring more efficient application performance, which is especially important under high load conditions. You can experiment with some of the concepts we've learned here in Lab 1 (Retrieving Data from the Database) and Lab 2 (Adding Interactivity).


Error Handling
When an error occurs, .NET applications should gracefully handle the error and inform the user with a meaningful message. Try-Catch-Finally structured error handling is a part of .NET languages. Here is a relatively minimalist example of using the Try-Catch-Finally syntax:
' Visual Basic
Try
conn.Open()

Dim cmd As New OracleCommand
cmd.Connection = conn
cmd.CommandText = "select department_name from departments " _
+ "where department_id = " + TextBox1.Text
cmd.CommandType = CommandType.Text

If dr.Read() Then
Label1.Text = dr.Item("department_name") ' or use dr.Item(0)
End If
Catch ex As Exception ' catches any error
MessageBox.Show(ex.Message.ToString())
Finally
' In a real application, put cleanup code here.
End Try

// C#
try
{
conn.Open();

OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "select department_name from departments where department_id = " + textBox1.Text;
cmd.CommandType = CommandType.Text;

if (dr.Read()) // C#
{
label1.Text = dr["department_name"].ToString();
// or use dr.GetOracleString(0).ToString()
}
}
catch (Exception ex) // catches any error
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
// In a real application, put cleanup code here.
}


Although this approach will gracefully capture any errors in attempting to get data from the database, it is not user friendly. For example, look at the following message displayed when the database is unavailable:
vs2010-oracle-dev-f6
Figure 6
An ORA-12545 error caught and displayed to the user

An ORA-12545 is quite meaningful for an Oracle DBA or developer, but not for an end user. A better solution is to add an additional Catch statement to trap for the most common database errors and provide user-friendly messages.
' Visual Basic
Catch ex As OracleException ' catches only Oracle errors
Select Case ex.Number
Case 1
MessageBox.Show("Error attempting to insert duplicate data.")
Case 12545
MessageBox.Show("The database is unavailable.")
Case Else
MessageBox.Show("Database error: " + ex.Message.ToString())
End Select
Catch ex As Exception ' catches any error
MessageBox.Show(ex.Message.ToString())

// C#
catch (OracleException ex) // catches only Oracle errors
{
switch (ex.Number)
{
case 1:
MessageBox.Show("Error attempting to insert duplicate data.");
break;
case 12545:
MessageBox.Show("The database is unavailable.");
break;
default:
MessageBox.Show("Database error: " + ex.Message.ToString());
break;
}
}
catch (Exception ex) // catches any error not previously caught
{
MessageBox.Show(ex.Message.ToString());
}



Notice the two Catch statements in the code sample above. If there aren't any Oracle errors to catch, the first Catch statement branch is skipped, leaving any other non-Oracle error to be caught by the second Catch statement. Catch statements must be ordered in the code from most specific to most general. After implementing the user-friendly exception handling code, the ORA-12545 error message appears as follows:
vs2010-oracle-dev-f7
Figure 7 A user-friendly error message for an ORA-12545 error

The Finally code block is always executed regardless of whether or not an error occurred. It is where cleanup code belongs. If you don't use Using or using, you should dispose your connection and other objects in the Finally code block.

Retrieving Multiple Values Using a DataReader

Thus far our examples have only showed how to retrieve a single value. An OracleDataReader can retrieve values for multiple columns and multiple rows. First consider a multiple column, single row query:

select department_id, department_name, location_id from departments where department_id = 10

To keep things simple for this article, we are using a single table, the departments table. To obtain the values of the columns, either zero-based ordinals or column names can be used. Ordinals are relative to the order in the query. Thus, the location_id column's value can be retrieved in Visual Basic by using either dr.Item(2) or dr.Item("location_id").
Here is a code snippet that concatenates the department_name and location_id columns from the previous query:

Label1.Text = "The " + dr.Item("department_name") + " department is in " _
+ dr.Item("location_id") ' VB

label1.Text = "The " + dr["department_name"].ToString() + " department is in " +
dr["location_id"].ToString(); // C#


Now consider a query that returns multiple rows:

select department_id, department_name, location_id from departments

To process multiple rows returned from an OracleDataReader, some type of looping construct is needed. Furthermore, a control that can display multiple rows is desirable. An OracleDataReader is a forward-only, read-only cursor, so it can't be bound to an updateable or fully scrollable control such as a Windows Forms DataGrid control. An OracleDataReader is compatible with a ListBox control, as the following code snippet illustrates:

While dr.Read() ' Visual Basic
ListBox1.Items.Add("The " + dr.Item("department_name") _
+ " department is in " + dr.Item("location_id"))
End While

while (dr.Read()) // C#
{
listBox1.Items.Add("The " + dr["department_name"].ToString() + " department is in " +
dr["location_id"].ToString());
}


Lab 3 (Retrieve Multiple Columns and Rows with an OracleDataReader) highlights some of these concepts.

Building and Running on Windows x64

When running Visual Studio 2010 on a Windows x64 operating system, you can use the Configuration Manager to change the target platform type. Select the solution in the Solution Explorer, right-click, and select Configuration Manager.


vs2010-oracle-dev-f8
Figure 8
You can use the Configuration Manager to change the target platform type when building on Windows x64.

Summary

This article has introduced you to the process of accessing Oracle databases using .NET programming languages. You should now have the capability to connect to the database and retrieve multiple columns and rows.

Lab 1: Retrieving Data from the Database

We begin with the requirement that you've created a project and added a reference as shown previously in this article.

  1. Continue by adding a button control and a label control to the Windows form. Be sure to leave room above the controls to allow additions that will be made in Lab 2.

    vs2010-oracle-dev-f9
  2. Figure 9 Lab 1 form with button and label controls
  3. Add code to retrieve data from the Oracle database and display the results on the form. Put the code in a click event handler for the button. The easiest way to get started with this task is to double click the button because it will create a stub for the event handler.

    vs2010-oracle-dev-f10
    Figure 10 Click event handler stub.
  4. Add Visual Basic Imports statements before the Public Class declaration or C# using statements before the namespace declaration.

    Imports Oracle.DataAccess.Client ' Visual Basic, ODP.NET Oracle managed provider
    using Oracle.DataAccess.Client; // C#, ODP.NET Oracle managed provider
  5. Add the Visual Basic version of the click event handler code between the Private Sub and End Sub statements (be sure to replace ORASRVR with your server's host name and replace the service name entry with your database’s service name):

    Dim oradb As String = "Data Source=(DESCRIPTION=(ADDRESS_LIST=" _
    + "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))" _
    + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));" _
    + "User Id=hr;Password=hr;"

    Dim conn As New OracleConnection(oradb) ' Visual Basic
    conn.Open()

    Dim cmd As New OracleCommand
    cmd.Connection = conn
    cmd.CommandText = _
    "select department_name from departments where department_id = 10"
    cmd.CommandType = CommandType.Text

    Dim dr As OracleDataReader = cmd.ExecuteReader()
    dr.Read() ' replace this statement in next lab
    Label1.Text = dr.Item("department_name") ' or dr.Item(0), remove in next lab

    dr.Dispose()
    cmd.Dispose()
    conn.Dispose()


    Add the following C# code to the click event handler between the { and } curly braces for the button's click event handler (be sure to replace ORASRVR with your server's host name and replace the service name entry with your database’s service name):

    string oradb = "Data Source=(DESCRIPTION=(ADDRESS_LIST="
    + "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))"
    + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
    + "User Id=hr;Password=hr;";

    OracleConnection conn = new OracleConnection(oradb); // C#
    conn.Open();

    OracleCommand cmd = new OracleCommand();
    cmd.Connection = conn;
    cmd.CommandText =
    "select department_name from departments where department_id = 10";
    cmd.CommandType = CommandType.Text;

    OracleDataReader dr = cmd.ExecuteReader();
    dr.Read(); // replace this statement in next lab
    label1.Text = dr["department_name"].ToString(); // remove in next lab

    dr.Dispose();
    cmd.Dispose();
    conn.Dispose();
  6. Run the application. Click the button. You should see the following:

    vs2010-oracle-dev-f11
    Figure 11
    Data successfully retrieved


Lab 2: Adding Interactivity

Now that the basics of database access are implemented in the code, the next step is to add interactivity to the application. Instead of running the hard coded query, a textbox control can be added to accept a user input for the department number (i.e., department_id).

  1. Add a textbox control and another label control to the form as shown below. Set the text property of the Label2 control to “Enter department_id:” and make sure that the Text property of TextBox1 isn't set to anything.

    vs2010-oracle-dev-f12
    Figure 12
    Lab 2 form with button and label controls
  2. Modify the code that defines the select string:

    cmd.CommandText = _
    "select department_name from departments where department_id = "_
    + TextBox1.Text 'VB

    cmd.CommandText = "select department_name from departments where department_id = " + textBox1.Text; // C#
  3. Run the application. Test the application by entering 10 for the department_id. Retest the application by entering an invalid department_id (e.g., 12). The application will abort.

    vs2010-oracle-dev-f13
    Figure 13
    An unhandled exception
  4. Modify your code to prevent an error when an invalid department_id is entered. Recall that the ExecuteReader method actually returns an object. Replace the line containing dr.Read with all of the following statements.

    If dr.Read() Then ' Visual Basic
    Label1.Text = dr.Item("department_id").ToString()
    Else
    Label1.Text = "department_id not found"
    End If

    if (dr.Read()) // C#
    {
    label1.Text = dr["department_id"].ToString();;
    }
    else
    {
    label1.Text = "department_id not found";
    }


    Test the application by entering a department_id that does not exist. Now the application no longer aborts. Enter the letter A instead of a number and click the button. The application aborts. Clearly, our application needs a better approach to handling errors.

    Although it could be argued that the application should not allow the user to make invalid inputs that would cause an error, ultimately the application must have robust error handling added. Not all errors are preventable, so error handling must be implemented.


Lab 3: Retrieve Multiple Columns and Rows with an OracleDataReader


Now that a single value has been retrieved, the next step is to retrieve multiple columns and rows with an OracleDataReader. A ListBox control is added to the form to display the results.

  1. Add a ListBox control to the form. Resize the control to fill most of the width of the form as shown below.

    vs2010-oracle-dev-f14
    Figure 14
    Form with ListBox added
  2. Remove the where clause from the query and add the additional columns:

    cmd.CommandText = _
    "select department_id, department_name, location_id from departments" ' VB

    cmd.CommandText = "select department_id, department_name, location_id from departments "; // C#
  3. The query results will be read in a while loop and will populate the ListBox control. Modify your Visual Basic code to look like this, making the appropriate changes to the host and service name for your database:

    Dim oradb As String = "Data Source=(DESCRIPTION=(ADDRESS_LIST=" _
    + "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))" _
    + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));" _
    + "User Id=hr;Password=hr;"

    Dim conn As New OracleConnection(oradb) ' Visual Basic
    conn.Open()

    Dim cmd As New OracleCommand
    cmd.Connection = conn
    cmd.CommandText = _
    "select department_id, department_name, location_id from departments" ' VB
    cmd.CommandType = CommandType.Text

    Dim dr As OracleDataReader = cmd.ExecuteReader()
    While dr.Read()
    ListBox1.Items.Add("The " + dr.Item("department_name") + _
    " department is in " + dr.Item("location_id").ToString())
    End While

    dr.Dispose()
    cmd.Dispose()
    conn.Dispose()
    Modify your C# code to look like this:
    string oradb = "Data Source=(DESCRIPTION=(ADDRESS_LIST="
    + "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))"
    + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"
    + "User Id=hr;Password=hr;";

    OracleConnection conn = new OracleConnection(oradb); // C#
    conn.Open();

    OracleCommand cmd = new OracleCommand();
    cmd.Connection = conn;
    cmd.CommandText = "select department_id, department_name, location_id from departments.168";
    cmd.CommandType = CommandType.Text;

    OracleDataReader dr = cmd.ExecuteReader();
    while (dr.Read())
    {
    listBox1.Items.Add("The " + dr["department_name"].ToString() +
    " department is in " + dr["location_id"].ToString());
    }

    dr.Dispose();
    cmd.Dispose();
    conn.Dispose();
  4. Run the application. The ListBox should be populated with all of the department names and locations from the departments table. The code downloads have error handling implemented.