Why Can't You Code?
The highest form of ignorance is when you reject something you don't know anything about.
The highest form of ignorance is when you reject something you don't know anything about.
Nov 25th
These are the steps I had to go through to migrate a Silverlight application that was running on the .NET RIA Services preview released in July 09, to the new WCF RIA Services released during PDC 09:
<system.webServer>
...
<handlers>
...
<add name="DataService" verb="GET,POST" path="DataService.axd" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</handlers>
</system.webServer>
<httpHandlers> ... <add path="DataService.axd" verb="GET,POST" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" /> </httpHandlers>
.NET 3.5:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpModules>
<add name="DomainServiceModule" type="System.Web.Ria.Services.DomainServiceHttpModule, System.Web.Ria,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
</system.web>
<system.webServer>
<modules>
<add name="DomainServiceModule" preCondition="managedHandler" type="System.Web.Ria.Services.DomainServiceHttpModule, System.Web.Ria,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35"/>
</modules>
<system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
</configuration>
.NET 4.0:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpModules>
<add name="DomainServiceModule" type="System.Web.Ria.Services.DomainServiceHttpModule, System.Web.Ria, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpModules>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="DomainServiceModule" preCondition="managedHandler"
type="System.Web.Ria.Services.DomainServiceHttpModule, System.Web.Ria, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
</configuration>
using System.Web.DomainServices.LinqToEntities;
To this:
using System.Web.DomainServices.Providers;
Everywhere.
Now, your Web application should build, but you may still get this error while building the actual Silverlight application:
Error 5 The "CreateRiaClientFilesTask" task failed unexpectedly. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: The AutoGenerateField property has not been set. Use the GetAutoGenerateField method to get the value. at System.ComponentModel.DataAnnotations.DisplayAttribute.get_AutoGenerateField()
In my case, this was a problem with the System.ComponentModel.DataAnnotations.dll reference. Remove it and re-add it from the Global Assembly Cache.
Replace System.Windows.Ria.Controls with System.Windows.Controls.Ria in your namespace declarations in the header of the XAML file. Here’s how the old ones look:
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls" xmlns:System_Windows_Data="clr-namespace:System.Windows.Data;assembly=System.Windows.Ria.Controls"
<Application.ApplicationLifetimeObjects>
<app:WebContext>
<app:WebContext.Authentication>
<appsvc:FormsAuthentication/>
<!--<appsvc:WindowsAuthentication/>-->
</app:WebContext.Authentication>
</app:WebContext>
</Application.ApplicationLifetimeObjects>
With some luck, your project should be migrated to WCF RIA Services now. These were the steps I needed to get mine working.
Additional breaking changes in the new release can be found here.
Good luck!
Nov 25th
While working on a Silverlight application. I discovered that all the dates displayed in my DataGrid were skewed by a few hours from the real date stored in the database. Upon a closer look I noticed this skew was closely correlated to the time difference between the server’s time zone and the UTC date.
I needed my Silverlight application to display and use the exact same dates as the database regardless of the time zone my users were in.
Apparently, there’s a little known bug “feature” in the latest RIA Services Beta for Silverlight that involves dates:
RIA uses JSON to send data across the wire, and the Microsoft JSON serializers always serialize dates as UTC.
Dates retrieved from the database always seem to come up as DateTimeKind.Unspecified, meaning that the serializer will take a guess and treat them as local dates (in the server’s local time zone) and convert them to UTC time before sending out on the wire.
There’s an overridable property in the DomainService class called UsesUtcDateTimes which should in theory make the serializer leave your dates alone by treating them as UTC – which is still not ideal, but it means it won’t change them further – the property, however, currently doesn’t do anything.
The gotcha here is that the original time zone of the date is lost on the wire. It’s not sent along with the date so there’s no way you could determine, on the client, what time zone the date was in originally!
Example: if the server’s timezone is GMT+1, a date of December 21, 2012 12:21 PM will be converted to the UTC (GMT+0) date of December 21, 2012 11:21 AM before being sent out!
The Silverlight application will now display the UTC date of December 21, 2012 11:21 AM instead of the expected date from the database.
… is to mimic the behavior of the currently un-implemented UsesUtcDateTimes property and fool the serializer into thinking all of your dates are already in UTC so it doesn’t mess with them. Thanks to partial classes, you can do this.
Create new partial classes for each of your RIA Data Classes that hold DateTime values and override the On(DateTimePropertyName)Changed() methods like the following:
public partial class MyDataClass
{
partial void OnDateChanged()
{
_Date = DateTime.SpecifyKind(_Date, DateTimeKind.Utc);
}
partial void OnOtherDateChanged()
{
_OtherDate = DateTime.SpecifyKind(_OtherDate, DateTimeKind.Utc);
}
}
(Notice the partial keyword on the methods as well, not just on the class.)
.. is to pass the original time zone, as a property, along with the UTC DateTime across the wire, and then re-apply the time zone to it on the client before using it.
I’m hoping for a future RIA Services release to address this issue better, and perhaps pass the time zone across by itself.
Nov 18th
Linq-to-SQL is our ORM of choice until the Entity Framework matures – and in our projects we use a factory method to get a new reference to our database data context. Here’s what I mean:
var db = Database.GetDataContext();
The DataContext class implements IDisposable, which means that (usually) it should be wrapped in an using block:
using (var db = Database.GetDataContext())
{
... code that uses the database here ...
}
We discovered that we frequently have one liners inside the using block, and in most of these cases, we just return some quick value from the database.
This made me think if there was something I could do about this to make it into a more compact construct. The result is an extension method that lets me do all of this on one line, while also taking care of object disposal.
Introducing <IDisposable>.Using() extension method:
int userCount = Database.GetDataContext().Using(db => db.Users.Count()); // get a quick user count
Of course, this applies to any object implementing IDisposable, not just Linq-to-SQL – so it has lots of possible uses. Here’s another example:
foreach (string file in Directory.GetFiles(@"C:\TextFiles", "*.txt"))
{
string firstLine = new StreamReader(file).Using(f => f.ReadLine());
Console.WriteLine(firstLine);
}
We’re reading the first line of every file and making sure the file gets closed immediately afterwards. The extension method takes care of disposing the StreamReader, and allows you to focus on the functionality rather than the implementation.
That’s what functional programming is all about!
Extension method follows:
public static class DisposableExtensions
{
/// <summary>
/// Runs a delegate on the specified <see cref="IDisposable"/> and returns its value.
/// </summary>
/// <typeparam name="T">Type of the object implementing <see cref="IDisposable"/></typeparam>
/// <typeparam name="TOut">The type of the return value.</typeparam>
/// <param name="disposable">The object implementing <see cref="IDisposable"/>.</param>
/// <param name="func">A delegate that takes <paramref name="disposable"/> as a parameter and returns a value.</param>
/// <returns>Value returned by <paramref name="func"/> delegate.</returns>
public static TOut Using<T, TOut>(this T disposable, Func<T, TOut> func) where T : IDisposable
{
using (disposable)
{
return func(disposable);
}
}
/// <summary>
/// Runs a delegate on the specified <see cref="IDisposable"/> and does not return anything.
/// </summary>
/// <typeparam name="T">Type of the object implementing <see cref="IDisposable"/></typeparam>
/// <param name="disposable">The object implementing <see cref="IDisposable"/>.</param>
/// <param name="action">A delegate that takes <paramref name="disposable"/> as a parameter.</param>
public static void Using<T>(this T disposable, Action<T> action) where T : IDisposable
{
using (disposable)
{
action(disposable);
}
}
}
Nov 14th
Although every neuron in my brain is trying to fight me from writing this post, I realized that in our company, the websites we produce are not necessarily for computer literate people.
A huge chunk of our visitors still use IE6 and we need to provide them with a decent experience. We do have some plans to at least show some alert to these users telling them that their browser is outdated and they need to upgrade. A nice script to help us do that would be the one from http://code.google.com/p/ie6-upgrade-warning/, pictured below:
If, like us, you still need to support IE6, you can use the incredible Spoon.net Browser Sandbox to launch IE6, or any other browser straight from their web page, after installing a small plugin. You can then just start any app right from the browser without needing to install it, one click and it just starts right up!
We find this tool invaluable to us as web developers.
Our Wordpress theme already complains about IE6 by default, so that’s a step in the right direction. I wouldn’t even have noticed that if it weren’t for Spoon.net.
Here’s a screenshot of Internet Explorer 6 running on Windows 7:
Nov 13th
I’ve seen various ways of handling the lack of support for an index in the foreach () construct over the years.
By far the most used strategy is to declare an index yourself and increment it at the end of every loop iteration. Let me demonstrate:
static void Main(string[] args)
{
var range = Enumerable.Range(0, 100);
int index = 0;
foreach (int number in range)
{
Console.WriteLine(index + " " + number);
index++;
}
// Output:
// 0 0
// 1 1
// 2 2
}
However, this becomes more of a problem if the code inside your loop conditionally breaks out of the loop, or if you need to use continue; to end the iteration early, requiring you to keep track of all of your exit points.
static void Main(string[] args)
{
var range = Enumerable.Range(0, 100);
int index = 0;
foreach (int number in range)
{
if (number < 50) continue; // <- oops, the index will be out of sync now. shouldn't have forgotten to increment it
Console.WriteLine(index + " " + number);
index ++;
}
// Output:
// 0 50 (should be 50 50 – remember, this would be the 50th loop iteration, but it was ended early, before the index got a chance to be incremented)
// 1 51 (should be 51 51)
// 2 52 (should be 52 52)
}
You can get rid of these problems with a little known overload for the Linq Enumerable.Select() method which will supply the much needed index. Behold the uglyness:
static void Main(string[] args)
{
var range = Enumerable.Range(0, 100);
foreach (var c in range.Select((value, index) => new { Index = index, Value = value }))
{
if (c.Value < 50) continue; // <- the index will still be correct despite the early exit
Console.WriteLine(c.Index + " " + c.Value);
}
// Output:
// 50 50 (correct)
// 51 51
// 52 52
}
Damn code, you scary! (if you don’t want to get ate, see the elegant solution right below the video)
Being someone who doesn’t particularly enjoy uglyness, I decided to wrap this into an extension method for IEnumerable<T>, so I can write this beautiful beautiful code below:
static void Main(string[] args)
{
var range = Enumerable.Range(0, 100);
foreach (var c in range.WithIndex())
{
if (c.Index % 2 == 0) continue; // <- the index will still be correct despite the early exit
Console.WriteLine(c.Index + " " + c.Value);
}
}
You want your index to go backwards? Easy, an overload does all the dirty work, you can specify the value to start at and the step as parameters. The step can even be negative if you want!
foreach (var c in range.WithIndex(range.Count(), –1)) { }
Here’s the code listing for the extension method, enjoy:
public static class EnumerableWithIndexExtension
{
public static IEnumerable<ValueWithIndex<T>> WithIndex<T>(this IEnumerable<T> enumerable)
{
return enumerable.Select((value, index) => new ValueWithIndex<T>(value, index));
}
public static IEnumerable<ValueWithIndex<T>> WithIndex<T>(this IEnumerable<T> enumerable, int startAt, int step)
{
return enumerable.Select((value, index) => new ValueWithIndex<T>(value, startAt + index * step));
}
public class ValueWithIndex<T>
{
public int Index { get; private set; }
public T Value { get; private set; }
public ValueWithIndex(T value, int index)
{
Value = value;
Index = index;
}
}
}
Nov 12th
The System.Lazy<T> type in the new .NET 4.0 framework came to my attention recently. This type is not at all revolutionary. In fact, everyone could have written it themselves in under 10 lines of code going as far back as the .NET 2.0 framework.
Some less experienced programmers won’t realize however, that deferring the call to a delegate could have nasty side effects.
Consider the following code snippet:
static void Main(string[] args)
{
List<Lazy<string>> lazyInit = new List<Lazy<string>>();
for (char letter = 'A'; letter <= 'Z'; letter++)
{
var lazy = new Lazy<string>(() => letter.ToString());
lazyInit.Add(lazy);
}
foreach (var lazy in lazyInit)
{
Console.Write(lazy.Value);
}
Console.ReadLine();
}
The code is pretty straight forward, but what gets printed here? Would you think it’s the alphabet? You would be very wrong.
The output is exactly ‘ZZZZZZZZZZZZZZZZZZZZZZZZZ’. Go ahead, run it yourself if you don’t trust me.
To understand why this happens, you need to understand how closures work.
In the constructor to the Lazy<> class, you’re passing in a delegate, in the form of a lambda. This delegate captures the letter variable (attention, not its value at the time of the call, but the variable as a whole) and creates a closure class around it behind the scenes. This may be counter-intuitive to the average programmer. For further information on what happens behind the scenes with captured variables and closures, read this great post by Marc Gravell.
This is not specific behavior of the new Lazy<T> class, it’s what happens every time a delegate is stored for deferred execution.
If you rewrite the code without deferred execution, you’ll see that the problem doesn’t manifest itself:
static void Main(string[] args)
{
for (char letter = 'A'; letter <= 'Z'; letter++)
{
var lazy = new Lazy<string>(() => letter.ToString());
Console.Write(lazy.Value);
}
Console.ReadLine();
}
// Output: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Same delegate is being used, but it is executed immediately. The output is now the complete English alphabet, as you would expect.
This isn’t very useful however, We’ve completely thrown away the advantages of the Lazy<T> class and we might as well not be using it.
So, how can we fix it? We need to use an intermediary variable inside the body of the for loop that is simply a copy of the outer variable. The inner variable’s scope is unique to each loop iteration, so it matters a whole lot where you define your variables.
Fixed code:
static void Main(string[] args)
{
List<Lazy<string>> lazyInit = new List<Lazy<string>>();
// char letter2; // <- for the sake of exercise, uncomment this line and remove the ‘char’ keyword from the initialization of the letter2 variable inside the for loop below. the ‘bug’ will manifest itself again
for (char letter = 'A'; letter <= 'Z'; letter++)
{
char letter2 = letter; // value re-captured in inner block (remove ‘char’ keyword and uncomment line above to see the ‘bug’ manifest itself again)
var lazy = new Lazy<string>(() => letter2.ToString());
lazyInit.Add(lazy);
}
foreach (var lazy in lazyInit)
{
Console.Write(lazy.Value);
}
Console.ReadLine();
}
One tool that can automatically check for this condition so you can avoid headaches later is JetBrain’s Resharper. With Resharper installed, you’d see a warning underneath () => letter.ToString() which spells ‘Access to modified closure’ and suggests the same fix I described in this blog post.
If anyone’s interested in seeing how the same Lazy<T> class could be implemented in .NET 2.0 and up, leave a comment and I’ll post it here!
Nov 12th