 |
|
 |
|
|
Where is my Astoria Client for Silverlight 2? |
|
Andy's Blog
|
By Andy Beaulieu on
4/25/2008 9:04 AM
|
|
|
|
According to this post from the Astoria Team Blog, it looks like we won't have a new Astoria (ADO.NET Data Services) client for Silverlight 2 until SL2 Beta 2 is released (perhaps May 2008?)
Many of the data demos for Silverlight 2 have so far used LINQ to SQL for the data access layer. These demos involve creating a LINQ to SQL data model (using a nice drag/drop editor), and then exposing that model through a web service by manually coding a WCF Web Service or .asmx Service.
Don't get me wrong, this is a pretty rapid development method... but what if you didn't need to code the web service for basic CRUD operations and queries on your data? What if it were all exposed for you and you could use LINQ to access the data from the Silverlight client?
This automatic service layer is just one of the advantages that ADO.NET Data Services (Astoria) provides, and since Silverlight 2 has much better support for Data Entry controls, the combination of SL and Astoria should provide a powerful rapid development environment!
|
 |
|
Comments (2)
|
|
|
|
Silverlight 2 for Data Apps |
|
Andy's Blog
|
By Andy Beaulieu on
4/6/2008 5:59 PM
|
|
|
|
Thanks to everyone who attended my "Silverlight 2 for Data Applications" talk at Code Camp 9 in Waltham, MA on 4/5/2008! And a big thanks to Chris Bowen and Chris Pels for their hard work organizing this great event time after time. I had a great crowd for my talk, standing room only, and as promised I have some goodies for all:
First, even if you couldn't make it to Code Camp for my talk, I have created a screen cast that walks through the demos. Just click the image below to launch the video:
I also have the Beers Demo Application and Slide Deck available:
DOWNLOAD THE DEMO CODE
DOWNLOAD THE SLIDE DECK (PPT)
Summary of the Presentation
In this talk, I walked through a mult-tier Silverlight Application with the following architecture:
1. A Silverlight 2 Client containing a Master/Detail scenario
2. A WCF Web Service providing communication to the Silverlight Client
3. A Data Accesss Layer using LINQ to SQL
4. A Simple SQL Server Database with (Mmmmm) Beer Data.
We explored how to use LINQ to SQL to expose our database entities through a WCF Web Service, and how Silverlight 2 can communicate with the web service. We also explored formatting a DataGrid and creating User Controls with DataBound UI Elements, and how to do basic CRUD operations from the Silverlight client back to the Web Service.
Here is a shot of the completed demo (download the source code above):

|
 |
|
Comments (3)
|
|
|
|
LINQ to SQL CRUD |
|
Andy's Blog
|
By Andy Beaulieu on
3/28/2008 12:42 PM
|
|
|
|
I'm seeing a lot of buzz around LINQ to SQL lately and how it can help to quickly create a Silverlight 2 data app.
I'll be giving a talk around this at the upcoming Code Camp 9 in Waltham, MA, and I wanted to share how I am doing basic CRUD operations in LINQ to SQL, as I've seen this question come up a few times.
You may remember my Silverlight 1.1 Alpha demo app, "Andy's Fridge." I'll be using a similar Beer Database which has a very simple schema containing Beers and Brewers like so:

It's important to note that the RowVersionId columns in the diagram are Timestamp columns. This will allow LINQ to SQL to generate more efficient Update statements, based on the unique Row Id (timestamp) instead of Where clauses with lots of logical "AND's" for each original value.
So, given that schema is like that above, our CRUD operations for the Beer entity would exist in our web service like so:
public class BeerService : IBeerService
{
public List<Beer> GetAllBeers()
{
DataClassesDataContext db = new DataClassesDataContext();
var beers = from b in db.Beers
orderby b.BeerName
select b;
return beers.ToList<Beer>();
}
public void SaveBeer(Beer beer)
{
DataClassesDataContext db = new DataClassesDataContext();
if (beer.BeerId > 0)
{
// this is an update
db.Beers.Attach(beer, true);
}
else
{
// this is an insert
db.Beers.InsertOnSubmit(beer);
}
db.SubmitChanges();
}
public void DeleteBeer(Beer beer)
{
DataClassesDataContext db = new DataClassesDataContext();
db.Beers.Attach(beer, false);
db.Beers.DeleteOnSubmit(beer);
db.SubmitChanges();
}
}
Note that I piggybacked the SaveBeer method to do either an Insert operation or Update operation, based on whether or not a primary key is available in the passed entity.
I guess until ADO.NET Data Services (Astoria) and the Entity Framework are officially available, we will have to settle with LINQ to SQL for Data Access! But I don't think we will be waiting long :)
What can we look forward to with Astoria and the EF?
- no need to write tedious web service methods for CRUD operations like shown above
- serialization of Parent and Child records (LINQ to SQL cannot pass related child records across the wire with parent rows)
- Access to other Database Providers other than SQL Server.
- The ability to flexibly map Conceptual model elements such as class properties to Physical columns in the database (LINQ to SQL provides only a 1-to-1 mapping)
|
 |
|
Comments (2)
|
|
|
|
When in Beta, Not all Locales are Created Equal? |
|
Andy's Blog
|
By Andy Beaulieu on
3/18/2008 4:11 PM
|
|
|
|
I ran into an odd Silverlight Beta 1 problem after releasing the latest version of "Sort the Foobars" - the game worked fine for me in testing, but shortly after putting it up on this site I received several comments about it crashing in different locales, like Russian and French (you can see those comments here)
The exception looked something like this:
Silverlight error message ErrorCode: 4002 ErrorType: ManagedRuntimeError Message: System.Exception: Défaillance irrémédiable (Error 0x1709. Debugging resource strings are unavailable. See http://go.microsoft.com/fwlink/?linkid=106663&Version=2.0.30226.2&File=mscorrc.dll&Key=0x1709 0x8000FFFF (E_UNEXPECTED)) at MS.Internal.XcpImports.CheckHResult(UInt32 hr) at MS.Internal.XcpImports.SetValue(IntPtr oPtr, UInt32 iPropertyId, String s) at MS.Internal.XcpImports.SetValue(IntPtr oPtr, UInt32 iPropertyId, Object obj) at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean isSetByStyle, Boolean isSetByBuiltInStyle) at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
So the first question is, how do you set up your development machine to test the other locales? It turns out this part is easy - go to Control Panel/Regional Settings and set the language to, say Russian.
After doing that, I found that this was the line of code that was dying:
this.SetValue(Canvas.LeftProperty, X)
Not much to that… “this” is a UserControl and (here is the key part!) “X” is a float. So apparently, setting the left property to a float is bad outside of en-us J
I added a Convert.ToDouble(X) in there and it seems happy now:
this.SetValue(Canvas.LeftProperty, Convert.ToDouble(X))
So the moral of the story? I think that the different behavior is hopefully because this is still a Beta release of Silverlight... Because we would really hope for consistent behavior between Locales! But on the other hand, you still need to be careful with setting Dependency properties to types that they aren't suited for!
|
 |
|
Comments (3)
|
|
|
|
Calling an .asmx Web Service in Silverlight 2 |
|
Andy's Blog
|
By Andy Beaulieu on
3/17/2008 6:14 PM
|
|
|
|
I wanted to share a couple of tips for calling web services from a Silverlight client.
If you are just beginning to useWeb Services from a Silverlight 2 Client, Tim Heuer has a good introductory post here.
Getting the Binding Url A lot of the web service samples will show the binding created with a hardcoded Uri such as this:
WebServiceSoapClient webSvc = new WebServiceSoapClient(binding, new System.ServiceModel.EndpointAddress("http://localhost/MyWebService.asmx"));
The problem being of course that the EndpointAddress is hardcoded to localhost, and you may not know what server you will ultimately deploy to. You could add the Uri as a configuration setting, but there is a more flexible way.
Chances are, your web service is hosted on the same web server that your Silverlight application downloads from. So when you create your Web Service binding, you can determine the Url for you service to bind to based on the current browser Uri:
public static string GetUrlForResource(string resourcePage) { string webUrl = System.Windows.Browser.HtmlPage.Document.DocumentUri.ToString();
string containerPage = webUrl.Substring(webUrl.LastIndexOf("/") + 1);
webUrl = webUrl.Replace(containerPage, resourcePage);
return webUrl;
}
... So the method above, when passed a resource string such as "MyWebService.asmx" will return a full Url for a page that is in the same virtual directory as the silverlight app.
When binding, you can then use this utility method like so:
// get the full url of the Web Service string webServiceUrl = GetUrlForResource("WebService.asmx");
System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();
WebServiceSoapClient webSvc = new WebServiceSoapClient(binding, new System.ServiceModel.EndpointAddress(webServiceUrl));
webSvc.HelloWorldCompleted += new EventHandler<HelloWorldCompletedEventArgs>(webSvc_HelloWorldCompleted); webSvc.HelloWorldAsync();
Keep an Eye on MaxReceivedMessageSize If your web service is returning a lot of data, you may blow out the default max message size for a return. If this happens you will get an exception like so:
An exception of type 'System.ServiceModel.CommunicationException' occurred in System.ServiceModel.dll but was not handled in user code
Additional information: [MaxReceivedMessageSizeExceeded]
To remedy this, you can up the MaxReceivedMessageSize attribute of the binding like so:
System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();
// if you are getting a LOT of data back, you will need to up Message Size binding.MaxReceivedMessageSize = int.MaxValue;
|
 |
|
Comments (8)
|
|
|
|
|
|
|
Tunnel Trouble - Silverlight 2 Beta 1 Scroller |
|
Andy's Blog
|
By Andy Beaulieu on
3/6/2008 8:08 PM
|
|
|
|
I am sitting in on a presentation at MIX, “Silverlight as a Gaming Platform” by Joel Neubeck and Scott McAndrew of TerraLever. They created a very cool scrolling puzzle game using Silverlight 2 Beta 1, named Tunnel Trouble, which is currently available on Miniclip.com. Miniclip is probably the most popular casual games site on the internet. I don't think Miniclip is allowing the game to be found through their search function yet, so I'm not even sure they will keep the game accessible...
The game is a tile-based scroller inspired by Valve’s Portal (part of the Orange Box), in which a beaver needs to rescue his children in an underground maze. The designers used TileStudio to design the tile-based levels. Very cool!
|
 |
|
Comments (0)
|
|
|
|
Using HitTest Method in Silverlight 2 for Collision Detection |
|
Andy's Blog
|
By Andy Beaulieu on
3/6/2008 12:03 PM
|
|
|
|
UPDATE 7/10/2009: See THIS BLOG POST regarding Silverlight 3 RTW, which demonstrates collision detection between XAML and Image elements.
Prior to Silverlight 2.0 Beta 1, there was no method provided in the framework for determining if two UI elements were colliding. So if you wanted collision testing, you had to pretty much brew up your own. But there is now a FindElementsInHostCoordinates method provided on the VisualTreeHelper class. This method returns a list of elements that intersect with a Point or Rect. Not particularly helpful out of the box, and also not a very fast operation, but using this new method we can do some fair collision detection.
[TRY THE DEMO] [DOWNLOAD SOURCE]
If you try the demo above, you can use the mouse to move the ship around the asteroid. Notice that a collision is only detected when the ship's outer path element collides with the asteroid's path element.
This was done using the method below, which can be used to determine if two UI Elements are colliding. Remember that the FindElementsInHostCoordinates method is very slow so we always want to do a quick Rectangle Intersect collision test first before doing a per-pixel Hit Test. Once the intersection rectangle is found, the code simply loops through pixel-by-pixel to see if both elements in question share a Hit Test on the same x,y pixel…
private bool CheckCollision(FrameworkElement control1, FrameworkElement controlElem1, FrameworkElement control2, FrameworkElement controlElem2)
{
// first see if sprite rectangles collide
Rect rect1 = UserControlBounds(control1);
Rect rect2 = UserControlBounds(control2);
rect1.Intersect(rect2);
if (rect1 == Rect.Empty)
{
// no collision - GET OUT!
return false;
}
else
{
bool bCollision = false;
Point ptCheck = new Point();
// now we do a more accurate pixel hit test
for (int x = Convert.ToInt32(rect1.X); x < Convert.ToInt32(rect1.X + rect1.Width); x++)
{
for (int y = Convert.ToInt32(rect1.Y); y < Convert.ToInt32(rect1.Y + rect1.Height); y++)
{
ptCheck.X = x;
ptCheck.Y = y;
List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(ptCheck, control1) as List<UIElement>;
if (hits.Contains(controlElem1))
{
// we have a hit on the first control elem, now see if the second elem has a similar hit
List<UIElement> hits2 = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(ptCheck, control2) as List<UIElement>;
if (hits2.Contains(controlElem2))
{
bCollision = true;
break;
}
}
}
if (bCollision) break;
}
return bCollision;
}
}
|
 |
|
Comments (18)
|
|
|
|
|
 |
|
 |
|
|