| Comments

Just a little post to point out a hidden gem if you are a .NET developer creating a Metro style app: you can bind to anonymous types.  This came up in a discussion with a customer today that I was having and, frankly, I never tried it until then because my mind was back in Silverlight where this isn’t possible.  There may not be a tone of cases where this is valuable for you, but knowing it is there may help.

Let’s assume I have a basic class Person:

   1: public class Person
   2: {
   3:     public int Age { get; set; }
   4:     public string FirstName { get; set; }
   5:     public string Gender { get; set; }
   6: }

And in my application I have a list of that Person type that I somehow received.  In this example, I’m just hard-coding it right now.

   1: List<Person> people = new List<Person>();
   2: people.Add(new Person() { Age = 38, FirstName = "Tim", Gender = "Male" });
   3: people.Add(new Person() { Age = 9, FirstName = "Zoe", Gender = "Female" });
   4: people.Add(new Person() { Age = 5, FirstName = "Zane", Gender = "Male" });

I can then decide I want to bind to a ListView control which has a particular template:

   1: <ListView x:Name="PeopleList" Width="500" Height="300">
   2:     <ListView.ItemTemplate>
   3:         <DataTemplate>
   4:             <StackPanel Orientation="Horizontal">
   5:                 <TextBlock Text="{Binding TheName}" Margin="0,0,10,0" />
   6:                 <TextBlock Text="{Binding GuysAge}" />
   7:             </StackPanel>
   8:         </DataTemplate>
   9:     </ListView.ItemTemplate>
  10: </ListView>

Notice that I’m binding to properties (TheName and GuysAge) that don’t exist on my Person class?  In my code, I can then create a LINQ query to filter out only the “dudes” from my list and bind that result:

   1: var onlyGuys = from g in people
   2:                where g.Gender == "Male"
   3:                orderby g.FirstName descending
   4:                select new
   5:                {
   6:                    GuysAge = g.Age,
   7:                    TheName = g.FirstName,
   8:                    Gender = "Dude"
   9:                };
  10:  
  11: PeopleList.ItemsSource = onlyGuys;

The result is that my ListView now shows 2 people in the list.  Nice.

Get in the real world

Now I would probably agree that since you already have a strongly-typed class this is probably not the use case here.  It certainly might be helpful, but you already have a class (and in this example, one that you completely control so you could shape it to be what you really need).  What about those times you don’t have a class or you don’t own the type coming back?  JSON ring a bell?  Using the sample JSON response (I’m not focusing on how to retrieve data here just how to bind to it) from Twitter APIs, we can demonstrate how this might be more helpful.  Here’s the Twitter JSON data I’m referring to in this example: Twitter Mentions API.

My app wants to retrieve and bind to Twitter data but I don’t really want to have a “TwitterResponse” data type that I have to serialize in/out in my code.  The mention data is an array of mentions.  For the sake of simplicity I’ve basically put my JSON string in a file rather than confuse this sample in how to work with Twitter.  My code looks like this (assume that ‘data’ is the resulting Twitter mentions JSON string:

   1: // parse the data into a JsonArray object
   2: var mentions = JsonArray.Parse(data);
   3:  
   4: // build the query out of the mentions
   5: var qry = from m in mentions
   6:           select new
   7:           {
   8:               MentionText = m.GetObject()["text"].GetString(),
   9:               FromUser = m.GetObject()["user"].GetObject()["screen_name"].GetString(),
  10:               ProfilePic = m.GetObject()["user"].GetObject()["profile_image_url"].GetString()
  11:           };
  12:  
  13: MentionData.ItemsSource = qry;

Notice the LINQ query for creating a “new” type that I will bind to my ListView.  In my XAML I have a simple DataTemplate to demonstrate:

   1: <ListView x:Name="MentionData" Width="500" Height="300">
   2:     <ListView.ItemTemplate>
   3:         <DataTemplate>
   4:             <StackPanel>
   5:                 <TextBlock Text="{Binding FromUser}" />
   6:                 <TextBlock Text="{Binding MentionText}" TextWrapping="Wrap" />
   7:             </StackPanel>
   8:         </DataTemplate>
   9:     </ListView.ItemTemplate>
  10: </ListView>

The result is me being able to create a LINQ query and create a new anonymous type and directly bind to it.

Voila!  Perhaps you already discovered this little gem and are using it.  It is a welcome addition to the data binding story for Metro style app development with XAML and .NET!  Of course the same benefit can be had for XML data using XLINQ queries, so while this example is for JSON data, really any source data applies…it is all about that new anonymous type you create!

Hope this helps!

| Comments

We’ve update the .NET RIA Services build for May 2009.  The updated May preview can be downloaded here: .NET RIA Services May 2009.  You may have to uninstall your previous version before installing this one. 

What is .NET RIA Services?
Microsoft .NET RIA Services simplifies the traditional n-tier application pattern by bringing together the ASP.NET and Silverlight platforms. The RIA Services provides a pattern to write application logic that runs on the mid-tier and controls access to data for queries, changes and custom operations. It also provides end-to-end support for common tasks such as data validation, authentication and roles by integrating with Silverlight components on the client and ASP.NET on the mid-tier.

This update incorporates a bunch of fixes that have been reported in the RIA Services forum.  This is a good place to report issues and communicate with the dev team.  Most fixes came from the forum.  In addition, DomainService base classes now infer some data access metadata based on the model (length, required for example).  There are a few other samples that were added to this as well to note:

Also upon installing you’ll see a new project type called the Business Application Template.  Right now it looks and feels exactly like the navigation template with the Silverlight tools, but has a few defaults added, namely authentication.  You’ll see in the ASP.NET project there with a Services folder and three new files: AuthenticationService, UserInformation, UserRegistrationService.  These are all services to expose authentication and membership integration.  Running the template by default will give you a new “login” link in the upper right and clicking on that implements a new ChildWindow for login:

Biz App Login Template

Notice the "Register now” link which then uses another ChildWindow control for registration:

Biz App Register Template

Registering a new user uses the UserRegistrationService to add a new user to the system.  If you look at the UserRegistrationService you’ll see that it uses the ASP.NET Membership APIs:

   1: namespace BusinessApplication2.Web
   2: {
   3:     [EnableClientAccess]
   4:     public class UserRegistrationService : DomainService
   5:     {
   6:         // NOTE: This is a sample code to get your application started. In the production code you would 
   7:         // want to provide a mitigation against a denial of service attack by providing CAPTCHA 
   8:         // control functionality or verifying user's email address.
   9:  
  10:         public void AddUser(UserInformation user)
  11:         {
  12:             MembershipCreateStatus createStatus;
  13:  
  14:             // NOTE: ASP.NET by default uses SQL Server Express to create the user database. 
  15:             // CreateUser will fail if you do not have SQL Server Express installed.
  16:  
  17:             Membership.CreateUser(user.UserName, user.Password, user.Email, user.Question, user.Answer, true, null, out createStatus);
  18:             if (createStatus != MembershipCreateStatus.Success)
  19:             {
  20:                 throw new DomainServiceException(ErrorCodeToString(createStatus));
  21:             }
  22:         }
  23:         
  24:         // other methods exist here
  25:         // ...
  26:     }
  27: }

Because the membership APIs are provider-based, you can leverage whatever you want for your membership model and still use those APIs.  The example uses the default mechanism in ASP.NET.

Download the updated RIA Services bits today and take a look at the new template for integrating with the various ASP.NET providers.  Thanks for the continued feedback and keep it coming!

| Comments

A while back I pondered doing a “live” debug session with people who were/are working with Silverlight 2 and data access via services, etc.  I really like a live concept because it allows people to ask real questions and feels more conversational than a one-way presentation.  After some consideration, I’m not sure I could quite guarantee the environment I was looking for to accomplish this type of style.

confused man imageSo as a second best, I’ve set up a webcast: Troubleshooting Silverlight Data Access.  I hope to keep the question channel open during the webcast though and answer as many questions as possible.  I’ve seen many questions on forums, through emails, and all over the interwebs about people hitting certain pitfalls with Silverlight and data access.  Most of these are common scenarios and you need just a bit of “a-ha!” help to get you over the confusion stump.  That’s my aim.  I have set aside an hour (would have liked to do it sooner, but just time doesn’t permit right now) to tackle the most common things I’m seeing with data and Silverlight.  I’ll create the scenarios that get you stuck and show you what I do to help get you un-stuck from those moments.  Stop scratching your head any longer!

UPDATE: The webcast is now available online for playback.

We’ll look at tools you can use, how you can dig deeper into error messages, working with different types of data, etc.  I want to help!  Please leave your questions here on this blog post as a comment so that I can be sure to address the scenarios.  This isn’t a 1:1 debug session, so it will be hard to tackle the “hey, I’ve got this service from my AS/400 server exposed as a fitzer-valve service bus, which is able to be called from my Java front-end but doesn’t work in Silverlight: why not Tim?" questions, but I hope to help get you along the path of what to look for and to avoid the common mistakes.

Sound good?  I’m looking forward to it.  Again, please leave comments on this post so we can have the best possible session.  You can register for the webcast here.  I look forward to our time together :-).

Related Posts:


This work is licensed under a Creative Commons Attribution By license.

| Comments

In a previous post, I wrote about some samples of calling various types of services from Silverlight 2.  In the code, I was using constructors in my ASMX and WCF services with specifying a binding type and endpoint address.

It was called out to me that in other demonstrations, people did not use this construct.  While the method I demonstrated works (explicitly specifying the binding and endpoint), in some cases it may not be necessary.  One such case would be if you only have one endpoint and it is basicHttpBinding.

The error in my code/instructions was about changing the binding information in web.config.  The information is correct, however I wasn't clear on when/what you needed to do.  For example, the default information in web.config for the Silverlight project created for you uses wsHttpBinding.  If you add a service reference in your Silverlight project PRIOR to changing that binding information, your generated proxy will require you to specify a binding and endpoint as Silverlight doesn't support wsHttpBinding and it would be trying to use that as a default method.

So the appropriate way is to change the binding type in your web.config FIRST.  Then generate the service reference in your Silverlight application and your proxy code generated will then allow you to new up the service using:

WcfServiceClient wcf = new WcfServiceClient();

for both WCF and ASMX services...which is probably more familiar to most web developers implementing services in their applications.

Again, EITHER way is fine.  Providing no information in the constructor will use the default binding/endpoint information for that service, and if it isn't supported, you'll get a nasty exception.  Whether or not it is best practice to always explicitly call it out in your code is up to you.  I'd argue it is.  In looking at the code above do you know what binding/endpoint is being used at the time of the service call?  No.  You could make some reasonable assumptions (hey, I'm in Silverlight and I know I must use basicHttpBinding), but for maintainability, maybe someone else coming to the code doesn't have the same understanding.

To each his own.  Either way, I hope this clarifies and I've updated my post with the note about this as well.

| Comments

If you are like me, you probably create a lot of projects in Visual Studio that end up getting thrown away and are intended just to test out a theory you have, double-check yourself when you are going mad because you can't find a bug, testing out something you read on a blog post, whatever.

Most of the projects I create are web projects.  I've started to adopt the "_Delete" mechanism to help me identify what I can truly delete in my folders later.  But is not the point here.  One thing that I do when creating web projects is use the Empty Web Site template:

I choose this template because it is the cleanest...it's actually what it says it is: empty.  It allows me to really isolate things as I'm the one adding things in, not the IDE.  So I usually follow that up with a new WebForm to get an ASP.NET page in there.  I write some code then CTRL+F5 it to run.  The first thing I hit is a build error.  Can you guess what it is?

Here's the thing.  When you choose the Empty Web Site template, you literally get nothing...no web.config, no default pages, no references, nada.  Like I said, it is what it is: empty.  But herein lies the problem.  The WebForm item template doesn't know that.  The WebForm item template is shared with all the web template types, which generally would be fine.  Let's do some digging to find out why I get a build error.

The WebForm item template is located in %ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Web\1033\WebForm.zip.  This file contains the WebForm.aspx and code beside templates.  If you look at the CodeBeside.cs template within there you will see this line:

$if$ ($targetframeworkversion$ == 3.5)using System.Linq;

And there is the problem!  When I create a new web site, i'm using the .NET Framework 3.5 setting:

instead of any other target.  It makes sense because I'm doing 3.5 stuff anyway and I don't want to have to change it later.  But the problem is that the WebForm template now thinks that I already have web.config settings for LINQ, a reference, etc. and that is why I can't run...no references to System.Linq assemblies anywhere.

It's quite annoying for me, but I would imagine not most.  In talking with some product team folks, and I concur, people who choose the empty template are usually likely going to know what is up and make whatever changes needed.  Fair enough, but still slightly annoying only because I keep forgetting about it!

So since I find myself removing those using statements a lot, I decided to just change the template.  This, of course, is completely going to get overwritten any update in the future.  But for me, I think it made sense to remove them rather than to assume that I, the developer, will always be using LINQ in my web forms...which I'm not.  I'll choose to add it back in when I need!  So I simply removed the $if$ statements and I'm good to go.  I wish there was a way to say $if$ (3.5 && !empty)using System.Linq, but I'm okay with my minor change for me.

Anyhow, I thought I'd share this useless piece of knowledge as you might have come across it while checking out new development, tinkering with ASP.NET, creating shell web hosts, etc.  Hope it helps.