.net

  • submit to reddit

Core ASP.NET

By Holger Schwichtenberg

16,349 Downloads · Refcard 46 of 151 (see them all)

Download
FREE PDF


The Essential ASP.NET Cheat Sheet

ASP.NET stands for “Active Server Pages .NET”, which is a framework for the development of dynamic websites and web services. This DZone Refcard summarizes the most commonly used core functions and controls in ASP.NET. Author Holger Schwichtenberg shows you how to set up your ASP.NET development environment, explains the Webform model, and showcases common WebControls for Lists and Validation. He also explores ASP.NET state management features, configuration file management and shows the typical content of an .aspx page. This Refcard is useful for some of the most common tasks with ASP.NET, regardless of version number.
HTML Preview
Core ASP.NET

Core ASP.NET

By Holger Schwichtenberg

ABOUT ASP.NEt

ASP.NET stands for “Active Server Pages .NET”, however the full name is rarely used. ASP.NET is a framework for the development of dynamic websites and web services. It is based on the Microsoft .NET Framework and has been part of .NET since Version 1.0 was released in January 2002. The current version named 3.5 Service Pack 1 was released in August 2008. The next version, 4.0, is expected to be released at the end of the year 2009.

This Refcard summarizes the most commonly used core functions of ASP.NET. You will find this Refcard useful for some of the most common tasks with ASP.NET, regardless of the version you are using

Instalation

The best development environment for ASP.NET is Microsoft’s Visual Studio. You can either use the free Visual Web Developer Express Edition (http://www.microsoft.com/express/ vwd/) or any of the commercial editions of Visual Studio (e.g. Visual Studio Professional). The latest version that supports ASP.NET 2.0 and ASP.NET 3.5 is “2008” (internal version: 9.0). The .NET Framework and ASP.NET are part of the setup of Visual Web Developer Express Edition and Visual Studio. However, make sure you install Service Pack 1 for Visual Studio 2008, as this will not only fix some bugs but also add a lot of new features.

ASP.NET needs a server with the HTTP protocol (web server) to run. Visual Web Developer Express 2005/2008 and Visual Studio 2005/2008 contain a webserver for local use on your development machine. The “ASP.NET Development Server” (ADS) will be used when specifying a “File System” location when creating your project. Thus, “HTTP” would mean you address a local or remote instance of Internet Information Server (IIS) or any other ASP.NET enabled web server. ADS is a lightweight server that cannot be reached from other systems. However, there are differences between ADS and IIS, especially in the security model that makes it sometimes hard for beginners to deploy a website to the IIS that was developed with ADS. On the production system you will use IIS and only install the .NET Framework, because Visual Studio is not required here.

Hot Tip

If you choose to use Internet Information Server (IIS), install the IIS on your machine before installing the .NET Framework or Visual Studio. If you did not follow this installation order, you may use aspnet_regiis. exe to properly register ASP.NET within the IIS.

ASP.NEt Web Applications

An ASP.NET application consists of several .aspx files. An .aspx file can contain HTML markup and special ASP.NET markup (called Web Controls) as well as the code (Single Page Model). However, the Code Behind Model which comes with a separate code file called, the “Code Behind File” (.aspx. cs or .aspx.vb), provides a cleaner architecture and better collaboration between Web designers and Web developers. ASP.NET applications may contain several other elements such as configuration files (maximum one per folder), a global application file (only one per web application), web services, data files, media files and additional code files.

There are two types of Web projects: “Website Projects” (File/ New/Web Site) and “Web Application Projects” (File/New/ Project/Web Application). “Website” is the newer model, while Web Application Projects mainly exist for compatibility with Visual Studio .NET 2002 and 2003. This Refcard will only cover Web Site Projects. Most of this content is also valid for Web Applications.

Hot Tip

A well designed ASP.NET application distinguishes itself by having as little code in the Code Behind files and other code files as possible. The large majority of your code should be in referenced Assemblies (DLLs) as they are reusable in other Web applications. If you don’t want to put your code into a separate assembly, you at least should use separate classes in the “App_Code” folder within your web project.
Figure 1

Figure 1: The Content of an ASP.NET Web Application

The ASP.NET Web form Model

ASP.NET uses an object- and event-oriented model for web pages. The ASP.NET Page Framework analyzes all incoming requests as well as the .aspx page that the request is aimed at. The Page Framework creates an object model (alias control tree) based on this information and also fires a series of events. Event handlers in your code can access data, call external code in referenced .NET assemblies and manipulate the object model (e.g. fill a listbox or change the color of a textbox). After all event handlers have executed, the Page Framework renders the current state of the object model into HTML tags with optional CSS formatting, JavaScript code and state information (e.g. hidden fields or cookies). After interacting with the page, the user can issue a new request by clicking a button or a link that will restart the whole process.

Figure 2

Figure 2: The ASP.NET request/response life cycle

Web Controls

An ASP.NET page can contain common HTML markup. However, only ASP.NET web controls provide full objectand event-based functionality. Web controls have two representations: In the .aspx files they are tags with the prefix “asp:”, e.g. . In the code they are .NET classes, e.g. System.Web.UI.WebControls.TextBox.

Table 1 lists the core members of all web controls that are implemented in the base class “System.Web.UI.WebControls. WebControl”.

Name of Member Description
Id Unique identifier for a control within a page
ClientID Gets the unique identifier that ASP.NET generates if more than one control on the page has the same (String) ID.
Page Pointer to the page where the control lives
Parent Pointer to the parent control, may be the same as “Page”
HasControls() True, if the control has sub-controls
Controls Collection of sub-controls
FindControl(“NAME”) Finds a sub-control within the Controls collection by its ID
BackColor, BorderColor,
Borderstyle, BorderWidth,
Font, ForeColor, Height,
Width, ToolTip, TabIndex
Self-explaining properties for the formatting of the control.
CssClas The name of CSS class that is used for formatting the control
Style A collection of single CSS styles, if you don’t want to use a CSS class or override behavior in a CSS class
EnableViewState Disables page-scoped state management for this control
Visible Disables rendering of the control
Enabled Set to false if you want the control to be disabled in the browser
Focus() Set the focus to this control
DataBind() Gets the data (if the control is bound to a data source)
Init() Fires during initializtion of the page. Last chance to change basic setting e.g. the culture of the current thread that determines the behavior used for rendering the page.
Load() Fires during the loading of the page. Last to change to do any preparations./td>
PreRender() Fires after all user defined event handlers have completed
and right before rendering of the page starts. Your last
chance to make any changes to the controls on the page!
UnLoad() Event fires during the unloading of a page.

Table 1: Core Members in the base class system. Web.UI.WebControls.WebControl.

Tables 2, 3 and 4 list the most commonly used controls for ASP. NET web pages. However, there are more controls included in the .NET platform and many more from third parties not mentioned here.

Control Purpose/strong> Important specific members in
addition to the members inheritedn
from WebControl
<asp:Label> Static Text Text
<asp:TextBox> Edit Text (single line,
multiline or password)
TextMode, Text, TextChanged()
<asp:FileUpload> Choose a file for upload FileName, FileContent, FileBytes,SaveAs()
<asp:Button> Display a clasic button Click(), CommdName, Command()
<asp:ImageButton> Display a clickable image Click(), CommdName, Command()
<asp:LinkButton> Display a hyperlink that works like a button ImageUrl, ImageAlign, Click(),
CommdName, Command()
<asp:CheckBox> Choose an option Text, Checked, CheckedChanged()
<asp:RadioButton> Choose an option Text, Checked, CheckedChanged()
<asp:HyperLink> Display a hyperlink NavigateURL, Target, Text
<asp:Image> Display an image ImageURL, ImageAlign
<asp:ImageMap> Display a clickable
image with different
regions
ImageURL, ImageAlign,

Table 2: Core controls for ASP.NET web pages.

List controls display several items that the user can choose from. The selectable items are declared static in the .aspx file or created manually using the Items collection or created automatically by using data binding. For data binding you can fill DataSource with any enumerable collection of .NET objects. DataTextField and DataValueField specify which properties of the objects in the collection are used for the list control.

Hot Tip

If you bind a collection of primitive types such as strings or numbers, just leave DataTextField and DataValueField empty.

Hot Tip

Setting AppendDataBoundItems to true will add the databound items to the static items declared in the .aspx file. This will allow the user to select values that don’t exist in the data source such as the values “All” or “None”
Control Purpose Important specific members in
addition to the members inherited
from WebControl
<asp:Drop DownList> Allows the user to select
a single item from a
drop-down list
Items.Add(), Items.
Remove(), DataSource,,
DataTextField, DataValueField,
AppendDataBoundItems,
SelectedIndez, SelectedItem,
SelectedValue, SelectedIndexChanged()
<asp:ListBox> Single or multiple selection box Items.Add(), Items.
Remove(), DataSource,,
DataTextField, DataValueField,
AppendDataBoundItems,
SelectedIndez, SelectedItem,
SelectedValue, SelectedIndexChanged(),
Rows, SelectionMode
<asp:Check BoxList> Multi selection check box group Items.Add(), Items.
Remove(), DataSource,,
DataTextField, DataValueField,
AppendDataBoundItems,
SelectedIndez, SelectedItem,
SelectedValue, SelectedIndexChanged(),
RepeatLayout, RepeatDirection
<asp:Radio ButtonList> Single selection radio button group Items.Add(), Items.
Remove(), DataSource,,
DataTextField, DataValueField,
AppendDataBoundItems,
SelectedIndez, SelectedItem,
SelectedValue, SelectedIndexChanged(),
RepeatLayout, RepeatDirection
<asp:Bulleted List> List of items in a bulleted format Items.Add(), Items.
Remove(), DataSource,,
DataTextField, DataValueField,
AppendDataBoundItems,
SelectedIndez, SelectedItem,
SelectedValue, SelectedIndexChanged(),
BulletImageUrl, BulletStyle

Table 3: List Controls for ASP.NET web pages

Validation Controls check user input. They always refer to one input control ControlToValidate and display a text ErrorMessage if the validation fails. They perform the checks in the browser using JavaScript and also on the server. The client side validation can be disabled by setting EnableClientScript to false. However, the server side validation cannot be disabled for security reasons.

Control Purpose Important specific members
in addition to the members
inherited from WebControl
<asp:Required
FieldValidator>
Checks if a user changed the
initial value of an input control
ControlToValidate, ErrorMessage,
Display, EnableClientScript,
IsValid, InitialValue
<asp:Compare
Validator>
Compares the value entered by
the user in an input control with
the value entered in another
input control, or with a constant
value
ControlToValidate, ErrorMessage,
Display, EnablesClientScript,
IsValid, ValueToCompare, Type,
ControlToCompare
<asp:Range
Validator>
Checks whether the value of
an input control is within a
specified range of values
ControlToValidate, ErrorMessage,
Display, EnableClientScript,
IsValid, MinimumValue,
MaximumValue, Type
<asp:Regular
Expression Validator>
Checks if the user input
matches a given regular
ControlToValidate, ErrorMessage,
Display, EnavleClientScript,
IsValid, ValidationExpression
<asp:Custom
Validator>
Performs custom checks on the
server and optional also on the
client using JavaScript
ControlTValidate, ErrorMessage,
Display, EnableClientScript,
IsValid, ValidateEmptyText,
Client ValidationFunction,
ServerValidate()

Hot Tip

For the CustomValidator you can optionally write a JavaScript function that performs client side validation. The function has to look like this: <script type=”text/javascript”> function ClientValidate(source, args) { if (x > 0) // Any condition { args.IsValid=true; } else { args.IsValid=false; } } </script>

The Page Class

All web pages in ASP.NET are .NET classes that inherit from the base class “System.Web.UI.Page”. The class Page has associations to several other objects such as Server, Request, Response, Application, Session and ViewState (see figure 3). Therefore, developers have access to a wide array of properties, methods and events within their code. Table 5 lists the most important members of a Page and its dependent classes. Please note that the Page class has the class Control in its inheritance hierarchy and therefore shares a lot of members with the WebControl class (e.g. Init(), Load(), Controls, FindControl). However, these members are not repeated here.

Figure 3

Figure 3: Object Model of “System.Web.UI.Page”

Member Description
Page Title Title string of the Page
Page.IsPostBack True, if page is being loaded in response to a client postback. False if it is being loaded for the first time.
Page.IsAsync True, if the page is loaded in an asynchronous request (i.e. AJAX request)
Page.IsValid True, if all validation server controls in the current validation group validated successfully
Page.Master Returns the MasterPage object associated with this page
Page.PreviousPage Gets the page that transferred control to the current page (only available if using Server.Transfer, not available with Response. Redirect)
Page.SetFocus(Control ControlID) Sets the browser focus to the specified control (using JavaScript)
Trace.Write Writes trace information to the trace log.
User.Identity.IsAuthenticated True, if the user has been authenticated.
User.Identity.AuthenticationType Type of Authentication used (Basic, NTLM, Kerberos, etc)
User.Identity.Name Name of the current user
Server.MachineName Name of the computer the web server is running on
Server.GetLastError() Gets the Exception object for the last exception
Server.HtmlEncode(Text) Applies HTML encoding to a string
Server.UrlEncode(Pah) Applies URL encoding to a string
Server.MapPath(Path) Maps the given relative path to an absolute path on the web server
Server.Transfer(Path) Stops the execution of the current page and starts executing the given page as part of the current HTTP request
Request.AcceptTypes String array of cliet-supported MIME accept types.
Request.Browser Provides information about the browser
Request.ClientCertificate Provides the certificate of the client, if SSL client authentication is used
Request.Cookies The list of cookies that the browser sent to the web server
Request.Form The name and value of the input fields the browser sent to the web server
Request.Headers Data from the HTTP header the browser sent to the web server
Request.IsAuthenticated True, if the user is authenticated
Request.IsSecureConnection True, if SSL is used
Request.Path Virtual path of the HTTP request (without server name)
Request.QueryString Name/Value pairs the browser sent as part of the URL
Request.ServerVariables Complete list of name/value pairs with information about the server and the current request
Request.Url Complete URL of the request
Request.UrlReferrer Refering URL of the request (Previous page, the browser visited)
Request.UserAgent Browser identification
Request.UserHostAddress IP address of the client
Request.UserLanguages Preferred languages of the user (determined by browser settings)
Response.BinaryWrite(bytes) Writes information to an HTTP response output stream.
Response.Write(string) Writes information to an HTTP response output stream.
Response.WriteFile(string) Writes the specified file directly to an HTTP response output stream.
Response.BufferOutput True if the output to client is buffered
Response.Cookies Collection of cookies that shall be sent to the browser
Response.Redirect(Path) Redirects a client to a new URL using the HTTP status code 302
Response.StatusCode HTTP status code (integer) of the output returned to the client
Response.StatusDescription HTTP status string of the output returned to the client
Session.SessionID Unique identifier for the current session (a session is user specific)
Session.Item Gets or sets individual session values.
Session.IsCookieless True, if the ID for the current sessions are embedded in the URL. False, if its stored in an HTTP cookie
ViewState.Item Gets or sets the value of an item stored in the ViewState, which is a hidden field used for state management witin a page
Application.Item Gets or sets the value of an item stored in the application state, which is an applicationscope state management facility

Table 5: Most important members of the Page class and its associated classes

A Typical Page

Figure 4 shows the typical content of an .aspx page and Figure 5 the content of a typical code behind class. The sample used is a registration form with three fields: Name, Job Title and Email Address.


<%@ Page Language=”C#” AutoEventWireup=”true”
  CodeFile=”PageName.aspx.cs” Inherits=”PageName” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//en”
  “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
  <title>Registration Page</title>
  <link href=”MyStyles.css” rel=”stylesheet” type=”text/css”/>
  <style type=”text/css”>
   .Headline
   {
    font-size: large; font-weight: bold;
   }
  </style>
 </head>
 <body>
  <form id=”c_Form” ruanat=”server”>
  <div>
   <asp:Label runat=”server” ID=”C_Headline” Text=”Please register:”
     class=”Headline”></asp:label>
    <p>Name:
   <asp:TextBox ID=”C_Name” runat=”server”></asp:TextBox>
   <asp:RequiredFieldValidator ID=”C_NameVal” ControlToValidate=”C_
   Name” ruanat=”server” ErrorMessage=”Name required”></
   asp:RequiredFieldValidator>
 </p>
    <p>Job Title:
   <asp:DropDownList ID=”C_JobTitle” runat=”server”>
  <asp:ListItem Text=”Software Developer” Value=”SD”></
 asp:ListItem>
  <asp:ListItem Text=”Software Architect” Value=”SA”></
   asp:ListItem>
  </asp:DropDownList>
 </p>
<p>EMail:
  <asp:TextBox ID=”C_EMail” runat=”server”></asp:TextBox>
   <asp:RequiredFieldValidator Id=”C_EMailVal1” ControlToValidate=”C_
  EMail” runat=”server” ErrorMessage=”EMail required”></
  asp:RequiredFieldValidator>
  <asp:RegularExpressionValidator ID=”C_EMailVal2”
 ControlToValidate=”C_EMail” runat=”server” ErrorMessage=”Email
   not valid” ValidationExpression=”\w+([-+.’]\w+)*@\w+([-.]\
     w+)*\.\w+([-.]\w+)*”>
   </asp:RegularExpressionValidator>
   </p>
   <p>
  <asp:Button ID=”C_register” runat=”server” Text=”Register”
 onclick=”C_Register_Click”/>
   </p>
   </div>
 </form>
</body>
</html>

Figure 4: Typical content of an ASPX file


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class PageName : System.Web.UI.Page
 {
  protected void Page_Load(object sender, EventArgs e)
   {
    // If an authenticated users starts using this page,
    // use his login name in the name textbox
    if (!Page.IsPostBack && Page.User.Identity.IsAuthenticated)
    {
     this.C_Name.Text = Page.User.Identity.Name;
     this.C_Name.Enabled = false;
    }
   }
 protected void C_Register_Click(object sender, EventArgs e)
  {
   if (Page.IsValid) // if all validation controls succedded
   { // call business logic and
    if (BL.Register(this.C_Name.Text, this.C_EMail.Text, this.C_
     JobTitle.SelectedValue))
    { // redirect to confirmation page
     Response.Redirect(“RegistrationConfirmation.aspx”);
    }
    else
    { // change the headline
     this.C_Headline. = “You are already registered!”;
    }
   }
  }
}    

Figure 5: Typical content of a Code Behind file

State Management

State management is a big issue in web applications as the HTTP protocol itself is stateless. There are three standard options for state management: hidden files, URL parameters and cookies. However, ASP.NET has some integrated abstractions from these base mechanisms know as View State, Session State, and Application State. Also, the direct use of cookies is supported in ASP.NET.

Hot Tip

Disabling the View State (EnableViewState=false in a control) will significantly reduce the size of the page sent to the browser. However, you will have to take care of the state management of the controls with disabled View State on your own. Some complex controls will suffer the loss of functionality without View State.

The following code snippet shows how to set values for a counter stored in each of these mechanisms:


ViewState[“Counter”] = CurrentCounter_Page + 1;
Session[“Counter”] = CurrentCounter_Session + 1;
Application[“Counter”] = CurrentCounter_Application + 1;
Response.Cookies[“Counter”].Value = (CurrentCounter_User +
  1).ToString();
Response.Cookies[“Counter”].Expires = DateTime.MaxValue; // no
  expiration

Figure 6: Setting Values

Hot Tip

When reading value from these objects, you have to check first if they already exist. Otherwise you will recieve the exception “NullReferenceExeception: Object reference not set to an instance of an object.”

The following code snippet shows how to read the current counter value from each of these mechanisms: Next Column ---->

Mechanism Scope Lifetime Base Mechanism Data Type Storing Value Reading Value
View State Single user on a single page Leaving the current page Hidden FIeld “ViewState” Object (any serializable.NET data type) Page.ViewState Page.ViewState
Session State Latest interaction of a single
user with the web page
Limited number of minutes after the last request from
the user
Cookie (“ASPSessionJD...”)or URL Parameter “(S(...))”
plus server side store (local RAM, RAM on dedicated
server or database)
Object. Object must be serializable
if the store is not the local RAM
Page.Session Page.Session
Cookies A single User Closing of the browser or dedicated point in time Cookie String Page.Response.Cookies/td> Page.Response.Cookies
Application State All users Shutting down the web application Local RAM Object Page.Application Page.Application

long CurrentCounter_Application, CurrentCounter_ApplicationLimited,
CurrentCounter_Session, CurrentCounter_Page, CurrentCounter_User;
 if (Application[“Counter”] == null) { CurrentCounter_Application =
  0; }
  else { CurrentCounter_Application = Convert.ToInt64(Application[“C
   ounter”]); }
 if (Session[“Counter”] == null) { CurrentCounter_Session = 0; }
  else { CurrentCounter_Session = Convert.
   ToInt64(Session[“Counter”]);}
 if (ViewState[“Counter”] == null) { CurrentCounter_Page = 0; }
  else { CurrentCounter_Page = Convert.
ToInt64(ViewState[“Counter”]); }
 if (Request.Cookies[“Counter”] == null) { CurrentCounter_User = 0; }
  else { CurrentCounter_User = Convert.ToInt64(Request.
   Cookies[“Counter”].Value); }

Figure 7: Reading Values

Configuration

All configurations for ASP.NET applications are stored in XMLbased configuration files with the fixed name “web.config”. In addition to the configuration files in the application root folder, subfolders may also contain a web.config that overrides parent settings. Also, there are the global configuration files machine. config and web.config in the folder \Windows\Microsoft.NET\ Framework\v2.0.50727\CONFIG that provide some default settings for all web applications. (Note: v2.0.50727 is still correct for ASP.NET 3.5!).

Visual Studio and Visual Web Developer create a default root configuration file in your web project that contains a lot of internal setting for ASP.NET 3.5 to work properly. Figure 6 shows a fragment from a web.config file with settings that are often used.


<!-- Connection strings -->
<connectionStrings>
  <add name=”RegistrationDatabase” connectionString=”Data
Source=EO2;Initial Catalog= RegistrationDatabase;Integrated
Security=True” providerName=”System.Data.SqlClient” />
</connectionStrings>
<!-- User defined settings -->
<AppSettings>
  <and key=”WebmasterEMail” value=”hs@IT-Visions.de” />
</appSettings>
<system.web>
  <!-- Specify a login page -->
  <!-- Use the URL for storing the authentication ID if cookies are
not allowed -->
  <!-- Set the authentication timeout to 30 minutes -->
<authentication mode=”Forms”>
  <forms loginUrl=”Login.aspx” cookieless=”AutoDetect” timeout=”30”>
  </forms>
  </authentication>
   <!-- Deny all unauthorizd access to this application -->
  <authorization>
   <deny users=”?” />
  </authorization>
 <!-- Use the URL for storing the session ID if cookies are not
allowed -->
 <!-- Set the session timeout to 30 minutes -->
 <sessionState cookieless=”AutoDetect” timeout=”30”></sessionState>
<!-- Display custom error pages for remote users -->
<customErrors mode=”RemoteOnly” defaultRedirect=”GenericErrorPage.
  htm”>
  <error statusCode=”403” redirect=”NoAccess.htm” />
  <error statusCode=”404” redirect=”FileNotFound.htm” />
</customErrors>
<!-- Turn on debugging -->
<compilation debug=”false”>

Figure 8: Typical setting in the web.config file.

Hot Tip

Please make sure you turn debugging off again before deploying your application as this decreases execution performance.

Deployment

ASP.NET applications can be deployed as source code via the so called “XCopy deployment”. This means you copy the whole content of the web project folder to the production system and configure the target folder on the production system as an IIS web application (e.g. using the IIS Manager). The production web server will automatically compile the application during the first request and recompile automatically if any of the source files changed.

However, you can precompile the application into .NET assemblies to improve protection of your intellectual property and increase execution speed for the first user. Precompilation can be performed through Visual Studio/Visual Web developer (Menu “Build/Publish Website”) or the command line tool aspnet_compiler.exe.

Hot Tip

Download the “Visual Studio 2008 Web Deployment Projects” from microsoft.com. This is an Add-In that provides better control over the precompilation process.

About The Author

Photo of author Holger Schwichtenberg

Holger Schwichtenberg

Holger Schwichtenberg is one of Europe’s best-known experts on .NET and Windows PowerShell. He holds both a Master’s degree and a Ph.D. in business informatics. Microsoft recognizes him as a Most Valuable Professional (MVP) since 2003. He is a .NET Code Wise Member, an MSDN Online Expert and an INETA speaker. He regularly gives high-level talks at conferences such as TechEd, Microsoft Summit, BASTA and IT Forum. He is the CEO of the German based company www.IT-Visions.de that provides consulting and training for many companies throughout Europe.

Publicaitions

Holger Schwichtenberg has published more than twenty books for Addison Wesley and Microsoft Press in Germany, as well as about 400 journal articles. His recent book “Essential PowerShell” has also been published by Addison Wesley in English.

Blog: www.dotnet-doktor.de (German)

Website: www.IT-Visions.de/en

Recommended Book

ASP.NET

An in-depth guide to the core features of Web development with ASP.NET, this book goes beyond the fundamentals. It expertly illustrates the intricacies and uses of ASP.NET 3.5 in a single volume. Complete with extensive code samples and code snippets in Microsoft Visual C# 2008, this is the ideal reference for developers who want to learn what s new in ASP.NET 3.5, or for those building professional-level Web development skills.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose: Miguel Garcia Talks Scala and .Net

Miguel Garcia, a member of the Scala group at EPFL, gave an insightful, informative interview at scala-lang.org regarding his Microsoft-funded efforts to make Scala productivity available to .Net developers, which have recently come to fruition. On why people...

0 replies - 17909 views - 07/18/11 by Jim Moscater in Daily Dose

Getting Started with Visual Studio 2010

By Alessandro Del Sole

16,952 Downloads · Refcard 118 of 151 (see them all)

Download
FREE PDF


The Essential Visual Studio 2010 Cheat Sheet

The Visual Studio 2010 Refcard focuses on the new features in this release and the most common keyboard shortcuts. It will get you started with the IDE and show you how to create, build and debug applications. Youll learn about the WPF Code Editor, which has improved extensibility and code reusability. Youll learn about the "Generate from Usage" tool. Youll also learn about drag and drop data binding with WPF and Silverlight. This Refcard is the perfect companion for the .NET developer working in Visual Studio 2010, whether its WPF, Silverlight, C#, VB, or F# development.
HTML Preview
Getting Started with Visual Studio 2010

Getting Started with Visual Studio 2010

By Alessandro Del Sole

INTRODUCTION

The new version of the Visual Studio 2010 Integrated Development Environment ships with a number of new important features. Such features are both related to the IDE architecture and to the coding experience, with the addition of new tools as well. This Refcard is a quick reference to the most important new features and instruments in Visual Studio 2010, also providing tips to most common shortcuts.

STARTING WITH VISUAL STUDIO 2010

Visual Studio 2010 is the developer tool used for creating .NET applications. There are different editions which cover every need, such as the Ultimate edition or the free Express editions (the latter are specific for hobbyists and students).

Starting the IDE

When you run Visual Studio 2010, the first thing you notice is a new Start Page which provides shortcuts, organized into tabs, to lots of learning resources about programming different Microsoft technologies with Visual Studio. These include the .NET Framework and programming languages, data platform, cloud computing or tools for teams. The following figure shows how the Start Page looks:

Visual Studio 2010 face

Visual Studio 2010 offers a convenient way for managing the most recently used projects by simply right-clicking each project name in the list. With this action you can pin or remove items from the list itself.

Creating applications

You create .NET applications in Visual Studio 2010 by first creating projects. A project is the place where all the parts composing your application, such as code, libraries, dialogs, pages and resources, reside. An application can be composed of one or more projects. Multiple projects bound together are combined into a Solution. Thus, the first step is creating a new project. You accomplish this by selecting the New|Project command from the File menu. This will show the New Project dialog which looks like this:

Visual Studio 2010 face2

As you can see, there are a number of available project types, grouped by programming language or by typology. As you can see from the above figure, the programming language project types are sub-grouped by technology. Once you have selected the desired project type, just assign a name and click OK. The Visual Studio documentation that ships with the product provides full descriptions for both Windows and Web projects.

In Visual Studio 2010 you can also target different versions of the .NET Framework (as shown in the figure above) or search specific project templates using the Search Installed Templates search box.

Building and debugging applications

You can build and run your executable application by pressing F5. This is common to both Windows and Web applications and will run your application with an instance of the Visual Studio debugger attached. Visual Studio provides a lot of debugging tools available in the Debug menu. For example, you can place breakpoints (also by pressing F9) or check for the value of local variables via the Locals tool window. If you don’t want to run the application under the debugger investigation, simply press Shift+F5.

You can quickly deploy your application using the ClickOnce technology, which you access via the Build|Publish command.

Browsing the documentation

You can access the Visual Studio documentation in different situations by pressing F1. For example you can get general information by pressing F1 anywhere or get specific help for an element in your code by selecting the code element (such as the name of a type) and, again, press F1. In Visual Studio 2010 the help system has been rebuilt completely and now allows you to browse the documentation inside your Web browser. The following figure shows an example:

Browsing the documentation

WPF-BASED CODE EDITOR

Most of the Visual Studio 2010 architecture now relies on Windows Presentation Foundation, the most recent technology from Microsoft for building rich client applications. If you are an existing Visual Studio developer this is something you immediately notice when running the IDE for the first time; it affects a number of areas such as the Start Page and tabbed dialogs or tool windows. The code editor is also built upon WPF which provides some great benefits, including:

  • Better text r endering
  • Code editor zoom by pr essing CTRL + mouse wheel
  • Automatic selection of all occurr ences of a word
  • Tabbed code dialogs can be undocked and tr eated like any other window outside the IDE
  • Improved extensibility: the code editor also takes advantage of MEF (Managed Extensibility Framework) to receive pluggable components. This allows hosting rich content inside the code editor, such as images, videos, WPF controls, comment adornments and so on.
  • Reusability: you can reuse the code editor as a component in your own Visual Studio add-ins.

You interact with the code editor via the IWPFTextView interface which is described in the MSDN Library. The following image shows how the WPF-based code editor looks:

WPF-based code editor

Notice that the zoom percentage is greater than 100%. This was accomplished simply by pressing CTRL + mouse wheel. A good number of code editor extensions are available in the Visual Studio Gallery Web site.

“GENERATE FROM USAGE” TOOL

In its continuous evolution, the Visual Studio environment has committed to offer even more sophisticated tools for helping developers write code. IntelliSense®, syntax highlighting, and auto-completion are just a few examples. It previously lacked the ability to create new objects on the fly. With Visual Studio 2010 you can now create new objects while writing code. This is useful when you realize that you need an object that you did not consider before or that you need to extend an existing object with new members. This functionality is integrated into the code editor and is known as Generate From Usage; it is available for both Visual Basic and C#.

Creating new types on the fly

Let’s start describing Generate From Usage by creating a new Console application. Consider the following situation, in which the code attempts to create an instance of the Contact class that actually does not exist yet and pay attention to the error correction options provided by the IDE:

IDE

Click Generate ‘Class Contact’ and Solution Explorer you will notice the presence of a file named Contact.vb (or .cs in C#) which contains the empty definition of the new class.

Hot Tip

The class declaration gets the default visibility modifier, according to the current programming language, which is Friend for Visual Basic and Internal for C#. You need to change this manually if you want to expose the class outside the assembly.

Now you can populate your class with new members, like in the following figure, where the code attempts to assign a non-inexistent property, but the IDE provides the possibility of generating a property or a field:

IDE2

If you select the first option, Visual Studio will add a property named LastName of type String to the Contact class. Similarly you can add both instances and shared methods on the fly. It is worth mentioning that Visual Studio:

  • generates members of the appropriate type when possible.
  • is able to generate interfaces and methods referring to delegates according to the current scenario. When generating such methods, it is able to add the appropriate signature.

You saw how to create a class, which is the default type, and members with default visibility. But you can do more with Generate From Usage as explained in next subsection.

Creating different kinds of types

There are situations in which you need to create different kinds of objects, such as structures or enumerations. Generate From Usage makes this task easy. For example, you might want to create a new structure. If you type the following line of code:


Dim someData As New CustomData

the IDE marks CustomData as non-existent. From the error correction suggestions popup, simply select Generate New Type. This will prompt you with the Generate New Type dialog shown in the next figure:

Type dialog

Here you can:

  • Provide the new object’s visibility by setting the Access property
  • Decide what kind of object you want to cr eate from the Kind property
  • Add the new member to a dif ferent project in your solution via the Project combo box
  • Create a new code file or add the new object to an existing code file inside the File Name box

Simply click OK when you are done and the new object will be added to your solution according to the specified settings. At this point you can add new members as described in the previous section.

WPF & SILVERLIGHT: DRAG AND DROP DATA-BINDING

Visual Studio 2010 introduces an important feature for data development to both WPF and Silverlight: drag and drop data-binding. This technique has been very popular in the past among Windows Forms developers since it allows creating data forms quickly and easily. In order to make the data development experience easier in modern client technologies, such a technique is now available for WPF and Silverlight. In WPF full support is offered for DataSets and ADO.NET Entity Framework. With full support we intend complete UI and codebehind code generation. Support is also offered for custom business objects or different data sources such as LINQ to SQL or WCF Data Services, but only on the UI side, meaning that you need to write all the data access code from scratch. In Silverlight you don’t have DataSets, so you can use this kind of data-binding with Entity Framework and custom objects.

Hot Tip

The drag and drop data-binding is also available for WPF 3.5 and Silverlight 3 projects.

Creating the data-bound interface

Whatever your data source is, you may open the Data Sources window and then simply drag your desired data item from the window onto the designer surface, as it was done previously in Windows Forms applications. The following figure provides an example based on the Entity Framework as the data source:

figure2

Hot Tip

The Data Sources window in Visual Studio 2010 provides full support for entities exposed by the Entity Framework.

As in older technologies, you can still create grid views or details views and you are allowed to replace the default controls with different ones. You can drag an entire object to create a view or a single object onto an items container control such as the ListBox for creating lists.

Hot Tip

Visual Studio adds controls to the user interface depending on the version of the .NET Framework you are targeting. For example, if you want to create a grid view, Visual Studio uses the DataGrid control in .NET 4 and a ListView control in .NET 3.5.

Dragging and dropping the data is just the first step since you obviously need some code.

A tour of the code

When you use the drag and drop binding, Visual Studio generates some useful code for you. This not only refers to the user interface and controls, but also to querying data. On the XAML side, it first generates the appropriate CollectionViewSource objects acting like “bridges” between data and UI:


<Window.Resources>
	  <CollectionViewSource x:Key=”CategoriesViewSource” d:DesignSo
urce=”{d:DesignInstance my:Category, CreateList=True}” />
	  <CollectionViewSource x:Key=”CategoriesProductsViewSo
urce” Source=”{Binding Path=Products, Source={StaticResource
CategoriesViewSource}}” />
	</Window.Resources>

Next it generates data-bound controls, such as a DataGrid and Label/TextBox couples if considering the previous image (notice the Binding markup extension pointing to the bound property):


<DataGrid AutoGenerateColumns=”False” EnableRowVirtualization=”True”
Height=”128” HorizontalAlignment=”Left” ItemsSource=”{Binding}”
Name=”CategoriesDataGrid” RowDetailsVisibilityMode=”VisibleWhenSelect
ed” VerticalAlignment=”Top” Width=”248”>
	<DataGrid.Columns>
		<DataGridTextColumn x:Name=”CategoryIDColumn”
Binding=”{Binding Path=CategoryID}” Header=”Category ID”
Width=”SizeToHeader” />
		<DataGridTextColumn x:Name=”CategoryNameColumn”
Binding=”{Binding Path=CategoryName}” Header=”Category Name”
Width=”SizeToHeader” />
		<DataGridTextColumn x:Name=”DescriptionColumn”
Binding=”{Binding Path=Description}” Header=”Description”
Width=”SizeToHeader” />
	</DataGrid.Columns>
  </DataGrid>
…
	<Label Content=”Product ID:” Grid.Column=”0” Grid.Row=”0”
HorizontalAlignment=”Left” Margin=”3” VerticalAlignment=”Center” />
	<TextBox Grid.Column=”1” Grid.Row=”0” Height=”23”
HorizontalAlignment=”Left” Margin=”3” Name=”ProductIDTextBox”
Text=”{Binding Path=ProductID, Mode=TwoWay,
ValidatesOnExceptions=true, NotifyOnValidationError=true}”
VerticalAlignment=”Center” Width=”100” />
…

It is worth mentioning that Visual Studio also maps data types to the appropriate controls. A typical example is when you have data of type System.DateTime that is represented via a DatePicker control (available in .NET 4 only). On the managed code side, Visual Studio generates some starting code for querying data. In case you use the Entity Framework as the Data Access Layer, the generated code looks like this (continuing the example from the previous image):


Class MainWindow
	Private Function GetCategoriesQuery(ByVal NorthwindEntities As _
										WpfApplication1.
NorthwindEntities) _
										As System.Data.Objects.
ObjectQuery(Of WpfApplication1.Category)


	Dim CategoriesQuery As System.Data.Objects.ObjectQuery(Of
WpfApplication1.Category) =
		   NorthwindEntities.Categories
		‘Update the query to include Products data in Categories. You
can modify this code as needed.
		CategoriesQuery = CategoriesQuery.Include(“Products”)
		‘Returns an ObjectQuery.
		Return CategoriesQuery
	End Function
	
	Private Sub Window_Loaded(ByVal sender As System.Object,
							  ByVal e As System.Windows.
RoutedEventArgs) _
							  Handles MyBase.Loaded
		Dim NorthwindEntities As WpfApplication1.NorthwindEntities =
			New WpfApplication1.NorthwindEntities()
		‘Load data into Categories. You can modify this code as
needed.
		Dim CategoriesViewSource As System.Windows.Data.
CollectionViewSource =
			CType(Me.FindResource(“CategoriesViewSource”), System.
Windows.Data.CollectionViewSource)
		Dim CategoriesQuery As System.Data.Objects.ObjectQuery(Of
WpfApplication1.Category) =
		  Me.GetCategoriesQuery(NorthwindEntities)
		CategoriesViewSource.Source = CategoriesQuery.
									  Execute(System.Data.Objects.
MergeOption.AppendOnly)
   End Sub
End Class

This will allow loading some data when you run the application. Once you have your starting code, you can write your own queries or extend the auto-generated code with additional features, such as Insert/Update/Delete operations or provide data navigation functionalities.

WPF & SILVERLIGHT: MULTI-TARGETING DESIGNER

In previous versions of Visual Studio the design-time experience for WPF and Silverlight developers did not offer specialized design tools. For WPF developers, the IDE lacked some tooling familiar to Windows Forms developers. Visual Studio 2008 introduced some improvements to the WPF design experience, like the ability to drag controls from the toolbox and drop them onto the designer surface, or the possibility to access event handlers by double-clicking the controls. But no support was available for setting special properties inside the Properties Window (e.g. brushes) so developers needed to manually write the code to set them. For Silverlight developers, things were even worse, in that you had neither drag and drop support nor design time support such as adjusting the application layout, so everything had to be set in code. Although Visual Studio is a developer tool, Microsoft Expression Blend is the tool best suited for deep customization of the user interface. While lots of developers use only Visual Studio to create the user interface for their applications, the need for better VS designer program was paramount. This is what happened with the release of Visual Studio 2010. In the next section you get an overview of the new and improved features, while later you will get information about how this targets multiple .NET Framework versions.

Improved experience

With Visual Studio 2010, both the WPF and Silverlight esigners now provide a full design-time experience and, most importantly, both technologies share the same tools. This means that you have the same instrumentation available for both WPF and Silverlight projects. You now have full support for dragging and dropping controls from the toolbox, for rearranging controls on the controls’ surface and you can also set complex properties within the Properties Window. The following figure represents such a description with regard to a WPF project:

figure3

If you try to do this inside a Silverlight project, you get exactly the same result and tools available. Notice how you now have a new color picker editor available for properties of type brush, which allows specifying the brush color, its type (e.g. a gradient or an image) and manually entering the color code. Prior to Visual Studio 2010 this had to be performed by writing pure XAML code. There are a number of other improvements in this area that are listed below.

Setting grid columns and rows

You can easily set rows and columns within a Grid control by selecting the RowDefinitions and ColumnDefinitions properties in the Property Window and then by taking advantage of a new dialog that looks like the following figure:

figure4

You simply click Add, then set properties for each row or column, such as the Height or Width.

Searching for a property

The Properties Window has been enhanced with a number of new features. You got a taste of this in the previous section when discussing how to set properties of type Brush. Another interesting addition is that you can now search for a specified property by writing its name in the search box at the top of the window. Also, you do not need to write the entire property name since Visual Studio filters the property list as you type characters inside the search box:

figure5

This way you can easily reach and set the properties you want to assign.

Hot Tip

The search field is also available in the Events tab of the Properties Window.
Setting controls’ fonts

In Visual Studio 2010 you can now easily set font properties to controls supporting fonts via an integrated tool inside the Properties Window.

Hot Tip

This is available only when you enable the Categorized view.

For instance, you can select the font from a combo box and then set text alignment, size and weight all together, as shown in the following figure:

figure6
Visually setting data-binding and resources

The Properties Window also improves the way you assign data-bound properties or resources. You select the data-bound property for your control and then you can easily use the Binding popup as follows:

  1. Select your data source. This can be the DataContext—another control or a resource as shown in the followingfigure:

    figure7

  2. Switch to the Path tab in order to select the property you wish to be bound;
  3. Select any value converter you want to apply via the Converter tab; and
  4. Finally go to the Options tab and apply any other additional options. This is really impressive in that you have a great number of available properties such as data error validation or triggering property changes.

You can apply resources similarly. For example, if you defined a style for a button and then you want to apply such a style, just right click the Style property in the Properties Window and select Apply Resource. This will provide a useful popup where you will be able to pick both default and local resources, as demonstrated in the following figure:

figure8

You can also choose between static and dynamic resources and you are offered a preview of the result you get once the resource is applied.

Multiple .NET Framework versions targeted

Visual Studio 2010 ships with integrated support for Silverlight 3 but it also supports Silverlight 4 when you install the appropriate developer tools. The good news is that all the stuff you have seen so far, including the drag and drop databinding, is available for both .NET Framework 3.5 SP 1 and 4.0 in Visual Studio 2010. This is what is usually referred to as multi-targeting, when talking about the designer. This basically means that you can create applications for WPF 3.5, WPF 4, Silverlight 3 and 4 taking advantage of all the new designer features independent of the technology or its version. If you want to check this out by yourself, simply create a new WPF or Silverlight project and in the New Project dialog select the .NET Framework 3.5 as the target Framework. You will notice no difference in the designer if compared to .NET 4.

COMMON SHORTCUTS AND TIPS

Visual Studio 2010 offers both shortcuts for quick access to common tools and instruments that you may find really useful. This section provides information on both topics.

Common shortcuts

  • Start the application in debugging mode by pr essing F5 or without attaching the debugger by pressing Shift+F5
  • Save all files in your solution by pr essing Ctrl+Shift+S
  • Build your solution by pr essing Ctrl+Shift+B
  • Run your application without the debugger by pr essing Shift+F5
  • Show the toolbox by pr essing Ctrl+Alt+T
  • Navigate to a specific member definition by pr essing Ctrl+
  • Comment multiple line of codes by pr essing CTRL+K and CTRL+C in sequence or uncomment lines by pressing CTRL+K and CTRL+U in sequence
  • Show up the Properties window by pressing F4
  • Select code blocks by pr essing ALT + mouse
  • Place a breakpoint by pressing F9 on the specified line of code

Common tips

  • Download and manage Visual Studio extensions via the Tools|Extension Manager tool
  • Add menu items for running external tools via the Tools|External Tools command
  • Add IntelliSense code snippets within the code editor by pr essing Ctrl+K or right-click and then Insert Snippet
  • Export project or item templates in or der to create reusable templates with File|Export template
  • Find all references of a type or member by performing right click inside on a member inside the code editor and then selecting Find All References

About The Authors

Photo of author Alessandro Del Sole

Alessandro Del Sole

Alessandro Del Sole, Microsoft Most Valuable Professional (MVP) for Visual Basic since 2008, is well known throughout the global Visual Basic community. The author of four books about .NET development with Visual Studio, he is a community leader on the Italian Visual Basic Tips and Tricks (www.visual-basic.it) web site that serves more than 42,500 VB developers. He is also a frequent contributor to the MSDN Visual Basic Developer Center (msdn.com/vbasic). He enjoys writing articles on .NET development, writing blog posts on both his Italian and English blogs, and producing instructional videos. You can find him online in forums or newsgroups.

Recommended Book

Photo of Book: Visual Basic 2010

This book’s broad coverage includes advanced features such as generics and collections; a thorough introduction to the Visual Studio 2010 IDE and Visual Studio Team System; a full section on data access with ADO.NET and LINQ; practical overviews of WPF and WCF; coverage of web and cloud development with Silverlight and Azure; and advanced topics such as multithreading, testing, and deployment.

Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Optimize Your db4o Techniques in 6 Pages!

Whether you're advanced in db40 and want increased efficiency or you want to learn basic operations, you'll find what you're looking for in this free, 6-page DZone Refcard. Click here to download the PDF. 

0 replies - 6250 views - 05/11/09 by Lyndsey Clevesy in Announcements

Getting Started with db4o

Persisting .NET Object Data

By Stefan Edlich and Eric Falsken

7,112 Downloads · Refcard 53 of 151 (see them all)

Download
FREE PDF


The Essential db4o Cheat Sheet

db4o is an open source object database that allows you to quickly store and retrieve your .NET application data. It was introduced in 2000 with a focus on performance, compactness, zero administration, simplicity, and (most important of all) native object persistence. Developers were finally able to combine the power of a full database engine with plain undecorated objects. This DZone Refcard walks you through db4os basic operations, its various query types and techniques for optimal data access performance.
HTML Preview
Getting Started with db4o: Persisting .NET Object Data

Getting Started with db4o: Persisting .NET Object Data

By Stefan Edlich and Eric Falsken

About db4o and object databases

db4o is the open source object database that enables developers to store and retrieve any application object with one line of code.

The Object Database (ODB) arrived in the software industry with the advent of object oriented languages. The ODB is primarily used as an application specific database in either extreme scale systems or embedded systems where typical DBA activities are automated.

If you are familiar with object-relational mapping (ORM) tools, then you are already an object database expert because many of the APIs and query languages are comparable. You will even find db4o both familiar and yet simpler to use as ORM tools as there is no requirement for XML mapping, annotations or IDs.

db4o was introduced in 2000 with a focus on performance, compactness, zero administration, simplicity and (the most important of all) native object persistence. Developers were finally able to combine the power of a full database engine with plain undecorated objects.

Getting Started

Note

The current version of db4o at the time of this writing is version 7.8.

db4o comes distributed as a few native .NET assemblies. Only Db4objects.Db4o.dll is required for basic db4o operation. Use the Visual Studio "Add Reference" command to add the necessary assemblies. Then use the Solution Explorer to locate the new reference, right-click and open the properties window to ensure that "Copy Local" is set to true for each db4o assembly. This will copy the necessary db4o libraries to your application's bin folder automatically when compiling your project.

Note

Running db4o from the GAC is not supported.

Required Environment

Developing with db4o requires only the .NET SDK version 2.0 or better. (3.5 suggested)

Visual Studio 2008 or better is suggested for the best experience, but any .NET IDE will do. Microsoft Visual Studio 2008 Express editions are available for free download from Microsoft.

Running db4o requires only the .NET Framework to be installed. Some hosting environments, such as shared website hosting providers, do not allow code to run with full trust. When the environment is configured to run with reduced trust, all basic database operations require at least ReflectPermission (MemberAccess and ReflectionEmit) for the classes and types being persisted.

Required Libraries per Database Feature

Depending on the features your application requires, reference and distribute these assemblies when you distribute your application:

(Required for all Installations) Db4objects.Db4o.dll
Client-Server Db4objects.Db4o.CS.dll
LINQ Db4objects.Db4o.Linq.dll
Native Queries Db4objects.Db4o.NativeQueries.dll
Transparent Activation Db4objects.Db4o.Instrumentation.dll

Note

Run-time Optimization of LINQ, NQ, and TA requires the Mono.Cecil.dll and Cecil.FlowAnalysis.dll assemblies. Optimization can also be done at buildtime using Db4oTool.exe. (see db4o Reference Documentation for usage)

ObjectManager for Debugging

Included in the db4o distribution you'll find the installer for ObjectManager Enterprise (OME) which, once installed, will integrate into your Visual Studio Environment and allow you to open and inspect, query, and edit (value types only ) object instances stored in your database file.

Basic Database Operations

A Complete Example


IObjectContainer db =
Db4oFactory.OpenFile([filename]), ([config]);
try{
	// Store a few Person objects
	db.Store(new Person("Petra"));
	db.Store(new Person("Gallad"));
	// Retrieve the Person
	var results = db.Query<Person>(x => x.Name == "Petra");
	Person p = result.First();
	// Update the Person
	p.Name = "Peter";
	db.Store(p);
	// Delete the person
	db.Delete(p);
	// Don't forget to commit!
	db.Commit();
}
catch{
	db.Rollback();
}
finally{
	// Close the db cleanly
	db.Close();
}

Create or Open a Database File


IObjectContainer container = Db4oFactory.OpenFile([filename]);

While a db4o database file is open, it is locked and cannot be accessed by another application at the same time.

Hot Tip

It's important to know that db4o works best if you open the database file when you start working with data, and close the db when all posible operations are completed.

In traditional relational databases, it's common to open a connection, get/update data, close connection, and then perform your operation. Because db4o uses the native object (or referential) identity, it's better to open the database or connection when your application begins, do all your work, then close the database when your program is shutting down. You'll see why when we get to updating an object with our changes.

Starting a db4o Server

By default, the db4o server runs in-process within your application. To start a db4o server, place this code into your application:


IObjectServer server =
	Db4oFactory.OpenServer([filename], [port]);
server.GrantAccess([user], [password]);

To shut down the server:


server.Close();

The port parameter specifies the network port number. Acceptable values are any number above 1024 which are not already in use.

Hot Tip

Using Port 0 for your server creates an "Embedded" server which will not be available remotely. This is useful for multi-threaded operations or web-server style environments where you wish to handle parallel operations in a single process.

The GrantAccess() method must be called for each username/ password combination. It is not required at all for embedded servers.

Connecting to a db4o Server

After starting a db4o server instance, use either of the commands below to open a db4o client connection:


// In-Process mode (embedded server)
IObjectContainer client = server.OpenClient();
// Client/Server mode (remote server)
IObjectContainer client =
	Db4oFactory.OpenClient([serverAddress], [port], [user],
[password]);

To close the client connection to the server:


client.Close();

Storing an Object


db.Store(anObject);
db.Commit()

Just one line of code is all it takes. All of an object's properties and child objects will be stored.

Updating an Object


db.Store(anObject);
db.Commit();

Looks familiar? You can use the same Store(object) command to update an object. One difference, however, is that db4o will (for performance reasons) not automatically check child objects for changes.

Hot Tip

By default, db4o will NOT descend into child objects. Store() must be called for each modified object unless you change the default UpdateDepth (see the UpdateDepth parameter in the Configuration section, below) or configure cascading update for the persisted class.

There is one more thing to be aware of: db4o uses an object's native identity (referential identity) to identify an object and map it to the stored instance of the object. This means that there is only ever 1 instance of an object in memory for each stored instance of the object. (per ObjectContainer or connection) This is important when dealing with class instances that may come from ASP.NET ViewState, Web Services, Interop, or any other serialized source of object data.

Hot Tip

Avoid Confusion: Always make sure that the object you are trying to update or delete was previously stored or retrieved in the database. Calling Store() with 2 User objects both with an ID of "jack" will result in 2 separate instances. However, if you retrieve the user, and modify the first instance, then store it again, you will have only 1 updated instance in the database.

Deleting an Object


db.Delete(anObject);
db.Commit();

You didn't think it was any harder than that, did you? Like updates, db4o will not automatically delete child objects unless you configure cascading deletes for your object will remain in memory until the objects are refreshed or garbage collected.

Database Transactions

Whenever you start making changes to your database (using the Store() and Delete() commands) you are automatically in an open transaction. To close the transaction, use the Commit() method:


db.Commit();

Your changes will be permanently saved. If you wish to cancel or roll back any uncommitted changes, use the Rollback() method:


db.Rollback();

Hot Tip

Useful for beginners: Rollback only undoes uncommitted changes in the database. It will not undo changes to any currently loaded objects. So, when you call Rollback() you will not see any difference to your objects. If concerned about consistency, use the Refresh(object) command to cause the objects to be refreshed with stored database values.

Closing a database cleanly will automatically call Commit() for you, so any uncommitted transactions are committed automatically.

If the database is not closed cleanly, or if the application crashes at any time and uncommitted (or incomplete) transactions are discarded.

Queries

Query by Example (QBE)

QBE lets you pass db4o an example object. db4o will search and return all objects which match the object you specify. To do this, db4o will reflect all of the properties of the object and assemble all non-default property values into a single query expression.

Hot Tip

Useful for beginners: QBE queries are not able to use advanced boolean constraints (AND, OR, NOT) and cannot constrain on default values (zero, empty strings, null). QBE queries also cannot query for value ranges (greater than, less than) or stringbased expressions (contains, starts with). So QBE can be used only to retrieve exact-value matches.

Here's an example QBE query that will contain all Customer objects with "Lee" as their Surname:


Customer proto = new Customer ()
	{Surname = "Lee"};
IObjectSet result = db.Get(proto);

Native Queries (NQ)

Like any query language, Native Queries are capable of expressing complex parameterized constraints, however NQ also have the benefit of being 100% compiler checked and can be refactored using common code refactoring tools. NQ can do all this because they are expressed as native .NET code rather than as strings (like SQL statements)

Hot Tip

Developers are encouraged to use the Native Query interfaces when working with db4o.


// NQ Lambda Expression (.NET 3.5 syntax)
var result = db.Query<type>(
	o => [boolean expression]);
// NQ Anonymous Method (.NET 2.0 syntax)
IList<type> result = db.Query<type>(
	delegate(type o){
		return [boolean expression];
	});

Native Query Examples


// Query all instances of a type.
IList<User> result = db.Query<User>();
// Query Users by Name.
IList<User> result = db.Query<User>(u => u.Name == "Joe");
// Query Users with at least 10 orders
IList<User> result = db.Query<user>(u => u.Orders.Count >= 10);
// Complex Query
IList<User> result = db.Query<User>(
	u => u.Name.StartsWith("Bob")
		&& (u.Country == "Canada" | |
			u.Country == "USA" );

Sorting Native Queries

Native Query results can be sorted by using an IComparer or a comparison delegate. Here is the query syntax:


IList<User> result = db.Query<User>([predicate],[comparer]);

And here's an example:


// All users with "Smith" in their name
// sorted by name
IList<User> result = db.Query<User>(
	u => u.Name.Contains("Smith"),
	(u1, u2) => u1.Name.CompareTo(u2.Name)
	);

LINQ Queries

LINQ was introduced by Microsoft .NET Framework version 3.5 (also called C# 3.0) in November 2007. To enable the use of LINQ queries, you'll need to add a reference to the Db4objects.Db4o.LINQ.dll assembly and import the Db4objects.Db4o.LINQ namespace. (with a using statement)

A full description of LINQ syntax will not fit in this document. You can find the URL to Microsoft's LINQ reference in the Resources section at the end.

LINQ Queries have all the benefit of compiler checking and automated code refactorability that Native Queries have, but are expressed in syntax more familiar to SQL developers. Here's one quick and easy example that gets all of the Customers with "Smith" in their name, and sorts the results by name.


var results =
	from Customer c in db
	where c.Name.Contains("Smith")
	orderby c.Name descending
	select c;

With LINQ queries you can:

  • Use ORDERBY to sort the results.
  • Use JOIN expressions to filter one dataset based on the contents of another.
  • Use Aggregate Expressions to get the sum, min, max, or average values and GROUPBY to group the results.
  • Use Anonymous Types to get back only the fields you wish.
  • Use an expression to process, filter, or format the data as it is returned from the database.
  • Use LINQ extensions like First(), Any(), All(), Single(), and ElementAt() to access or constrain the result set.

SODA Queries

SODA query expressions are a standard that was present in all but the earliest versions of db4o. Using combinations of SODA query and constraint keywords, you can build up what is called a query "graph". A graph is a network of objects which represent a segment of data.

Hot Tip

Before using SODA Queries, you must import the Db4objects.Db4o.Query Namespace. (with a using statement)

In this example, we're querying for all of the customers named "Smith".


IQuery query = db.Query();
query.Constrain(typeof(Customer));
query.Descend("Name").Constrain("Smith");
IObjectSet results = query.Execute();

And in this more complicated example, we'll use a compound constraint:


IQuery query = db.Query();
query.Constrain(typof(Customer));
IConstraint c1 = query
	.Descend("Name")
	.Constrain("Smith");
IConstraint c2 = query
	.Descend("Country")
	.Constrain("USA");
c1.And(c2);
IObjectSet results = query.Execute();

Notice how each of the calls to Constrain() will return an IConstraint? You can keep references to those constraints and then use constraint keywords like And(), Or(), and Not() to relate the constraints together, as we did at the end of that example.

Note that the Descend() method returns an IQuery too. So you could Descend() into an object, and then Execute() at a deeper level to return only the matching child objects, like in this example:


IQuery q1 = db.Query();
q1.Constrain(typeof(Customer)); // start with Customers
q1.Descend("Name")
	.Constrain("Smith");
IQuery q2 = q1.Descend("Orders"); // constrain Orders
// Order totals greater than $100.
q2.Descend("Total")
	.Constrain(100)
	.Greater();
// Since we want to return Orders, execute q2 instead of q1
IObjectSet results = q2.Execute();

SODA Query Interfaces
IQuery Provides the location for constraining or selecting.
IConstraint Constrains the query results with the current IQuery node
SODA Query Keywords
Descend Move from one node to another
OrderAscending Order the result ascending according to the current node.
OrderDescending Order the result descending according to the current node.
Execute Execute the query graph and return the objects at the current node.
SODA Constraint Keywords
And(IConstraint) Performs an AND (&&) comparison between 2 constraints.
Contains() For collection nodes, matches will contain the specified value. For string values, behaves as Like().
EndsWith(bool) For strings, matches will end with the supplied value. Optionally case sensitive.
Equal() Combine with Smaller and Greater to include the specified value. (e.g. >= or <=)
Greater() Matching values will be greater than or larger than the supplied value.
Identity() Matching values will be the same object instance as the supplied value. (referential equality).
Like() For strings, matching values will contain the supplied value anywhere within the match.
Not() Performs a negation comparison. Matching values will NOT equal the supplied value. Added to any other constraint keyword, this will reverse the result.
Or(IConstraint) Performs an OR (||) comparison between 2 constraints.
Smaller() Matching values will be smaller or less than the specified value.
StartsWith(bool) For strings, matches will start with the supplied value. Optionally case sensitive.

Query Performance

  • If you are experiencing poor NQ performance, then you probably forgot to either enable run-time optimization of Native Queries (by including a reference to the assemblies listed in the "Required Libraries" section) or running Db4oTool.exe on your compiled assembly.
  • You can change the Query EvaluationMode configuration to control how and when a query should be evaluated. (See below in the Configuration section)
  • You can index fields to aid query evaluation. Indexing fields causes db4o to store the values of the field in a separate index lookup table in the db. As a result, when evaluating the query, db4o does not have to seek through all of the object data to resolve the query results. (See the Class-Specific Configuration Options below)

Hot Tip

Indexing fields is a great way to increase query performance, but each index table is one more place where a field's value is stored. Too many indexed fields can cause poor insert performance. The application developer should tune the number of indexes with the desired Query and Insert performance.

Dealing with object activation

When dealing with objects that may have relations to other objects quite deep (think of the path of data from Customer to Order to OrderItem to Product with relations to Address objects for billing and shipping and then PO and payment transactions) it would be quite expensive to have to pull all of that data into memory from the DB if all you wanted was the Customer object. Modern object databases use the idea of activation to control the depth to which objects are instantiated and populated when retrieved from the database.

Hot Tip

The default ActivationDepth in db4o is 5. A properly tuned activation depth is the best way to optimize retrieval of data from a db4o database. (See ActivationDepth in the Configuration section for more ideas)

With an ActivationDepth of 5, objects will be populated up to 5 levels deep. Properties of the 5th descendant object will have their values left as default or null.

If you encounter an object that is not yet activated, you can pass it to db4o for manual (late) activation:


db.Activate([unactivatedObject], [depth]);

Objects can also be manually de-activated:


db.Deactivate([activatedObject], [depth]);

Fine-grained activation depth can be configured per class. (see ActivationDepth in the Configuration section below) Activation can also be managed transparently using Transparent Activation. (see below)

Configuration

For all but the simplest db4o use cases, you'll probably want to specify one or more configuration settings when opening your db4o database:


IConfiguration config =
Db4oFactory.NewConfiguration();
// Set configuration properties here
IObjectContainer db= Db4oFactory.OpenFile([config], [filename]);

The IConfiguration object must be passed in the call to open the db4o file, server, or client connection.

Query EvaluationMode

This property controls when and how much of a query is executed.


IConfiguration config =
	Db4oFactory.NewConfiguration();
config.Queries().EvaluationMode([mode]);

Query EvaluationMode Values
Immediate (Best when queries must be deterministic or execute as quickly as possible.) A list of object ID matches is generated completely when the query is executed and held in memory
Lazy (Best for limited resource environments.) An iterator is created against the best index found. Accessing the results will simply iterate through the index until no further matches are found. The result set can be influenced by subsequent transactions in the current context or by other clients causing possible concurrency errors. Almost no memory is needed to hold the result set. Accessing the Count or Length properties will cause full evaluation.
Snapshot (Best for servers and concurrent environments.) Same as Lazy, however the iterator is created against a snapshot of the index. This avoids possible concurrency issues of Lazy evaluation. Since the index snapshot is held in memory, the memory required varies greatly depending on what is being queried.
(All Values) Object data is activated as the users accesses each object in the result set. The currently stored state is used when activating field data, not the object state at the time of query execution. The above values affect only the state of field indexes and when the evaluation is performed. Regardless of when it is run, query constraints against non-indexed data are always performed on the currently stored object state.

Global UpdateDepth

We said earlier that when calling Store() to update an object graph, that db4o will not (by default) descend into child objects to detect changes to the graph. If you know that you'll be often changing child properties, or when changing a parent object often results in changes to child objects, then you may want to change the UpdateDepth.


IConfiguration config =
Db4oFactory.NewConfiguration();
config.UpdateDepth([depth]);

The default value 1 means db4o will not descend into child objects when updating stored object instances.

Setting the UpdateDepth to int.MaxValue will cause db4o to descend as deeply as possible to look for changes.

Setting the UpdateDepth to 0 will prevent any changes from being saved to the database.

Hot Tip

Setting the UpdateDepth too aggressively can cause poor db4o update performance. Higher values should be used to debug UpdateDepth-related issues only.

Global ActivationDepth

As explained in the section on Dealing with Object Activation, the ActivationDepth controls how much data is loaded when an object is retrieved from the database.


Iconfiguration config =
	Db4oFactory.NewConfiguration();
config.ActivationDepth([depth]);

The default value of 5 is a good balance for most applications, but developers should balance this against the weight of their classes and their access patterns.

Setting the ActivationDepth to int.MaxValue will cause all related objects to be instantiated as deeply as possible, restoring the entire object graph to memory.

Setting the ActivationDepth to 0 will cause nothing to be activated. The object returned will have none of its values loaded. You can then call the Activate(object, depth) method to manually activate the object as described above.

Hot Tip

Setting the ActivationDepth too aggressively can cause poor db4o query performance and high memory usage. Higher values should be used to debug ActivationDepth-related issues only.

Transparent Activation (TA)

The Db4oTool.exe tool found in the distribution bin folder can be used to instrument your classes to perform activation on-demand transparently as you navigate between object references. When accessing a child object, db4o can automatically activate the child object from the database if it is not yet already activated.

Transparent Activation must be enabled in the configuration when opening a db4o database and your compiled assembly must be instrumented by Db4oTool.exe as part of the build (as an MSBuild task) or post-build by running the tool manually.

Using Db4oTool.exe is not complicated, but is beyond the scope of this DZone Refcard. You can find complete instructions in the db4o reference documentation.

Cascading Operations, call backs and class-specific configuration

The global UpdateDepth and ActivationDepth configurations are good for general testing. But oftentimes, you will want to configure specific behaviors per-class-type, or per-field. (e.g. field indexing)


IConfiguration config =
Db4oFactory.NewConfiguration();
//Get the class-specific canfiguration
IObjectClass objectClassConfig =
	config.ObjectClass([typeName]);
//Get a field-specific configuration
IObjectField objectFieldConfig =
	objectClassConfig.ObjectField([fieldName]);
// Usually shortened to one line. e.g. config.
objectClass(typeof(Customer)).ObjectField ("Name").Indexed(true);

A full description of Class-specific and field-specific configuration settings can be found in the db4o reference documentation.

db4o also allows you to specify event handlers when an object is retrieved, activated, deleted, etc. These events can be handled globally using the EventRegistryFactory or individually within your classes using any of the IObjectCallbacks methods like objectOnActivate, objectOnDelete, and objectOnNew. These handlers are great for selectively activating, refreshing, or cascading db operations.

Lastly, setting the Transient attribute on your class's field members will prevent db4o from storing the values of those fields. When read from the DB, these members will always be left at their default (null) values, useful for remote connections, non- native data (interop) and temporary state.

db4o Resources

db4o Homepage http://www.db4o.com
db4o Community Forum http://developer.db4o.com
db4o Downloads http://download.db4o.com
db4o Bug Tracker http://tracker.db4o.com
db4o Source Code Repository https://source.db4o.com/db4o/
db4o Reference Documentation http://docs.db4o.com
db4o Community Projects http://projects.db4o.com
LINQ General Programming Guide http://msdn.microsoft.com/en-us/library/bb397912.aspx
Versant Corporation http://www.versant.com
Versant Corporation supports the db4o team and open source community. Versant is a public company (NASDAQ:VSNT) and develops the Versant Object Database technology for users of .NET, C++ and Java who require a database capable of supporting extreme scale systems.
Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.