Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] - نسخه متنی

Andy Wigley; Peter Roxburgh

نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
افزودن یادداشت
افزودن یادداشت جدید






Building Data Components with Visual Studio .NET

Visual Studio .NET provides a number of useful tools that can greatly assist developers who work with data. The Database Designer allows you to interact with database objects using database diagrams, through which you can create database tables, rows, columns, keys, indexes, relationships, and constraints. The Table Designer is a visual tool that allows you to design a single database table. For details about these tools, consult the Visual Studio .NET SDK documentation. In this section, we'll look at two other useful tools in Visual Studio .NET, the Server Explorer and the Component Designer.


Using Server Explorer


Even if you don't consider yourself a database designer, Visual Studio .NET offers a number of useful features that allow you to view databases and create data components. One such feature is Server Explorer. Server Explorer allows you to navigate and access data sources that are available to your applications.

You can open Server Explorer by clicking the Server Explorer tab below the Toolbox tab in Visual Studio .NET. Alternatively, you can open the View menu and then click Server Explorer.

Using Server Explorer, you can perform the following tasks:



Open data connections to SQL servers and other databases



Connect to SQL servers and display their databases



Connect to systems on your network and display their system services, including event logs, message queues, performance counters, system services, and SQL databases



View information about available XML Web services and the methods and schemas they make available



For example, if you want to check the fields containing the names and characteristics of the authors table that we used in the previous section's examples, click Server Explorer and navigate to the authors table in the pubs database within SQL Server. Figure 11-4 shows what you'll see.


Figure 11-4: Using Server Explorer to examine database contents


Creating Data Components


Simple applications can access the database directly, as shown in the example in the previous section. However, it's often a good idea to adopt a two-tier or an n-tier model. In both these models, the classes that handle the user interface don't directly handle data; instead, they call components that perform data manipulation on their behalf. In an n-tier model, the user interface classes call components that enforce the business logic or business rules. These middle-tier components call other components that are responsible for fetching and updating data. In this architecture, a DataSet is the ideal object for transferring data between components because it's completely detached from the database. However, a DataSet object still knows about the relationships and constraints that apply to the database, and it enforces them when it is updated.

Visual Studio .NET offers a Component Designer that works with Server Explorer, making it easy to create data components. To demonstrate how to use these tools, you'll update the DataUpdateExample example from Listing 11-7 using a data component instead of embedded data handling logic.

First create a new project of type Visual C# Class Library and name it AuthorsDataComponent. This creates a project that will compile into an assembly, initially containing a class file named Class1.cs. Right-click this file in Solution Explorer, and click Delete. You don't need this file because you'll create a new class module using the Component Designer.

Next right-click the project file in Solution Explorer, click Add on the context menu, and then click Add Component. In the Add New Item window, click Component Class, enter the name AuthsComponent.cs, and click Open. Visual Studio .NET adds the AuthsComponent.cs file to your project and opens it in Design view. Now click Server Explorer, and navigate to the authors table in the pubs database. Drag the authors table from Server Explorer onto the AuthsComponent.cs Design view, as Figure 11-5 shows. This creates a SqlConnection object and a SqlDataAdapter object within the component class, both of which you'll see represented in the Design view. The code for the component class automatically sets up these objects with the appropriate connection string and the correct SqlCommand objects for selecting, deleting, inserting, and updating the authors table.


Figure 11-5: Dragging a database table from Server Explorer to the Component Designer to automatically set up SqlConnection and SqlDataAdapter objects

This component will communicate with other classes by sending and receiving DataSet objects. The Component Designer allows you to generate a DataSet object for the table you've selected. Click the Data menu in Visual Studio .NET, and then click Generate Dataset. In the Generate Dataset window, click New and enter the name AuthsDataSet, as shown in Figure 11-6. Verify that you've checked the authors table to include it in the DataSet, and check the "Add this dataset to the designer" check box. When you click OK, the runtime creates an XML schema file for the DataSet, named AuthsDataSet.xsd, and adds it to your project. The application then creates an instance of this new object, named authsDataSet1, and adds it to the Design view.


Figure 11-6: Generating the Typed DataSet in your component

As it stands, the data component contains all the low-level plumbing required to manipulate the authors table. If you right-click the Design view of the Component Designer and select View Code, you'll see that the runtime has created a class. If you then scroll down and click the plus sign (+) next to the code block labeled Component Designer Generated Code, you'll see all the code needed to connect to the pubs database and manipulate the authors table data. (Be sure that you don't alter any code in this region!) Aside from containing all this generated code, this component currently does nothing. Thus, you must add methods to populate the dataset and make it available externally.

Now add a public property to the class that fills the authsDataSet1 private class member and returns the dataset to the caller, as shown here:

/// <summary>
/// Returns a dataset of all authors in the authors table of the pubs database
/// </summary>
public AuthsDataSet AllAuthors
{
get
{
// Update class member dataset.
this.sqlDataAdapter1.Fill(this.authsDataSet, "authors");
return this.authsDataSet1;
}
}

The Fill method of the SqlDataAdapter automatically opens a connection to the database, reads the data into the DataSet object, then closes the connection.

This component should also implement a method to update the database with any changes to the data. The code that the Component Designer has generated makes this update very easy to implement. The Component Designer has set up the SqlDataAdapter object with the appropriate SqlCommand objects to insert, update, and delete rows in the authors table. When you call the Update method of the SqlDataAdapter object, passing it a DataSet object that contains changes, the runtime applies the changes to the database for each row in the DataSet that you've added, updated, or deleted using the appropriate SqlCommand. Consequently, the code that you need to add in order to implement a public method to update the database is quite simple:

/// <summary>
/// Take a DataSet, including changes, and apply it to the database.
/// </summary>
public bool UpdateAuths(AuthsDataSet DataChanges)
{
bool boolRetval;
try
{
this.sqlDataAdapter1.Update(DataChanges, "authors");
boolRetval = true;
}
catch(Exception)
{
boolRetval = false;
}
return boolRetval;
}

Now build your component. Creating a data component that offers basic functionality is that simple. However, a real application would undoubtedly require more complex error-handling code.


Using a Data Component in a Web Application


When you remove all the data-handling code from the component, the main application class becomes much cleaner and can focus on the logic required to drive the user interface.

To prepare a component for use in a Web application, open the DataUpdateExample project you used in the preceding example or use the Copy Project feature to make a copy, naming it DataComponentExample.

To use the data component, you must add a reference to it in your project. From the Project menu, click Add Reference. You can select the .NET assemblies or COM objects that your application uses from within the Add Reference window (shown in Figure 11-7). To add a reference to a custom component, click the Browse button and navigate to the assembly that the runtime built when you compiled your data component. Click the My Projects button, and then open the AuthorsDataComponent project folder. The AuthorsDataComponent.dll assembly resides in the /bin/debug directory. Click this assembly to select it, and then click OK.


Figure 11-7: The Add Reference window

Now add a declaration for the AuthorsDataComponent namespace at the top of the DataComponentExample.aspx.cs code-behind module so that you don't have to enter the fully qualified name of the component every time you use it. Here's the declaration:

using MSPress.Mob.Web.AuthorsDataComponent;

Next create the data component as a private member of the class. This application actually instantiates the object in the Page_Load method each time you create the class. This instantiation occurs when the application first starts and each time the client posts back to the server. The Page_Load method no longer needs to open a connection to the database as before because the component handles this. Here's how the syntax looks:

private AuthsComponent myDataComp;
private void Page_Load(object sender, System.EventArgs e)
{
// Create the data component each time the application
// returns to the server.
myDataComp = new AuthsComponent();
if (!IsPostBack)
BindList();
}

The BindList method has scarcely changed, apart from fetching the dataset to which the ObjectList control binds from the component and storing the DataSet in the Session object (an improvement over the method's previous incarnation). A Session object is used to store data across different HTTP request/response interactions; you'll learn more about the Session object in Chapter 12. BindList stores the DataSet in the Session object as a convenience to the SaveChanges method, which also requires access to the DataSet when it handles data changes later on in this application, during the processing of a later postback from the client. Let's take a look at the code:

public void BindList()
{
// Use the DataComponent to fetch a dataset.
AuthsDataSet ds = myDataComp.AllAuthors;
ObjectList1.DataSource = ds.Tables["authors"].DefaultView;
ObjectList1.LabelField = "au_lname";
ObjectList1.AutoGenerateFields = true;
ObjectList1.DataBind();
// The field names of au_id, au_lname, and au_fname do not provide
// good titles, so change them in the AllFields collection.
ObjectList1.AllFields[ObjectList1.AllFields.IndexOf("au_id")].Title
= "Author ID";
ObjectList1.AllFields[ObjectList1.AllFields.IndexOf("au_fname")].Title
= "First Name";
ObjectList1.AllFields[ObjectList1.AllFields.IndexOf("au_lname")].Title
= "Last Name";
// Store the DataSource in a session variable so that
// it can persist across multiple postbacks.
Session["MyDataSet"] = ds;
}

The purpose of the SaveChanges method is to update the DataSet with the changes that the user makes and to pass the revised DataSet back to the data component. The data component will then apply the changes retrieved from the dataset to the original data in the database. With the SaveChanges method, the real utility of the AuthsDataSet class generated by the Component Designer comes to light. The AuthsDataSet class that the Component Designer creates is derived from DataSet. The AuthsDataSet class offers methods and properties tailored to the manipulation of data retrieved from the authors table in the database. These methods and properties make the developer's job much easier. For example, the authors property of AuthsDataSet contains the authorsDataTable object, which has a FindByau_id method that searches for a specific authorsRow object using the primary key value. The authorsRow object contains each of the individual fields as properties.

Figure 11-8 shows the AuthsDataSet class structure as seen in the Visual Studio .NET Object Viewer.


Figure 11-8: The structure of the AuthsDataSet class, which contains the authorsRow object, which in turn shows all the individual fields as properties

Using this component, the logic to update the DataSet and send it to the data component becomes quite simple:

private void SaveChanges()
{
// Retrieve the dataset from the Session object.
AuthsDataSet ds = (AuthsDataSet)Session["MyDataSet"];
// Find the row and make changes.
AuthsDataSet.authorsRow rowToChange =
ds.authors.FindByau_id(ObjectList1.Selection["au_id"]);
rowToChange.au_fname = TextBox1.Text;
rowToChange.au_lname = TextBox2.Text;
// Call the UpdateAuths method of data component.
// Pass it the dataset so that it can update the database.
if (myDataComp.UpdateAuths(ds))
Label3.Text = "Record Updated";
else
Label3.Text = "ERROR: Could not update record";
Label3.Visible = true;
Command1.Visible = false;
Command2.Visible = true;
Command2.Text = "Back";
}

The application saves the AuthsDataSet object instance that we used to bind the ObjectList control in the BindList method's Session object to ensure that the DataSet persists across client requests. Then the runtime generates the markup for Form2 and sends it to the client browser. After you've finished editing, the client posts back to the server, where the runtime instantiates the classes of the mobile Web Forms page once more. In the SaveChanges method, the code retrieves the same data that the user viewed and edited from the Session object and updates that data to reflect the user's changes.

/ 145