47 posts categorized "Data & XML"

12/22/2012

Windows Store App Picture Search Part 2: Creating a Windows Runtime Component

Picture Search is a Windows Store sample app that is used to search pictures with Bing Search. The first part of this article series showed the implementation of a ASP.NET Web API service that itself called the Bing service. The second part of this series is about creating a Windows Runtime component that makes a request to the Web API service. The article is not only about the invocation of the service, but also the implementation of a Windows Runtime Component.

Deutschsprachige Version des Artikels

Picture Search in the App Store

 

Libraries for Windows Store Apps

For creating libraries for Windows Store apps using C# and XAML different options are available:

  • Class Library (Windows Store Apps)
  • Windows Runtime Component
  • Portable Class Library

The Class Library (Windows Store Apps) is a .NET library as we know it from creating .NET applications. However, here the library is reduced to a .NET subset with classes and methods that are available for Windows Store apps.

With the Add New Project template, The Portable Class Library cannot be found in the category of Windows Store templates. Instead, this template is available in the Windows category. This library is not restricted to use from Windows Store apps, you can use it with Windows desktop apps or Silverlight apps instead. The library can be configured for the available set of technologies (including Xbox 360) to create applications. Accordingly to the configuration only a subset of .NET is available.

The third option is the Windows Runtime Component. Creating such a library, the library can not only be used with .NET applications, but also with other Windows Store app technologies such as JavaScript and C++. However, creating this library with C# and using it from C++ or JavaScript also means that the .NET runtime needs to be loaded

Creating a Windows Runtime Component

Windows Runtime Components can be created with a Visual Studio project template.

image

Only Sealed Types

An important restriction for this type of library is that all public types must be sealed – with the exception of UI components.

PictureInformation represents the data which is received from the service: Title, Url, ThumbnailUrl, and Source. This class is similar to other .NET classes – with the exception that it needs to be sealed. Properties can be offered by Windows Runtime components directly.

public sealed class PictureInformation
{
   public string Title { get; set; }
   public string Url { get; set; }
   public string ThumbnailUrl { get; set; }
   public string Source { get; set; }
}
 

Converting a JSON Array to an Object List

SearchManager is the second class in this assembly. This class is sealed as well.

The GetImagesAsyncInternal method makes a call to the Web service. Similar to the first part of this article series, the HttpClient class is used to make the request. GetStringAsync returns a JSON result from the service.

A JSON string can be parsed by using classes from the namespace Windows.Data.Json. The Windows Runtime offers JSON and XML classes in the namespaces Windows.Data.Json, Windows.Data.Xml.Dom, and Windows.Data.Xml.Xsl.

private async Task<IEnumerable<PictureInformation>> GetImagesAsyncInternal(string searchTerm)
{
   string urlRequest = url + searchTerm;
   var client = new HttpClient();
   string jsonResult = await client.GetStringAsync(urlRequest);

  var results = await Task.Run<IEnumerable<PictureInformation>>(() =>
   {
     var searchItems = new List<PictureInformation>();

    JsonArray result;
     if (JsonArray.TryParse(jsonResult, out result))
     {
         foreach (var jsonItem in result)
         {
             JsonObject jsonObj = jsonItem.GetObject();

            var searchItem = new PictureInformation
             {
                 Title = jsonObj["Title"].GetString(),
                 Url = jsonObj["Url"].GetString(),
                 Source = jsonObj["Source"].GetString(),
                 ThumbnailUrl = jsonObj["ThumbnailUrl"].GetString()
             };
             searchItems.Add(searchItem);
         }
     }
     return searchItems;
   });

  return results;
}

The GetImagesAsyncInternal method uses the C# 5 async and await keywords for calling asynchronous methods. As usual with .NET async code, the method returns a task. The caller of an async mehtod does not block the caller thread. Continuation tasks are used behind the scenes with the await keyword.

If this method would be declared public, a compile run results in the error that the task of the type is not a valid Windows runtime type. Public methods within Windows runtime components can only use Windows runtime compatible types in the signature.

A Task can be converted to a Windows runtime type by using the extension method AsAsyncOperation. AsAsyncOperation is an extension method for the Task type and returns IAsyncOperation. IAsyncOperation is the interface of the Windows runtime (namespace Windows.Foundation) for asynchronous calls, and can be used with C# 5 async and await.

public IAsyncOperation<IEnumerable<PictureInformation>> GetImagesAsync(string searchTerm)
{
   Task<IEnumerable<PictureInformation>> t = GetImagesAsyncInternal(searchTerm);
   return t.AsAsyncOperation();
}

 

Summary

Windows Runtime components are libraries for Windows Store apps and can be used with .NET, JavaScript, and C++. Contrary to other .NET libraries, this library is restricted on using Windows runtime types in the signature. With the help of small utilities, such as extension methods, this is an easy task.

Christian

CN innovation

More about Windows Store apps in my book Professional C# 2012 and .NET 4.5, and my Windows Store App workshops.

This article series:

Part 1 – Web API – Search with Bing

Part 2 – Windows Runtime Components

Part 3 – Layout

Part 4 – Settings

Part 5 – Search

Part 6 – Share

12/04/2012

Picture Search Part 1: Searching with Bing

Picture Search is a Windows Store sample app that is used to search pictures with Bing or other services such as Flickr. With this blog you will find an article series that goes through all the different aspects of the application such as defining the user interface to show a grid of pictures, starting the search with the help of the search contract, sharing pictures, and organizing the pictures in the UI with the grid view control using grouping and a collection view source.

The first part of this article series shows the implementation of the server part using the ASP.NET Web API hosted within a Windows Azure Web site. The service offered here will be used from the Windows Store app later on.

Attendees of my Windows 8 Camp at Microsoft or from the Windows 8 Deep Dive at Basta! Austria already know this Windows Store sample app – Picture Search. Please find the source code here!

Creating the service using the ASP.NET Web API

Let’s start with an ASP.NET MVC 4 Web Application.

image

The ASP.NET MVC 4 Web Application offers the Web API Project template.

image

This project type defines a ValuesController type in the Controllers folder. However, this one is not used for the sample app. A new controller named BingSearchController is created for the Picture Search app.

image

The BingSearchController defines the Get method for doing a HTTP GET request passing a search term, and retrieving a list of PictureInformation objects. This controller method makes use of the SearchManager that instantiates the request to the Bing service.

        public async Task<IEnumerable<PictureInformation>> Get(string id)
        {
          SearchManager manager = new SearchManager();
          IEnumerable<PictureInformation> result = await manager.SearchImagesAsync(id);
          return result;
        }

By defining the Get method in the BingSearchController class, the URL to retrieve the returned items is http://<server>/api/bingsearch/<searchTerm>.

For the implementation of the controller, the SearchManager and PictureInformation types are needed. These types are defined next.

The Data Transfer Object

The PictureInformation class is a simple data holder that contains the title, Url, and ThumbnailUrl of the image.

  public class PictureInformation
  {
    public string Title { get; set; }
    public string Url { get; set; }
    public string ThumbnailUrl { get; set; }
    public string Source { get; set; }
  }

Contract for Image Requests

The picture search service can use different picture search providers, e.g. Bing and Flickr. In the book Professional C# 2012 and .NET 4.5 you can find implementations calling both of these services. The sample here just makes use of Bing search.

For creating different implementations, the interface IImageRequest is defined. With this interface, the search provider returns a Url property dependent on the provider that contains the search term. Both of these providers return XML content with the search request. This content is parsed by calling the Parse method of the IImageRequest interface. This returns a collection of PictureInformation objects.

  public interface IImageRequest
  {
    string SearchTerm { get; set; }
    string Url { get; }

    IEnumerable<PictureInformation> Parse(string xml);

    ICredentials Credentials { get; }
  }

Bing Search Request

The class BingRequest is the implementation of the IImageRequest interface to do the search via Bing. For using this class you need to add the application identifier. You can get this identifier by registering with the Bing Search API available at the Windows Azure Marketplace: https://datamarket.azure.com/dataset/bing/search. Up to 5000 transactions per month are free.

The major parts of this class are the Url property that returns the URL link to access the service including the search term, and the Parse method that makes use of LINQ to XML to convert the XML content to an object collection.

  public class BingRequest : IImageRequest
  {
    private const string AppId = "enter your BING app-id here!";

    public BingRequest()
    {
      Count = 50;
      Offset = 0;
    }

    private string searchTerm;
    public string SearchTerm
    {
      get { return searchTerm; }
      set { searchTerm = value; }
    }

    public string Url
    {
      get
      {
        return string.Format("https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Image?Query=%27{0}%27&$top={1}&$skip={2}&$format=Atom", SearchTerm, Count, Offset);
      }
    }

    public int Count { get; set; }
    public int Offset { get; set; }

    public IEnumerable<PictureInformation> Parse(string xml)
    {
      XElement respXml = XElement.Parse(xml);
      XNamespace d = XNamespace.Get("http://schemas.microsoft.com/ado/2007/08/dataservices");
      XNamespace m = XNamespace.Get("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");

      return (from item in respXml.Descendants(m + "properties")
              select new PictureInformation
              {
                Title = new String(item.Element(d + "Title").Value.Cast<char>().Take(50).ToArray()),
                Url = item.Element(d + "MediaUrl").Value,
                ThumbnailUrl = item.Element(d + "Thumbnail").Element(d + "MediaUrl").Value,
                Source = "Bing"
              }).ToList();
    }

    public ICredentials Credentials
    {
      get
      {
        return new NetworkCredential(AppId, AppId);
      }
    }
  }

Making the Call to Bing Search

The SearchManager class that is called from the Web API controller makes an asynchronous GET request to the Bing service. The request is done by the HttpClient class. This class is new with .NET 4.5 and fully based on asynchronous features.

  public class SearchManager
  {
    public async Task<IEnumerable<PictureInformation>> SearchImagesAsync(string searchTerm)
    {
      var request = new BingRequest();
      request.SearchTerm = searchTerm;
      
      var client = new HttpClient(new HttpClientHandler
        {
          Credentials = request.Credentials
        });
      HttpResponseMessage response = await client.GetAsync(request.Url);
      string resp = await response.Content.ReadAsStringAsync();
      IEnumerable<PictureInformation> images = null;
      await Task.Run(() =>
      {
        images = request.Parse(resp);
      });
      return images;
    }
  }

Instead of invoking GetAsync and then ReadAsStringAsync with the returned HttpResponseMessage, the implementation could be simplified by invoking GetStringAsync. I’ve decided for the former version to show more functionality of this class.

Calling the Search Service

With all this in place, the service can be invoked to make picture search requests. This can be a simple test from a Web browser, e.g. calling http://<server>/api/bingsearch/Ferrari. Calling this from IE returns JSON data, e.g. this collection as defined by the PictureInformation class:

[{"Title":"Voici une belle photo de Ferrari de qualité",
   "Url":"http://images-et-photos.com/files/ferrari1.jpg",
   "ThumbnailUrl":"http://ts1.mm.bing.net/th?id=H.4902048858114356&pid=15.1",
   "Source":"Bing"},
  {"Title":"Name: ferrari pictures.jpgViews: 110204Size:337.4",
   "Url":"http://www.whitegadget.com/attachments/pc-wallpapers/75212d1315377041-ferrari-ferrari-pictures.jpg",
   "ThumbnailUrl":"http://ts2.mm.bing.net/th?id=I.4894034425284685&pid=15.1&W=160&H=120",
   "Source":"Bing"},
  {"Title":"Ferrari Enzo Ferrari Photos:",
   "Url":"http://world-viewer.com/data_images/ferrari-enzo-ferrari/ferrari-enzo-ferrari-04.jpg",
   "ThumbnailUrl":"http://ts3.mm.bing.net/th?id=I.4935837306587618&pid=15.1&W=160&H=120",
   "Source":"Bing"},

 

In the next article of this series I’m creating a Windows runtime component to call this Web API service.

More information on the Web API and Windows Store apps can be found in my workshops and in my book Professional C# 2012 and .NET 4.5.

Christian

CN innovation

06/06/2011

Filter and Display Data with ASP.NET MVC (Part 2)–Partial Views and JQuery

In the previous blog post the sample to filter and display data with Formula 1 racers filtered by the country was started with ASP.NET MVC3. The first part created the model using the ADO.NET Entity Framework to map the Racers table to the Racer type, a controller to return filtered racers, and a view to display the racers. This article extends the example by adding a country selection and using JQuery to get the racers based on the selection.

DropDownList and ViewBag

First let’s start adding a controller method to display the countries of all racers. In the previous sample data was sent from the controller to the view by passing a model to the View method. This is one way of passing data to the view. Another way that is used here, is using ViewData or ViewBag properties of the ViewPage class. ViewData is of type ViewDataDictionary and allows assigning any object by using a dictionary key. ViewBag is new with MVC 3 and uses dynamic extensions to allow writing code without using the indexer syntax. For example, instead of writing ViewData[“Countries”], ViewBag.Countries can be used.

In the sample, a SelectList is assigned to ViewBag.Countries. SelectList is used to fill HTML select elements. SelectList is a collection of SelectListItem objects and has DataTextField and DataValueField properties to define what should be displayed in the select element, and what should be used as a value of the select element. In the sample, the SelectList is filled with a string list of unique countries.

public ViewResult Index() { var countries = new SelectList( db.Racers.Select(r => r.Country).Distinct().ToList()); ViewBag.Countries = countries; return View(); }

Within the view the HTML Helper method DropDownList can be used to create a select HTML element. The method DropDownList is defined with the class SelectExtensions. SelectExtensions defines extension methods to the HtmlHelper type for ListBox and DropDownList. The first paramter used with DropDownList defines a name and id for the HTML select element and also uses ViewData with the key of the first parameter (Countries) to display these data with option elements. The second parameter defines the option that is selected by default – in case it doesn’t exist this option is added.

<legend>Racers by Country</legend> <div> @Html.DropDownList("Countries", "select a country") </div>

Running the application the select element lists countries from all racers as shown in the following figure.

image

After the country is selected, the racers of the country should be displayed.

Partial View

With the previous blog post racers have been filtered based on a country by using an URL parameter route. Instead of building the same functionality within the page that contains the DropDownList it would make sense to make that functionality reusable. With ASP.NET MVC something like user controls can be created. With ASP.NET MVC the technology to render a part of a Web page is a partial view. According to that the action method within the controller returns a PartialViewResult that is created from the PartialView method:

public PartialViewResult RacersByCountryPartial(string id) { return PartialView( db.Racers.Where(r => r.Country == id).OrderByDescending(r => r.Wins) .ThenBy(r => r.Lastname).ToList()); }

The partial view that makes use of the model is defined in the view file RacersByCountryPartial.cshml. The implementation is the same as in the previous blog post just with the difference that here’s just the HTML part defined that goes into another HTML page.

@model IEnumerable<MvcDataQuery.Content.Racer> <table> <tr> <th> Firstname </th> <th> Lastname </th> <th> Country </th> <th> Starts </th> <th> Wins </th> </tr> @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> } </table>

A partial view can be rendered within a page by using the method RenderPartial. This method requires the action and model with the parameters. If the page itself has a model directive, the model can be passed to the partial action using ViewData.Model.

@{ Html.RenderPartial("RacersByCountryPartial", ViewData.Model); }

With the sample the action to request the partial page should be done from the client side using JavaScript when the selection of the select element changes. This is done in the next step.

Requesting Partial Views with JQuery

JQuery scripts are included with ASP.NET MVC by default. So now we’re making use of JQuery to request the partial view from the server.

First, empty div elements are defined that will be updated by JQuery calls.

<fieldset> <legend>Racers by Country</legend> <div> @Html.DropDownList("Countries", "select a country") </div> <br /> <div id="target"> </div> <div id="log"> </div> </fieldset>

Now let’s get into scripting. On the change event of the select element that lists the countries, the racers should be requested. The event handler can only be added after the DOM of the page is loaded.

$ is a shorthand alias for the jquery function. The first selector that is used is the document itself. The ready function binds a function that is invoked as soon as DOM of the page is ready to be used. The function that is invoked as soon as DOM is loaded searches for the element with the name Countries (using #Countries in the selector) and binds a function to the change event of that element.

<script type="text/javascript"> $(document).ready(function () { $("#Countries").change(function () { }); }); </script>

The function that is bound to the change event of the select element is invoked as soon as the selection is changed. Let’s implement this function. First we need to find the selected country. The variable countrySelected gets the current selection from the select element. $(“select option:selected”) finds the option elements inside the select element that have the selected attribute set to true. Because with a multi-selection select more than one items can be selected (which is not the case here), we need to get just one. The first() function just returns one element. text() gets the text value from this element, which is the selected country. $.get() makes an HTTP GET request. The first parameter of the requires the URL to be passed. The URL is generated from the server-side method Url.Action. This method returns the relative path to the controller where the parameter of the method is appended. With this sample it’s the Home controller and thus the relative path /Home/RacersByCountryPartial. The second parameter of the get function specifies key/value pairs that are sent to the server. Here the selected country retrieved from the select element is passed. The next parameter defines a function that is invoked as soon as the result from the HTTP GET request is returned. The selector looks for the div element with the target id, then the content of the div element is updated with the data returned from the GET request.

<script type="text/javascript"> $(document).ready(function () { $("#Countries").change(function () { var countrySelected = $("select option:selected").first().text(); $.get('@Url.Action("RacersByCountryPartial")', { id: countrySelected }, function (data) { $("#target").html(data); }); }); }); </script>

Of course the HTTP GET request to the server can fail. That’s why a function is attached in case an Ajax call fails. Within this function just a message box is shown to display the error.

<script type="text/javascript"> $(document).ready(function () { $("#Countries").change(function () { $("#log").ajaxError(function (event, jqxhr, settings, exception) { alert(exception); }); var countrySelected = $("select option:selected").first().text(); $.get('@Url.Action("RacersByCountryPartial")', { id: countrySelected }, function (data) { $("#target").html(data); }); }); }); </script>
Now the sample is ready to filter and display racers.  
image

This concludes the filter and query sample with ASP.NET MVC.

Summary

With ASP.NET MVC the server-side functionality is separated into controller, view, and model. This separation makes it easy to create unit tests. This is in contrast to the technology ASP.NET Web Pages that was shown earlier. ASP.NET Web Pages makes a mix of server-side code within client-side pages. ASP.NET Web Pages an serve as a starter, then it is easy to change into ASP.NET MVC by adding models and controllers, and changing the views accordingly.

ASP.NET MVC also full control over the client writing HTML code with JavaScript and JavaScript libraries such as JQuery. HTML Helper methods make it easy to generate HTML code.

ASP.NET MVC has a big difference compared to writing Web applications with ASP.NET Web Forms. Using ASP.NET Web Forms, Web applications can be written nearly without any HTML and JavaScript code. This makes it easy if a developer is coming from writing Windows Forms applications, but looses control over data sent across the network and performance both on the client- and the server side.

ASP.NET MVC gives full control over HTML and JavaScript. JQuery makes writing scripting code easier especially if you are used to writing Lambda expressions. Functionality behind the scene is written with well known .NET technologies. The MVC pattern makes unit testing a lot easier.

Christian

CN innovation

All the articles of this ASP.NET series

More information in my workshops

05/30/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

05/23/2011

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.

05/20/2011

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.

05/19/2011

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="QqVD2dAmqLYvg8TBGboYUGY3cHeJwH4/i8m7ppSGFt6jB8E8M/ORfZXnonXmhy8bWDcmTc4+m4FLblhEcVOkyfrZIUnicUkQHJ7vsjWxBOMnIWwuA4mMBUuOziqsYXxvfIi/5QdlNyx9O9YKBPDTYBMmlhdVusGa0H9b7spH3bnKRPawhqiqGQyi8xXS5PtrYZad5ptzdfosrCGzReDkYKC+bqaUsqZkjKYIIJ4oqIkEZzNXZ18yvW65hLwD1+EPVcWFSz7pXfdqnraU0zWpy8CcISkpfQPdFpipcp5NrR9qEAYtJUkEj3cxElcQZ4IjI6eLc3be+JqpZt4rpGMcsz3G/AyZ9KvnYS/YXAXwwr4X81dPU8QvhEiNkugPv/CeoQGw1LGWAtNbl52t+iXRdkSWqdGMpoFYQd2XzrEz3ZBsVj/rG/rCRWSewwYIC29hjICHvyFLCFAu9Y57ggKA2gmTcD3FqSdzTjHrt6PA1rowmeuRvNAkpHEbewQtUjJdK/0clboAQWYQeAaUO0ubXgsbW+uwd/ckyx+tORJ+/kgNFnpMMTTTNRArZgTzW8p2sT6o48RVKhDqS5tYzzvSblPDkc4xR1mNTQqn2iwArD0lm9VLSsRcIjXEkxNAUVPUIq0IyZ3PDH2g4/n0G1evI7DasIoyJfLE0v9k9yYPcVbaGtHy+6kJRqKu7i9WmaGQTiV8oMY6WLyZ2pB7sINepzKlo89VBFX+MVeyN2i2s+/ozLptTdC8wdaEP4Jf2CKtJQtT6DtxPn/9HYvJKQUcGPsNBzp1TZsCrWb1/o7la1LriRzTpI47yONpuaiKWdJfMs/FakaKs1KXFOoSptrYMcEx57eNjcqcblYDsl+cUYgSROIUjxiDB3PWQ+knHxgXuDA7Ibgu/PWkmLnTwrFF4PCk1FuWCU9XKvXCLho63bj9NYJXXi3w/Qp9GDKyDID4fDNXVznnDMwt79pgefQyrt7lCXLHYf9y49/4bVNRNE+3sSmnq+vc4gWZaqwboLxzFOYroWErMdmR38YiOUeYl4MQPLDLLScrM0QCj3YgHGE57aAqTy7zRvN4e6zYxoBrRcMnaqrfxUxWZL/m8aDLrtCUJIOkBY3oWssZTQkoOhdn8OQVrWSMCr53Sfw0RbNyB3hFngauweJFg0qsxw1lAXWj4WTGW8zf1A+mJpYVPc8sUilzKUiIvNSoKBsCE/3ZGxWU9ZL0BYx2SXPjZBKsjkqq9ANa/Hw7YnFlNrFnNYt92trfEoY3Ap2O80SV7c3D7+Dsm3flXg2eHeU2oO8ceUU/8/0RSfm604oECN9RIiBeNzzhflJywIoKj5C2b3u2tijRg7y0lYNMVG0dIp2Bwm5yJeNzdt22p0KowIpzGAVXxPTX78ltrltfeS0G6CPjxyKPBFrp1RRDq18fp2piRY3IZ2sDoWhXETL/dBfnzLYtdZzFhh/KXzPrbcCjgSVqkWplPzWHXgjSY1wEru3pEMWyyf1zydsd+unytbEUz6GSKJ3UhWqZAcEt3+BbDs+v5sRo8a60DnzaDMu2KIiH+bTFQAz7QE6ux5ZRa7wmk52mIclc06dncxkgmijLZRhEZlKc2HhkN0KdOkhBve1Ufu2ZZix60/Q8WIvsTKFg2Sg6mNWNMl9RacVM7CrC/Ta/xKJDw+BIYqe9V2dvuRz7unSzVmJd78CLzHF/nqCzRJmRfnNwtyqjjjF3v+wTSv/f8qG4TVT8hkNUedhX6j88GGmtByFWWyhXUQSYC+5dwFUYCP0KMhiPW8kXOPGafscyUbhvRcjsKCBCe2mwtrWsDgjrSxl0ZS5tzq0IpKimlyB33QRHEHWAG2skuacQvdn3p7Cv2dSjmNeKjNY7S62mIOwKUj/uZpMua2StXiwXkyE9yNraJTOuV9OCoA32ro3AAOlwUGCSOvqT0yuU32sUbvn91FxTR4wcBCi9JE0bhhX/Z2IsdJn3rCI3OPEtVdhUp29RATgWETAsOMZ7bTc1u2Tq/Y08DjtEqLPgu36gbpdc+dOXqczmbM8U6njYuXzhMZrMplVNWJ7uP4qgXu6ZtuyBC/SxvIPCQpm8BaLmGCRke1Fu6enkJ52qvBc5/N+nN5/hKsB5V5gf2ZgK8XM2H59Cp1ouDmZZdfxESmKG4rlZNdb5Bt3VZIr0dT52zoXhjrtH3G3oEqw4tTyxd0yT1TsxXbQy8srodDxpYsOeSpjNqTWx4XmlFZcaTWYTxAeRQvUyXu/qtXt1zcTr95siJCEWNIqSblCYZ81lVSiIJeMY8mUq30xGBAISM8gd71ONDCqAKPN5RDGoAp6FQZ6F0gnl8y3LzfL/Ai8B24EOhXNJd1Ayk1esYlz9AqLWR3VcM6dmQ/d3y9oHSmpNNiEF9Q==" /> </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

05/18/2011

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

05/17/2011

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

12/08/2010

A few LINQ Queries

Many of my course attendees, book readers, and attendees of my conference sessions know my Formula 1 samples Smile This time in a workshop I had questions on how to do some specific queries where the Formula 1 champions again come very handy.

Using the Racer class that has properties as shown here:

public string FirstName { get; set; } public string LastName { get; set; } public string Country { get; set; } public int Wins { get; set; } public int Starts { get; set; } public int[] Years { get; private set; } public string[] Cars { get; private set; }

these questions were asked: “how to get champions from three specific years”, and “how to sort the champions based on the first year they won the championship”. The interesting part is here that the Year property of a Racer is a collection on itself. A racer can be a champion in several years. Still, this can be done easily with LINQ.

The first example I’ve done more general instead of giving the option for three years, the method declaration allows for a flexible number of years:

public static void ChampionsOfSeveralYears(params int[] years)

And it can be invoked like this:

ChampionsOfSeveralYears(1970, 1975, 1984);

The query is not difficult to do. A compound from is good to access all the years of a racer, then the year can be used with the Contains method to check if the year of a racer is within the collection of years received with the parameter of the method:

var q = from r in Formula1.GetChampions() from y in r.Years where years.Contains(y) select r;

If you are curious, the result passing the years shown earlier is

Jochen Rindt Niki Lauda Niki Lauda

If the matching year should be shown with the racer, this can be done by creating a new type:

var q = from r in Formula1.GetChampions() from y in r.Years where years.Contains(y) select new { Racer = r, Year = y };

To get the first year of a racers championship the operator First comes handy. This sample has several orderby. Years.OrderBy(y => y) is first used to order the championship years of a single racer in case this is not already ordered. Then the first of these years is used, and then the result with all the racers and their first championship year is ordered.

var q = from r in Formula1.GetChampions() orderby r.Years.OrderBy(y => y).First() select r;

Many more queries are found in the book Professional C# 4 with .NET 4 and in my LINQ workshops.

Also more LINQ queries here:

Christian

CN innovation

Follow me on twitter