« April 2011 | Main | June 2011 »

May 2011

Filter and Display Data with ASP.NET MVC (Part 1)

Displaying a list of distinct countries of F1 racers within an HTML select element, and displaying a list of racers from one specific country has been the topic for the previous blog posts of this series. Previously this was done with ASP.NET Web Forms and ASP.NET Web Pages. The last article of this series demonstrates the same with ASP.NET MVC.

ASP.NET MVC is one of the newer ASP.NET technologies to create Web applications. Here I’m using version 3 which is an update to the version that is delivered with Visual Studio 2010. ASP.NET MVC is based on the model-view-controller pattern to make a separation between the view and the functionality. This separation helps with unit tests.

For a start I’m creating a new ASP.NET MVC Project using the Empty template. With the MVC3 templates it’s already possible to select HTML5 semantic markup with the template, and of course the Razor engine. Razor was already used with the previous blog post on Filter and display data with ASP.NET Web Pages as can be seen in the following figure.

image

The Empty project template already creates the main structure of the application with Models, Views, and Controllers directories, and JQuery scripts are also available with the project. MVC 3 contains version 1.5.1 of JQuery. A newer version is already available that can be loaded with the Visual Studio 2010 Extension Manager. However, for the simple scenario of this blog article an update is not required.

Routes

With the Empty template the global.asax file is already filled with some code. An important aspect of ASP.MVC is that the client doesn’t directly request the ASPX pages from the server, instead routing is done. The route is defined within global.asax in the method RegisterRoutes. With the generated code you can see an invocation to the MapRoute method that defines the Default route. The route is defined by {controller}/{action}/{id} with the default Home/Index/optional. The default means that if controller and action is not specified, the request to the Web application is directed to the Home controller with the Index action.

public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); }

The controller and action will be specified later. Before implementing the controller some data is needed.

Model

The entity types and data context classes to access the database is created with the help of the ADO.NET Entity Framework within the Models directory. Adding an ADO.NET Entity Data Model to the Models directory, generating the model contents from the database, and selecting the Racers table from the Formula1 database opens the designer showing the Racer type as in the following figure.

EntityDesignerDiagram

Controller

A method of a controller is invoked on a client request. Controller classes are defined within the Controllers directory. The Controller class i postfixed with the name Controller, such as the Home controller has the name HomeController. With definition of the routes you’ve seen that the default controller is the HomeController.

With the ASP.NET MVC 3 templates it’s easy to create controllers by using the Add Controller template. This template can create some implementation of the controller depending on the scaffolding options selected. First I’m showing the option to create read/write actions using the Entity Framework. With this option a model class can be selected (an entity type with the Entity Framework), and the data context class.

 

image

The generated controller class includes methods to retrieve a list of all racers, a single racer by passing the identifier, and also methods to create, edit, and delete racers.

public class HomeController : Controller { private Formula1Entities db = new Formula1Entities(); // // GET: /Home/ public ViewResult Index() { return View(db.Racers.ToList()); } // // GET: /Home/Details/5 public ViewResult Details(int id) { Racer racer = db.Racers.Single(r => r.Id == id); return View(racer); }

Another option of the template is to create a controller that contains read/write actions, but without implementation. For the sample I’m starting here with the third option to create an empty controller. This creates the HomeController class with an Index method as shown.

public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { return View(); } }

For accessing the database with the Entity Framework datacontext an instance of the Formula1Entitiies class is created and disposed.

private Formula1Entities db = new Formula1Entities(); protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); }

The first action demonstrated should return a list of racers depending on the country passed with the link, e.g. the query http://<server>/RacersByCountry/USA should return the racers from the USA. The action has the name RacersByCountry. The parameter has the name id as is defined by the parameter with the routing definition within global.asax. Returned from the action method is a ViewResult. Action methods from a controller can return a type that derives from ActionResult. Examples are JavaScriptResult to return JavaScript code, JSonResult to return a JSON object, RedirectResult to do a HTTP Redirect. To return a view, the return type is ViewResult. Partial views can be returned with the type PartialViewResult. The action RacersByCountry should return a complete view, thus the return type is defined as ViewResult. Returning a ViewResult, the View method of the Controller type is used. The View method accepts the name of the view that should be returned. If the name of the view is not passed, a view with the name of the action is selected. Another parameter of the View method is of type object where a model can be passed. This model can then be used by the view for displaying data. The sample passes a model where racers from the data context are filtered by the country.

public ViewResult RacersByCountry(string id) { return View( db.Racers.Where(r => r.Country == id).ToList()); }

View

After defining the controller it’s possible to define a view. Visual Studio templates take some work over creating the view. Selecting the Home directory inside the View (Home is the name of the controller), clicking the context menu Add | View… a new view can be created as shown in the following figure.

image

The first line of the generated view lists the model directive. This directive is new with ASP.NET MVC 3 to have a shorter notation of deriving from the base class passing the generic type for using strongly-typed model classes within the view. The longer term would be @inherits System.Web.Mvc.WebViewPage<IEnumerable<MvcDataQuery>>. In case a different base class should be used, the model directive is still possible. In such a case the base class can be configured in the configuration file. The Title of the ViewBag is set to be used within the shared layout page to set the HTML title element.

@model IEnumerable<MvcDataQuery.Content.Racer> @{ ViewBag.Title = "Racers by Country"; }

Following in the page is a HTML table with heading information. The Visual Studio template takes the properties of the model type to define the headings.

<table> <tr> <th> Firstname </th> <th> Lastname </th> <th> Country </th> <th> Starts </th> <th> Wins </th> </tr>

Every item in the model is iterated with a foreach statement. The value of every property of the item is displayed with the DisplayFor method of the HTML helper class. This method returns a string for primitive types, for Boolean values a HTML checkbox is returned.

@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Firstname) </td> <td> @Html.DisplayFor(modelItem => item.Lastname) </td> <td> @Html.DisplayFor(modelItem => item.Country) </td> <td> @Html.DisplayFor(modelItem => item.Starts) </td> <td> @Html.DisplayFor(modelItem => item.Wins) </td> </tr> }

Running the application passing a country followed on the action returns the filtered racers.

image

 

Christian

The next article in this series continues with ASP.NET MVC and adds a selection element to select available countries before displaying racers.

More information on ASP.NET MVC is available with my workshops.

All articles of this series.

CN innovation

Filter and Display Data with ASP.NET Web Pages using Microsoft WebMatrix

In the previous three blog posts I’ve shown how to filter and display data with ASP.NET Web Forms. Now I’m doing the same with ASP.NET Web Pages. You will see how to filter and display data by using Microsoft Web Matrix, ASP.NET Web Pages, and Razor.

During the early days of ASP.NET there was a free tool named ASP.NET WebMatrix to create Web applications. This was at a time before there was a free edition of Visual Studio. Nowadays there’s an Express edition of Visual Studio that gives much more options than the old ASP.NET WebMatrix. Nowadays the name WebMatrix was reused for a new tool. The new tool, Microsoft WebMatrix ,makes it easy to start writing Web applications. A ton of predefined sites are available from the Web Gallery that can be taken as they are or adapted to specific needs. The predefined sites range from Blogs to CMS systems, eCommerce, Forums, Galleries, Tools, and Wiki. Often it’s not necessary to change the predefined sites, with many scenarios configuration is all what’s needed for adaption. The following figure shows a small part of the available sites.

image

For the small sample for this blog that does nothing than listing countries of F1 racers and displaying a list of racers for a selected country (the same sample as was done with ASP.NET Web Forms in the previous three blog entries) I’m starting with a simple site from a template: an empty site.

image

After creating the site the tool gives a view to the categories Site, Files, Databases, and Reports. Selecting the Site tab gives an entry point to the three other categories and also allows for publishing and looking for a hosting provider.

To create the sample, first a connection to the database is required. In the ribbon control of the tool Microsoft WebMatrix, in the section Database, a new connection to a database can be created. Clicking on the button New Connection opens the dialog as shown in the following figure. I’m creating the connection to the existing Formula1 database.

image

After the connection is created, the connection string is added to the file web.config:

<?xml version="1.0" encoding="UTF-8"?> <configuration> <connectionStrings> <add connectionString="Trusted_Connection=True;Server=(local);Database=Formula1" name="Formula1" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>

Next a page can be created. WebMatrix supports HTML, CSS, JavaScript files, and even PHP files can be created. I’m using the CSHTML file extension.

image

CSHTML files allow mixing server-side with the Razor syntax and client-side code within one file. The Razor syntax allows writing fewer characters for server-side code in contrast to ASPX. Scott Guthrie has a great blog post to introduce the Razor syntax.

On top of the page I’m declaring a few variables and open the database with the help of the Helper class Database. This class is defined within the namespace WebMatrix.Data The Database class is an adapter to ADO.NET to offer simple database requests. The Open method opens a connection to a database. Other methods are Query, QuerySingle, and QueryValue that are used on the instance of the Database class.

@{ var db = Database.Open("Formula1"); var selectedCountry = ""; var queryRacers = "SELECT Id, Firstname, Lastname, Country, Starts, Wins " + "FROM Racers WHERE Country = @0"; var queryCountries = "SELECT DISTINCT Country FROM Racers"; }

Helper classes make it easy to offer features from many different categories from Web applications. From the ASP.NET Web Pages Administration it is possible to install a lot of different helper classes as shown in the following figure. Helper classes are available to shorten URLs, to display Twitter widgets, connect to Windows Azure storage, search and buy within Amazon, add IE9 features to the Web application, do a Bing search, offer PayPal, and a lot more!

image

Then it’s easy to create a HTML select element with option children. Other than the first option, children are filled by invoking the foreach statement to iterate every item that is returned from the database query. The variable queryCountries is defined on the top of the page to make a distinct selection of all countries. With each item in the loop the Country property is used to display the country.

<select id="countrySelection" name="countrySelection"> <option>Select a country</option> @foreach (var item in db.Query(queryCountries)) { <option>@item.Country</option> } </select>

Running the application now, the list of countries is displayed as shown.

image

One might ask, how can there be a Country property with the result from the Query method. Contrary to the ASP.NET Web Forms sample from the last blog posts, here no Entity Framework mapping was done to create the entity and context classes. To tell the truth, there isn’t a Country property available. The Query method is defined to return IEnumerable<object>. In reality a list of DynamicRecord is returned. The type DynamicRecord is defined within the namespace WebMatrix.Data as well and derives from the base class System.Dynamic.DynamicObject. This makes use of dynamic features from .NET 4 and C# 4 to program with simple property style while in turn indexers are used.

To do a postback to the server on selection of an item, some JavaScript code and a form tag is needed. I’m adding this form element to the cshtml page around the select element. Submitting this form, a HTTP POST request is done to the file QueryF1Racers.cshtml.

<form action="QueryF1Racers.cshtml" method="post">

The request is started with the onchange event of the select element. The onchange event invokes the submit method of the first form element in the page.

<select id="countrySelection" name="countrySelection" onchange="document.forms(0).submit()">

Submitting a form to the server, values of the elements within the form can be retrieved with the Request object. In this code I’m setting the variable selectedCountry to the value that is returned from Request.Form[“countrySelection”]. countrySelection is the name of the select element.

@{ if (IsPost) { selectedCountry = Request.Form["countrySelection"]; } }

Now the selection within the select element should be corrected. After a postback the select element should have the same selection as was before the request. The option element that is a choice within the select element defines the selected attribute. If the value for this attribute is true, the choice is the selected one.

@foreach (var item in db.Query(queryCountries)) { if (item.Country == selectedCountry) { <option selected="true">@item.Country</option> } else { <option>@item.Country</option> } }

To display the list of racers for a specified country, I’m using the WebGrid class that comes with WebMatrix. The WebGrid class is defined within the namespace System.Web.Helpers. This class requires the source in form of  IEnumerable<Object> as the argument. This is created by invoking the Query method of the Database instance db. The Query method receives the SELECT statement to query for all racers from a specific country. The country parameter is passed with the second argument of the Query method. Finally, the GetHtml method of the WebGrid class returns HTML code.

@{ var grid1 = new WebGrid(db.Query(queryRacers, selectedCountry)); } @grid1.GetHtml()

Running the application now a country can be selected and a list of racers from that country is displayed.

image

The WebGrid returns an HTML table as shown from the output of the IE9 Developer Tools:

image

Using Microsoft WebMatrix and ASP.NET Web Pages is really easy. It’s not anymore the drag&drop style of programming as we’ve seen with ASP.NET Web Forms. With ASP.NET Web Pages you have to write a little code. However, using helper classes such as the Database and WebGrid classes this is not that hard. One big advantage of starting the development of Web applications with Microsoft WebMatrix and ASP.NET Web Pages is that all the doors are open to move to ASP.NET MVC.

Christian

CN innovation

The same functionality as shown here will be demonstrated with ASP.NET MVC in the next article of this series.

Here you can find the links to all articles from this series.

Filter and Display Data with ASP.NET Web Forms (Part 3)

This is already part 3 of this series to filter and display data with ASP.NET Web Forms. In part 1 a distinct list of countries was retrieved from a Formula 1 Racers table, part 2 extended this to display racers from a single country within a GridView control. Changing the selection of the DropDownList control to a different country so far always makes a full postback to the server to request the new list. Part 3 now demonstrates how ASP.NET Web Forms can take advantage of Ajax to only request a part of the page.

For having Ajax functionality on a WebForms page, a ScriptManager control must be added to the page.

There can be only one instance of the ScriptManager with a page. In case master pages or user controls are used, and functionality of the ScriptManager should be used within the inner parts, the ScriptManager must be instantiated in the outer page parts, and the inner page parts can make use of the ScriptManagerProxy. The sample just defines a simple ASPX page, and thus just a singe ScriptManager is fine.

For updating only parts of the page the property EnablePartialRendering must be set to True. That’s the default setting. With this setting client-side JavaScript code is offered for partial rendering.

<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager>

To define the part of the page that should be updated asynchronously, the UpdatePanel does the job. With the sample page the DropDownList could stay the same with every page request, but the GridView should change with every selection change in the DropDownList control. Thus the GridView control should be moved within the UpdatePanel.

The DropDownList shouldn’t update. However, on selection change of the DropDownList control the Ajax postback should fire. This must be set with the Triggers collection of the UpdatePanel. Clicking on the ellipsis button of the Triggers collection in the property editor allows adding this behavior with a simple designer as the following figure shows.

image

Checking the ASPX code that’s generated reveals these settings of the UpdatePanel:

<asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:GridView ID="GridView1" runat="server" DataSourceID="EntityDataSource2"> </asp:GridView> <br /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="SelectedIndexChanged" /> </Triggers> </asp:UpdatePanel>

Running the application now just updates parts of the page instead of reloading the complete page with every selection change in the DropDownList control. The IE9 Developer Tools show the request of every page, and only the content of the UpdatePanel gets transferred. IE9 Developer Tools can be started from IE by clicking the F12 button and are really very helpful on developing Web applications Clicking the Network tab, network requests are captured and the complete HTTP request and response can be seen.

image

With an Ajax postback just the part of the update panel is replaced by new HTML code with the help from some JavaScript. There’s no need to write custom JavaScript code for doing this.

To summarize, ASP.NET Web Forms fulfills its promise with Ajax as well. With simple Web applications, partial page updates can be done easily just by using server-side controls and not deal with HTML and JavaScript at all. Of course, there are still the issues mentioned in the previous article on the ViewState, the necessity to do some tuning where still code is required, and ASP.NET Web Forms also lacks of a good way for unit testing.

Christian

CN innovation

The next article in this series makes use of a newer technology – ASP.NET Web Pages. Here Microsoft WebMatrix will be used as a tool instead of Visual Studio 2010. More on that next week.

Here you can find the links to all articles on this series.

Filter and display data with ASP.NET Web Forms (Part 2)

In the first part of this article series distinct countries from Formula 1 racers were retrieved from the database with the help of the ADO.NET Entity Framework and the EntityDataSource control. The country list was displayed in a DropDownList. Doing this not a single line of writing code was required, all could be done by setting properties of controls. All could be done with the help of Visual Studio 2010 designers. The second part continues on this to add another data source to retrieve the racers from a single country and display them.

To display the list of Formula 1 racers from a country the GridView control is used. This control needs another EntityDataSource. This data source is configured to select all the columns from the Racer type as shown:

image

However, not all racers should be displayed. The query should be filtered based on the selected country value from the DropDownList control. This can be done with a designer as well by configuring the Where property of the EntityDataSource control. Clicking the ellipsis button opens the Expression editor as shown in the following screen. Adding a Country parameter defines a Where clause to filter based on the Country. The value for this parameter can come from different source types, such as a cookie, another control, form value, profile, query string, and new with ASP.NET 4 also routing data. Here the source is a control, namely the DropDownList1 instance. Using the SelectedValue property of this control is done automatically.

 

image

The resulting list should also be sorted. The sort order can be defined by setting the OrderBy property of the EntityDataSource. The editor for this property is shown here. The OrderExpression requires Entity-SQL syntax using it. Entity SQL helper methods are based on it. While it’s easy to configure the dialogs by simply selecting checkboxes, it really helps knowing a little Entity-SQL on using the EntityDataSource.

image

 

The resulting configuration of this EntityDataSource can be seen in the source view of the ASPX file. The WhereParameters collection contains an ControlParameter.

<asp:EntityDataSource ID="EntityDataSource2" runat="server" AutoGenerateWhereClause="True" ConnectionString="name=Formula1Entities" DefaultContainerName="Formula1Entities" EnableFlattening="False" EntitySetName="Racers" EntityTypeFilter="Racer" OrderBy="it.[Wins] desc" Where="" Select=""> <WhereParameters> <asp:ControlParameter ControlID="DropDownList1" Name="Country" PropertyName="SelectedValue" /> </WhereParameters> </asp:EntityDataSource>

Running the application now the racers can be filtered based on the country and are sorted by the number of wins  as shown in this figure:

image

Now all of this was possible without writing a single line of code. Setting properties of server-side controls is all what’s needed. The code from the code-behind didn’t change from creating the ASPX file:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebFormsDataQuery { public partial class RacersByCountry : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } } }

Of course not everything is fast as it should be. For example, with every call of the page because of two EntityDataSource objects to different entity contexts are created that are filled by two queries. The first one to get all the countries, the second one to get the racers from a country. Writing a few lines of code there can be an easy fix. The EntityDataSource control defines events before the context is created (ContextCreating), and after the context is created (ContextCreated). Writing a handler for the ContextCreating event a data context can be assigned. The handler method OnContextCreating creates a data context only once. If the data context was already created, the existing one is used. Assigning the ContextCreating event of both EntityDataSource controls to this event handler, both controls make use of the same context.

private Formula1Entities data; protected void OnContextCreating(object sender, EntityDataSourceContextCreatingEventArgs e) { if (data == null) data = new Formula1Entities(); e.Context = data; } public void Page_Unload(object sender, EventArgs e) { if (data != null) data.Dispose(); }

This is just one issue of the page. Another question that should be asked is if the countries list shouldn’t be shared across all users of the Web application. It’s the same result that should be returned anyway. This could be done using the Cache object.

Also, the view state can be really huge. This sample page is very small, but to see the ViewState you need to scroll far to the right with the following resulting HTML code.

<div class="aspNetHidden"> <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" /> <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" /> <input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" /> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="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" /> </div>

There are ways to fix this. The sample page just needs the ViewState for remembering the previous selection of the DropDownList to handle the change event, it can be turned off with other controls.

You should also interested in the HTML code that’s generated. The GridView control by default creates a HTML table as shown.

<table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;"> <tr> <th scope="col">Id</th><th scope="col">Firstname</th> <th scope="col">Lastname</th><th scope="col">Country</th> <th scope="col">Starts</th><th scope="col">Wins</th> </tr><tr> <td>11</td><td>Jochen</td><td>Rindt</td><td>Austria</td><td>60</td><td>6</td> </tr><tr> <td>19</td><td>Niki</td><td>Lauda</td><td>Austria</td><td>170</td><td>25</td> </tr><tr> <td>226</td><td>Gerhard</td><td>Berger</td><td>Austria</td><td>210</td><td>10</td> </tr><tr> <td>254</td><td>Karl</td><td>Wendlinger</td><td>Austria</td><td>42</td><td>0</td> </tr><tr> <td>274</td><td>Alexander</td><td>Wurz</td><td>Austria</td><td>62</td><td>0</td> </tr><tr> <td>294</td><td>Christian</td><td>Klien</td><td>Austria</td><td>49</td><td>0</td> </tr><tr> <td>299</td><td>Patrick</td><td>Friesacher</td><td>Austria</td><td>11</td><td>0</td> </tr> </table>

Of course there are also ways influencing this. Custom templates allow defining the code that should be returned from the control.

Giving a first summary, with the help of the Visual Studio 2010 designer it’s really easy to create Web applications just by setting some properties. If the Web application doesn’t expect many requests, data transfer and performance is not an issue, it can be used as it is. Otherwise a lot of tuning is required.

The next part of this blog series extends the ASP.NET Web Forms sample to add AJAX functionality using server-side controls.

Here you can find the links to all articles on this series.

Christian

CN innovation

Filter and display data with ASP.NET Web Forms (Part 1)

This is the first article of a series using ASP.NET to filter and display data from a database. This article has the focus on ASP.NET Web Forms, you can read how to filter and display data using ASP.NET server controls. Follow on articles continue with Web Pages and MVC as mentioned in the introduction.

First a new project with the Visual Studio 2010 project template ASP.NET Empty Web Application is created.

The sample application makes use of a Formula 1 database and accesses it with the ADO.NET Entity Framework. The Racers table is directly mapped to the Racer type that is shown in the following figure. Just the designer is used to create the entity type and data context that is needed to access the database.

 Racer type Entity designer

The designer not only creates the types for the entities and the data context but also adds a connection string to web.config:

<connectionStrings> <add name="Formula1Entities" connectionString="metadata=res://*/Formula1Model.csdl|res://*/Formula1Model.ssdl|res://*/Formula1Model.msl; provider=System.Data.SqlClient;provider connection string=&quot;data source=(local);initial catalog=Formula1;integrated security=True;multipleactiveresultsets=True; App=EntityFramework&quot;" providerName="System.Data.EntityClient" /> </connectionStrings>

Next I’m creating a Web Form named RacersByCountry.aspx with the item template. A main idea of Web Forms is to abstract HTML and JavaScript away and make programming as similar to writing Windows applications as possible. Web server controls have properties that are very similar to Windows Forms controls. With ASP.NET 4 (and also some earlier editions of this framework) it should be possible to create a Web application with very few lines of code. Let’s have a look at how this works out in this simple scenario.

To display a list of all countries of the racers I’m using the Web server control DropDownList. This server-side control creates a HTML select element. Selecting the Enable AutoPostback checkbox from the smart tag in the designer makes use of JavaScript code to do a postback to the server on changing the selected element in the list.

For showing data, this control needs a data source. Available with the Data category in the toolbox several data source controls can be chosen from. The SqlDataSource makes use of the ADO.NET DataSet, or uses a DataReader directly. The XmlDataSource is a source for XML data as should be clear from its name. ObjectDataSource accesses objects and invokes methods from these objects. LinqDataSource uses LINQ to SQL as its source. EntityDataSource is the one used here to access the data context defined earlier.

The configuration of the EntityDataSource is shown in the next figures. The first configuration screen just needs the name of the connection string to offer the data context class as the DefaultContainerName.

image

With the second screen the entity set Racers with the type filter Racer is used. The query that is created to display the countries only needs the Country property of the Racer type, so just this property is selected.

image

Selecting the DropDownList in the designer, now the data source can be configured. With the data source selection, the EntityDataSource1 instance is selected.

image

The resulting ASPX code of the DropDownList control sets the properties DataSourceId, DataTextField, and DataValueField as shown.

<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" DataSourceID="EntityDataSource1" DataTextField="Country" DataValueField="Country" Height="30px" Width="173px"> </asp:DropDownList>

The query to retrieve the countries of the Racers table shouldn’t return the country of every racer, instead distinct values should be returned. The Select expression can be changed by using a designer opened from the Select property of the EntityDataSource adding DISTINCT as shown in the following figure.

image

The generated ASPX code for the EntityDataSource is shown here.

<asp:EntityDataSource ID="EntityDataSource1" runat="server" ConnectionString="name=Formula1Entities" DefaultContainerName="Formula1Entities" EnableFlattening="False" EntitySetName="Racers" EntityTypeFilter="Racer" Select="DISTINCT it.[Country]"> </asp:EntityDataSource>

Running the application distinct countries are displayed with an HTML select element  as the following figure shows.

image

So far all this was possible without writing a single line of code. All functionality was possible by using server-side controls and setting some properties with the help of a designer. This is a big advantage of ASP.NET Web Forms. This advantage doesn’t come without disadvantages that will be discussed as well.

Next in this series a grid is added to the display to show the racers from a single country. Let’s see how this can be done without writing a single line of code as well.

Christian

CN innovation

Filter and display data with ASP.NET Web Pages, Web Forms, and MVC

ASP.NET gives three main choices to create Web applications: ASP.NET Web Pages, ASP.NET Web Forms, and ASP.NET MVC. Of course there are a lot more options to choose from such as doing Web sites or Web projects, using Razor or ASPX syntax, accessing the database using ADO.NET Entity Framework or LINQ to SQL or directly ADO.NET, or a third party solution, there’s a large selection of JavaScript libraries… I think this list could be endlessly. This shot blog series concentrates on the three main options and gives information on differences between these technologies.

Demonstrating the differences, samples are given on displaying data from a database. The scenario is very simple with a selection list and a table to display records. The sample data I’m using is a Formula1 database with a table of F1 racers. The racers are filtered by the country they are from, and only racers from a single country are displayed. A combo box is used to select a country from the racers, and then the racers from the country are displayed. The same scenario is done with ASP.NET Web Forms, Web Pages, and ASP.NET MVC.

The first blog of this series will cover ASP.NET Web Forms and will be available soon linked from here.

Christian

CN innovation