# Monday, 21 June 2010

Read the other posts in this series:

In the previous blog posts listed above, I showed how Telerik’s new LINQ implementation works with WCF RIA Services. I showed how to build your own Domain Service as well as build custom query methods. In this post I will show how to build a metadata class. (Note: future versions of the OpenAccess LINQ Implementation will produce the metadata class for you automatically.)

The WCF RIA Services metadata class is a separate class from the DomainService that contains information about the entities. In this class you can write custom validation logic, set attributes of the properties of the entities or indicate whether the property is to be generated on the client or not.

To create this class, create a new class in Visual Studio and name it: YourDomainSeriveClassName.metadata.cs. For example, our DomainService is DomainService1, so the metadata class is: DomainService1.metadata.cs.

Erase everything in the class and then replace it with the following, using the proper namespace in your project:

 

   1:  namespace SilverlightApplication6.Web
   2:  {
   3:      using System.ComponentModel.DataAnnotations;
   4:   
   5:      // The MetadataTypeAttribute identifies CustomersMetadata as the class
   6:      // that carries additional metadata for the Customers class.
   7:      [MetadataTypeAttribute(typeof(Customers.CustomersMetadata))]
   8:      public partial class Customers
   9:      {
  10:          internal sealed class CustomersMetadata
  11:          {
  12:              // Metadata classes are not meant to be instantiated.
  13:              private CustomersMetadata()
  14:              {
  15:              }
  16:              public string Address { get; set; }
  17:              public string City { get; set; }
  18:              public string CompanyName { get; set; }
  19:              public string ContactName { get; set; }
  20:              public string ContactTitle { get; set; }
  21:              public string Country { get; set; }
  22:              public string CustomerID { get; set; }
  23:              public string Fax { get; set; }
  24:              public string Phone { get; set; }
  25:              public string PostalCode { get; set; }
  26:              public string Region { get; set; }
  27:          }
  28:      }
  29:  }

As you can see this class has each of the properties of your entity (lines 16-26), now you can set them as required, specify a length, or validate with a RegEx pattern. You can also specify that a property should not be sent down to the client. Of course you can specify much more sophisticated rules, you can even write your own methods.

Let’s do a quick example on the CompanyName property, we will set it to required, set an error message to be displayed if the field is not entered as well as set a length of 32. This is done with two attributes:

   1:  [Required(ErrorMessage = "CompanyName is Required!!")]
   2:  [StringLength(32)]
   3:  public string CompanyName { get; set; }

Now when you perform databinding, RIA Services will enforce these rules for you on the client. For example, if try to edit our data in the application built in Part II, RIA Services automatically adds validation for us and passes on the error message we specified in the attribute. (Note you have to add an UpdateCustomer method to your DomainService1 class to enable editing.)

clip_image002

Enjoy!

posted on Monday, 21 June 2010 06:55:05 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Friday, 18 June 2010

In my last blog post, I showed how Telerik’s new LINQ implementation works with WCF RIA Services. In that post I built a Domain Model from the Northwind database as well as a RIA Services Domain Service. I then showed the drag and drop features of RIA Services and created a simple Silverlight application with no code. Today we are going to take that example one step further by creating some custom server side Query Methods.

A query method is just a facility to query a data source. In RIA Services, you define a query method explicitly so it can be used on the client. This is pretty straight forward with RIA Services. Let’s create a query method to query the Customer table by its primary key (CustomerID) in the database. To do this, open the project we used in the previous blog post and add this code to the DomainService class in the server project.

   1:      //This query method will return only 1 customer
   2:      [Query(IsComposable = false)]
   3:      public Customer GetCustomersByID(string customerID)
   4:      {
   5:          //must also include the Germany restriction
   6:          //to keep in sync with the GetCustomers business logic
   7:          return this.DataContext.Customers.SingleOrDefault
   8:              (c => c.CustomerID == customerID 
   9:                  && c.Country=="Germany");
  10:      }

 

This method will return one customer and you need to specify that by the attribute IsComposable=False (Line 2). Everything else is pretty basic, you have a method signature that accepts a parameter (Line 3) and a LINQ statement that filters the data by CustomerID as well as by country (lines 8-9). We are filtering by country as well because in our original business logic (in Part I) we had a GetCustomers() method that filtered all of the records by the country Germany. This new GetCustomersByID method knows nothing of the GetCustomers() method so we have to replicate that business logic here. (We have hard coded the value of Germany, in a production application, you would most likely obtain this value from a database or cookie after authentication.)

Let’s create a second query method, one that will filter the Customer data source by the ContactName field and return a collection, not a single item. We define an IQueryable collection of Customer as the return value in the method signature (Line 3) and accept a parameter. This parameter is used in our LINQ statement to filter the data source (Lines 9-10). In addition, just like the previous example, we must also filter by the country Germany; also replicate the OrderBy of our GetCustomers() method (Line 11).

   1:  //This query method will return a collection of customers
   2:  //filtered by the letters passed in on the contact name
   3:  public IQueryable<Customer> GetCustomersByLetter(string letter)
   4:  {
   5:      //must also include the Germany restriction
   6:      //to keep in sync with the GetCustomers business logic
   7:      //also since we are returning a collection, must
   8:      //respect the OrderBy as well from the business logic
   9:      return this.DataContext.Customers.Where
  10:          (c => c.ContactName.StartsWith(letter) == true
  11:              && c.Country == "Germany").OrderBy(c => c.CustomerID);
  12:  }

 

Now that we have defined two query methods, let’s wire them up to our XAML form in the Silverlight application.

In our Silverlight application, delete the grid that we had dragged onto the form in Part I. Replace it with two labels, two text boxes, two buttons and a grid (set the grid’s AutoGenerateColumns property to True.) Your XAML page should look something like this:

image

Now we have to write some code.

In the last blog post we were able to use the drag and drop features of RIA Services and not write any code. Today I will show you how to perform similar and more advanced functions with just a little bit of code. First we need two using statements in order to get working:

using SilverlightApplication6.Web;
using System.ServiceModel.DomainServices.Client;

Next we need to create a global variable for the RIA Services DomainService’s context.

   1:  //domain context for all RIA operations
   2:  private DomainService1 domainContext = new DomainService1();

 

Next we will load the grid with all of the data the first time the XAML form loads. We load the data by calling the GetCustomers() method we created in the previous blog post (we use the domainContext global variable in line 6.).

   1:  void MainPage_Loaded(object sender, RoutedEventArgs e)
   2:  {
   3:      //since we are going across the wire, must explicitly tell
   4:      //RIA Services that we are going to load data 
   5:      LoadOperation<Customer> loadOperation = 
   6:          domainContext.Load<Customer>(domainContext.GetCustomersQuery());
   7:      //the actual binding of the results, RIA takes care of the async
   8:      this.dataGrid1.ItemsSource = loadOperation.Entities;
   9:  }

 

This code does the same thing as the drag and drop did in the previous blog post, call GetCustomers() (Lines 5-6) and bind the results (line 8). Notice in the codegen on the client, RIA Services appends the word “Query” to all query methods.  In the previous blog post this was done automatically, but today we did it via code. If we run this it will give us the following view:

image

Now let’s wire up the buttons so we can perform the filters. First we will wire up the button that will search by CustomerID. That button click event will call the GetCustomerByID query method (lines 11-13) and bind the results (line 15.) We have to pass in the data the user entered in the text box, make sure in production to validate this data!

   1:  private void button1_Click(object sender, RoutedEventArgs e)
   2:  {
   3:      //disable the buttons during the async load
   4:      //to prevent the user from clicking twice while waiting
   5:      button1.IsEnabled = false;
   6:      button2.IsEnabled = false;
   7:   
   8:      //since we are going across the wire, must explicitly tell
   9:      //RIA Services that we are going to load data 
  10:      //Also here is where you pass the parameter in 
  11:      LoadOperation<Customer> loadOp = domainContext.Load
  12:          (domainContext.GetCustomersByIDQuery(textBox1.Text), 
  13:              CustomerLoadedCallback, null);
  14:      //the actual data binding, RIA takes care of the async
  15:      dataGrid1.ItemsSource = loadOp.Entities;
  16:  }

As part of the operation, RIA Services will handle the asynchronous processing for you. The problem is that users are not used to async operations, so they may try to click on the button more than once. We account for this by disabling the buttons (lines 5-6) until the operation is complete.  We have to catch the end of the async operation in a callback function and pass that in as a parameter to the operation (line 13). The callback function is here:

   1:  //callback function for when the load is complete
   2:  private void CustomerLoadedCallback(LoadOperation<Customer> loadOperation)
   3:  {
   4:      //re-enable our buttons
   5:      //if you want to display an "IsBusy" graphic
   6:      //this is where you would remove it
   7:      button1.IsEnabled = true;
   8:      button2.IsEnabled = true;
   9:  }

 

Let’s run this and test it out. If you filter by “ALFKI”, the results look like this:

image

Now let’s do the same for the the filter by ContactName. The code behind the button event is here:

   1:  private void button2_Click(object sender, RoutedEventArgs e)
   2:  {
   3:      //disable the buttons during the async load
   4:      //to prevent the user from clicking twice while waiting
   5:      button1.IsEnabled = false;
   6:      button2.IsEnabled = false;
   7:   
   8:      //since we are going across the wire, must explicitly tell
   9:      //RIA Services that we are going to load data 
  10:      //Also here is where you pass the parameter in 
  11:      LoadOperation<Customer> loadOp = domainContext.Load
  12:          (domainContext.GetCustomersByLetterQuery(textBox2.Text),
  13:              CustomerLoadedCallback, null);
  14:      //the actual data binding, RIA takes care of the async
  15:      dataGrid1.ItemsSource = loadOp.Entities;
  16:  }

Similar to the previous example, we are calling the query method, this time GetCustomersByLetter (lines 11-13) and passing in the value the user typed into the text box. When we run this and filter by all contacts that start with the letter H, it looks like this:

image

Hopefully with these two examples you can see the power of using Telerik’s new LINQ implementation and WCF RIA Services.

Enjoy!

posted on Friday, 18 June 2010 05:20:56 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Thursday, 17 June 2010

With the Q1 release of Telerik OpenAccess ORM, Telerik released a brand new LINQ Implementation and supporting Visual Entity Designer. With the upcoming Q2 release next month, we will introduce full WCF RIA Services support. If you want to get started now you can wire up the services yourself pretty easily. Let’s take a look at how to get your feet wet with RIA Services and Telerik’s LINQ implementation.

Before you get started, you will need a few things installed:

  • Visual Studio 2010
  • Silverlight 4
  • WCF RIA Services for Visual Studio 2010
  • Northwind sample database
  • Telerik OpenAccess ORM Q1 Service Pack 1 or higher

Getting Started: The Easy Stuff

Let’s create a new Silverlight application first. In the New Silverlight Application dialog, check the “Enable WCF RIA Services” checkbox. This will enable RIA Services.

image

The next step is to create a new Telerik Domain Model in the server (ASP.NET) project. I have a detailed walk through here on how to do that. We’ll create a new Domain Model by right clicking on the server project and selecting “Add” and choosing the Telerik Domain Model from the menu. Then we will map all of the tables from Northwind using the wizard. We’ll also keep the default model name of NorthwindEntityDiagrams.

image

We’re in good shape. So far if you have used the new LINQ Implementation nothing is new (or LINQ to SQL/EF for that matter.)  Now let’s add the RIA Services stuff.

Housekeeping-Adding References

Since our RIA Services support is still beta, you have to wire up a few things manually, including some references. You need to add:

  • Telerik.OpenAccess.Ria.Extensions.dll (found under “Browse: Program Files|Telerik|OpenAccess ORM|Bin)
  • System.ServiceModel.DomainServices.Server.dll
  • System.ServiceModel.DomainServices.Hosting.dll
  • System.ComponentModel.DataAnnotations.dll

image

Now we are ready to create the domain class.

Creating the Domain Class

Add a new Domain Service Class by right clicking and selecting Add|New Item and choose Domain Service Class.

image

Accept the defaults in the dialog and then we are ready to go. (Note at this time OpenAccess does not support creation of the class for metadata, but will soon, possibly even before Q2.)

image

Once you accept this dialog, a new empty class is generated.

   1:      [EnableClientAccess()]
   2:      public class DomainService1 : DomainService
   3:      {
   4:      }

 

We need to add a using statement so we can make sure our DomainService uses the OpenAccess model: using Telerik.OpenAccess;

Now change the inheritance of DomainService1 to this:

   1:  [EnableClientAccess()]
   2:  public class DomainService1 : OpenAccessDomainService<NorthwindEntityDiagrams>
   3:  {
   4:  }

Now we have one last step to create our DomainService, we have to add the CRUD methods. (In the future all of this will be done automatically for you!)

   1:  {
   2:      public IQueryable<Customer> GetCustomers() 
   3:      { 
   4:          return this.DataContext.Customers; 
   5:      }
   6:   
   7:      public void InsertCustomer(Customer c)
   8:      {
   9:          this.DataContext.Add(c);
  10:          this.DataContext.SaveChanges();
  11:      }
  12:      public void DeleteCustomer(Customer c)
  13:      {
  14:          this.DataContext.Delete(c);
  15:          this.DataContext.SaveChanges();
  16:      }

These are the methods of your DomainService. You can also add business logic here. Let’s do that with our GetCustomers() query.  I will write some business logic that filters all of the customers by the country of Germany. Of course you would have more complex business logic here, however, I just want to demonstrate the point. All clients that use this DomainService will inherit this business logic, even if you expose your service as an OData feed. Our implementation is here:

   1:  public IQueryable<Customer> GetCustomers() 
   2:  { 
   3:      return this.DataContext.Customers
   4:          .Where(c=> c.Country=="Germany")
   5:          .OrderBy(c=> c.CustomerID); 
   6:  }

 

Now you are done. Compile and let’s get cracking on a Silverlight client.

Creating the Silverlight Client

This is the easy part. We’ll use the RIA Services drag and drop features. Open MainPage.XAML in the Silverlight application and in the Data Sources window, drag and drop the Customer entity to the XAML form. (Tip: if the Data Sources window is blank or not showing up, you can manually force it to come up via the “Data” menu option on the main menu in Visual Studio.)

Once you drag and drop the entity to the form, a grid will automatically show up.

image

Now press F5 and see the application running.

image

That's it! We just created an OpenAccess based RIA Services application!

Of course there is a lot more to RIA Services than just binding a grid, however, this demonstration should show you that once you create your DomainService class, all of the RIA Services “stuff” just works for you. In future posts we will look at more RIA Services features as well as creating a query method.

Enjoy!

posted on Thursday, 17 June 2010 09:06:30 (Eastern Daylight Time, UTC-04:00)  #    Comments [3] Trackback
# Wednesday, 16 June 2010

The true power of OData is that the programming model is the same for any feed. I spend a lot of time building and demoing my own feeds- usually building an OData service around Northwind or AdventureWorks. To realize the power of OData you also need to know that you can consume public feeds. Let’s take a look at consuming the Microsoft TechEd Sessions OData Service. The TechEd service can be found here: http://odata.msteched.com/sessions.svc/

Being a RESTful service, we can drill down a little and investigate our data. I will do some URL querying and look at a list of all the speakers as well as their sessions. For example I can drill down to see all speakers named “Forte”

http://odata.msteched.com/sessions.svc/Speakers?$filter=SpeakerLastName eq 'Forte'

Or all of my sessions:

http://odata.msteched.com/sessions.svc/Speakers(1621)/Sessions

This is the beauty of OData, we don’t know how it was created, we also don’t care. All we care is if we can consume it easily. Let’s do so with an ASP.net application and the OData client for ASP.NET.

To get started, create a new ASP.NET application. In the application, right click on the References folder of the project in the Solution Explorer and select “Add Service Reference”. Put in the public URL of the TechED 2010 OData Service. This creates a proxy so you can code against the service locally and not know the difference.

image

Next set a reference to System.Data.Services.Client. This will enable us to use the OData client library and LINQ on the ASP.net client. Then drag a textbox, button, and a gridview to the ASP page. We’ll fill the gridView with the Speaker data filtered on the last name field based on what was typed in to the textbox. We accomplish this with the following code on the button click.

   1:  //set a reference to ServiceReference1 and System.Data.Services.Client
   2:  ODataTENA10Entities dat = 
   3:      new ODataTENA10Entities(new Uri("http://odata.msteched.com/sessions.svc/"));
   4:              
   5:  //LINQ statement to filter by the textbox
   6:  var result = from s in dat.Speakers
   7:                  where s.SpeakerLastName.StartsWith(TextBox1.Text.ToString())
   8:                  orderby s.SpeakerLastName
   9:                  select s; 
  10:   
  11:  //bind the results
  12:  GridView1.DataSource = result;
  13:  GridView1.DataBind();

 

Line 2 and 3 sets the data context and the LINQ statement is on lines 6-9. Line 7 is where we do the filtering based on the textbox. Pretty easy stuff.

image

Enjoy!

posted on Wednesday, 16 June 2010 07:19:13 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Tuesday, 15 June 2010

Last month I participated in a World Cup themed skit about information worker productivity at the launch of Office 2010 and SharePoint 2010 in Hong Kong. You can watch the skits here. It was a lot of fun and shows off a ton of new features in Office and Sharepoint, including PowerPivot.

Enjoy!

posted on Tuesday, 15 June 2010 04:56:51 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Monday, 14 June 2010

Last week at TechEd North America I did DEV303, Building RESTful Applications with the OData Protocol. I really enjoy doing this session since I get to code on the fly and talk about building applications. At a high level we covered:

  • What is REST, comparison to Web Services (REST is resource based, Web Services is RPC/method based)
  • What is OData, who is using it
  • When to use OData vs RIA Services (OData is for exposing data as a service across boundaries, RIA is for a VB6 style RAD application development)
  • Using WCF Data Services to build an OData Service
  • Consuming the WCF Data Service in Silverlight asynchronously –yes everyone had to suffer and watch me code
  • A Bill Gates joke
  • WCF Data Services Service Operations, Data Interceptors (Query and Change), Data paging
  • Consuming OData Services in ASP.NET (select and add, we even got to see my custom error raise)

You can download the slides and code here.

posted on Monday, 14 June 2010 20:25:55 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Thursday, 10 June 2010

Telerik won the “Best of TechEd” award in the “Best Components and Middleware” category last night at TechEd in New Orleans, LA. Our premium collection was judged as the most innovative and best value over all the other vendors.

All 200+ of the Telerik employees around the world feel honored and those of us here of course took time to celebrate on Bourbon street. Now we’re back to work and hope to live up to our customers high expectations. (If you are still at TechEd, swing by the booth and take a look at the award, we are here until 3pm today when the Expo closes.)

Thanks again to all of our customers, you make us better and we do it for you.

31691_1451994147381_1459091054_31166546_61564_n

Here are the Telerikers left standing late last night in the French Quarter in New Orleans.

posted on Thursday, 10 June 2010 12:34:20 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Tuesday, 08 June 2010

Thursday, June 17, 2010
10 Practices Every Developer Should Start Right Now

Subject: 
You must register at https://www.clicktoattend.com/invitation.aspx?code=149217 in order to be admitted to the building and attend.
Based on Caleb’s popular blog series, these are the 10 things that if you or your company starting doing today, it would drastically change the way that you write and deliver software!
Topics hit on: Object Oriented Principals, SOLID Coding, Security Concerns, Software Patterns, Automated Testing, Source Control - Branching and Merging Strategies, Continuous Integration, Agile | Scrum | XP | Lean, Team Dynamics, Continually Learning

Speaker: 
Caleb Jenkins, Proaction Mentors
As a long time community leader and former Microsoft Developer Evangelist Caleb is well known for his engaging speaking style, depth of knowledge and creative energy. Caleb is the Principal Mentor and founder of Proaction Mentors - a Software Architecture and Development Mentoring Company.
Working as a Microsoft Certified Solution Developer, Certified Trainer and .Net Architect Caleb has helped to design and implement enterprise .Net solutions for some of the largest companies in the world; Six Flags, Countrywide Mortgage, American Airlines, CGI-AMS, Dollar Thrifty Automotive Group and Sunoco Inc. to name a few.
You may also recognize Caleb from his previous work with Improving Enterprises, or from his work as an active national speaker for the International .NET Association (INETA), a Microsoft MVP for ASP.NET, a Certified Scrum Master. He’s worked as a technical editor for Wrox Press, and was recently a featured presenter on xTrain and Adobe.TV. Caleb is also the host, cameraman and editor for CommunityCast TV (CommunityCast.wordpress.com).

Date: 
Thursday, June 17, 2010

Time: 
Reception 6:00 PM , Program 6:30 PM

Location:  
Microsoft , 1290 Avenue of the Americas (the AXA building - bet. 51st/52nd Sts.) , 6th floor

Directions:
B/D/F/V to 47th-50th Sts./Rockefeller Ctr
1 to 50th St./Bway
N/R/W to 49th St./7th Ave.

posted on Tuesday, 08 June 2010 07:54:32 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] Trackback
# Monday, 07 June 2010

Yesterday Joel and I did the day long Agile precon at TechEd in New Orleans, LA. We had a great crowd and were able to keep them engaged for 8 hours. You can download the materials here.

We used an “Agile presenting” technique where we put the agenda in an “Agenda Backlog” and we reprioritized after every sprint (agenda item) and let the audience decide what we would talk about next. To our surprise the audience voted against two planned sections and we did two new sections on the fly. We talked about:

  • Agile theory and agile methodologies (XP, Scrum, FDD, DSDM, *DD, Kanban, etc)
  • Intro to Scrum
  • Agile Estimation
  • Challenges to Implementing Agile in General
  • Challenges to Implementing Agile: In the Enterprise
  • Challenges to Implementing Agile: Remote Teams
  • Tools
  • QA and Documentation

We got into a discussion on what happens when the team finishes early, do you stop the sprint, or give them more work to do. (Joel and I both go against the agile literature and give the team more work!)

We also took a few micro-breaks to rest our brain to talk about the iPhone v Android, how I buy Joel clothes, and movie quotes from the Matrix (I know Kung Fu) and What about Bob (Baby Steps).

We also recommended a book, one of my favorite management books of all time: Peopleware. For those of you non-techies reading this blog (I don’t know why!) if you manage teams, this book is also for you.

Hope to do this seminar again soon!

posted on Monday, 07 June 2010 12:04:51 (Eastern Daylight Time, UTC-04:00)  #    Comments [1] Trackback