Learning Curve

Apr 06

Hey, Shadow Ed! Good to see you again.  (Taken with Instagram at Lucky Labrador Beer Hall)

Hey, Shadow Ed! Good to see you again. (Taken with Instagram at Lucky Labrador Beer Hall)

Feb 24

WCF Won’t Serialize an Expression Tree

Of course WCF won’t serialize an expression tree. Why would you attempt to do that?

It started post-authentication as a WCF error in Silverlight while trying to get the User object using WCF RIA.

private void AuthenticateUser()
{
   WebContext.Current.Authentication.LoadUser(ApplicationUserLoaded, null);
}

The error was cryptic:

System.ServiceModel.DomainServices.Client.DomainOperationException: Load operation failed for query ‘GetUser’. The remote server returned an error: NotFound. —-> …

Odd, when I debug, I can see the User is returnable:

public User GetUser()
{
    var user = ServiceContext.Wrap().User;
    return user;
}

So somewhere after I return the User, WCF pukes. By turning on “Break for all exceptions” I get a little more detail:

Type 'WorkDrivers.Models.User+<GetRoles>d__2' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.

WAT!? What kind of property is WorkDrivers.Models.User+<GetRoles>d__2. I have a GetRoles method…

Staring at the code didn’t help. How could GetRoles cause a serialization error? After a night’s sleep and a cup of strong coffee, the answer yielded to me:

Roles = GetRoles(value);

private static IEnumerable<string> GetRoles(...)

I set Roles to an IEnumerable<string>, and not just any IEnumerable<string>, a method with a bunch of yield return statements inside. I was actually setting it to an expression tree behaving as an enumerable of strings. Of course that won’t be properly serialized by WCF.

The fix was easy:

Roles = GetRoles(value).ToArray();

Jan 10

Work this week has been 2 steps forward, 1 step back. I left work Friday (Jan 6th) thinking we got a lot done only to return Monday (Jan 9th) and see much of it rejected. Finally fixed the rejections this afternoon. It&#8217;s a bit of a treadmill.

Work this week has been 2 steps forward, 1 step back. I left work Friday (Jan 6th) thinking we got a lot done only to return Monday (Jan 9th) and see much of it rejected. Finally fixed the rejections this afternoon. It’s a bit of a treadmill.

Jan 04

LINQ makes 3 year old C# look terrible

I ran across this pretty nugget today:

var result = new List<ModifierBase>(serviceProcedure.ProgrammaticModifiers.Length);

foreach (ModifierBase modifierBase in serviceProcedure.ProgrammaticModifiers)
{
    result.Add(modifierBase);
}

return result;

ReSharper helps me resolve this to:

return serviceProcedure.ProgrammaticModifiers.ToList();

Jun 24

irondavy:

Reading @waxpancake’s story today, my biggest question was: what will the new cover be? I certainly have no association with Mr. Baio or the project, but it seemed like a nice opportunity to play with pixels in a totally different aesthetic than I normally do. So: here’s a set of exercises.
(Edit: and just to be clear the top right one is a wholly original drawing! Based on around 6 photos, none from that angle.)

I like the bottom-left. Kinda looks like an arm flipping Maisel off.

irondavy:

Reading @waxpancake’s story today, my biggest question was: what will the new cover be? I certainly have no association with Mr. Baio or the project, but it seemed like a nice opportunity to play with pixels in a totally different aesthetic than I normally do. So: here’s a set of exercises.

(Edit: and just to be clear the top right one is a wholly original drawing! Based on around 6 photos, none from that angle.)

I like the bottom-left. Kinda looks like an arm flipping Maisel off.

Jun 21

Why I DI with a container

I’ve been asked to document architectural decisions made on a project I am leaving during the middle of development. I’ve chosen to use an Inversion of Control container for two projects and this choice has not been enthusiastically embraced by my colleagues. One of them was chosen to inherit the IoC expertise and this reading list, sir, is for you.

Here are some individuals who have shared a lot of their knowledge on the matter:

You’ll notice that a lot of the posts are several years old. That’s ok, this is not a new concept. I think this list serves as an informational indoctrination into IoC containers.

May 18

Spring. Sunshine. Slides. Swings. Squealing.  (Taken with instagram)

Spring. Sunshine. Slides. Swings. Squealing. (Taken with instagram)

Apr 20

[video]

Trouble

I woke up to an email that a “friend was in trouble” and to please send money.

Hi,

Apologies for having to reach out to you like this, but I made a quick trip to London and had my bag stolen from me with my passport and credit cards in it. The embassy is willing to help by authorizing me to fly without my passport, I just have to pay for a ticket and settle Hotel bills. Unfortunately, I can’t have access to funds without my credit card, I’ve made contact with my bank but they need more time to come up with a new one. I was thinking of asking you to lend me some quick funds that I can give back as soon as I get in. I really need to be on the next available flight.

I can forward you details on how you can get money to me. You can reach me via email or the hotel’s help desk, 08456807390. I hope to hear from you soon.

Thanks

Riiiiiiiiggght…

Gmail didn’t warn me about this email. After someone who also got the email forwarded it to me, Gmail then did warn me. Nice warning but a little late to be useful.

Gmail warned me about a phishing email

Apr 19

Editing numbers in Silverlight with binding and validation

Presenting numbers in a Silverlight user interface with editing can be difficult. Binding to WCF RIA entities and requiring validation further complicate the issue.

The NumericUpDown is decent (especially when you remove the up/down tickers), but clumsily handles invalid numbers by resetting the number to the previous value. Our user’s have found this confusing. A TextBox works for valid numbers, but fails miserably and silently for invalid entries.

Our ideal solution

Our current solution is based on 4-5 hours of tinkering. It is good enough for now since we were achieving diminishing returns on our efforts.

Let’s set this up. Here is a sample entity as it exists on the server:

public class ConvictionHistory
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int? InterviewID { get; set; }

    public int? Felonies { get; set; }

    public int? Misdemeanors { get; set; }

    public double? Bail { get; set; }
}

Originally, the properties were bound to TextBoxes in XAML to present to the user for editing in Silverlight:

<TextBox Text=”{Binding Felonies, Mode=TwoWay}” />

When the user typed in garbage, no validation occurred and the Felonies property remained null. The user had NO idea that their value was not stored. I won’t blame judge you for having no sympathy for the user that types ‘abc’ as a number. Let’s consider the accidental ‘o’ as a ‘0’ — that’s “OH” as “ZERO”. So we treat this as a real scenario.

I tried converters, behaviors, inheriting from TextBox, and even modifications to the NumericUpDown control to achieve the goals above. All failed at least one of the goals. The converter couldn’t affect validation. The behavior implementation moved the problem from the entity into the behavior but validation did not occur on the entity when saving. The TextBox was cleaner than the behavior but validation still failed. The attempt using the NumericUpDown was aborted in 10 minutes.

The final solution is composed of several elements.

Our solution is entirely within the Silverlight client, though it could be extended to the server. The code pattern must be applied to the entity in Silverlight via a partial class.

public partial class ConvictionHistory
{
    [RegularExpression(@”^\d*$”, ErrorMessage = "Felonies must be a number.")]
    public string FeloniesText
    {
        get { return this.GetNumberAsString(_ => _.Felonies); }
        set { this.SetIntProperty(_ => _.Felonies, value, number => Felonies = number); }
    }

    [RegularExpression(@”^\d*$”, ErrorMessage = "Misdemeanors must be a number.")]
    public string MisdemeanorsText
    {
        get { return this.GetNumberAsString(_ => _.Misdemeanors); }
        set { this.SetIntProperty(_ => _.Misdemeanors, value, number => Misdemeanors = number); }
    }

    [RegularExpression(@”^\d*.?\d*$”,
        ErrorMessage = "Bail must be a number.")]
    public string BailText
    {
        get { return this.GetNumberAsString(_ => _.Bail ); }
        set { this.SetDoubleProperty(_ => _.Bail , value, number => Bail = number); }
    }

    #region Text-Number Support Code

    private IDictionary<stringstring> _textProperties;

    public IDictionary<stringstring> TextProperties
    {
        get
        {
            return _textProperties ??
                (_textProperties = new Dictionary<stringstring>());
        }
    }

    void IExposeNumbersAsText.ValidateProperty(string propertyName, object value)
    {
        ValidateProperty(propertyName, value);
    }

    void IRaisesPropertyChangedEvent.RaisePropertyChanged(PropertyChangedEventArgs args)
    {
        RaisePropertyChanged(args.PropertyName);
    }

    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);

        if (TextProperties.ContainsKey(e.PropertyName))
        {
            RaisePropertyChanged(e.PropertyName + "Text");
        }
    }

    #endregion
}

Essentially you copy “Text-Number Support Code” region into your partial. By convention, you create a string property for each of your numeric properties and use the “Text” suffix.

The XAML binding changes as well to improve the validation experience.

<TextBox Text=”{Binding FeloniesText, Mode=TwoWay, ValidatesOnExceptions=True}” />

Now we get the user experience we were looking for. Let’s see how well we did against our goals:

The solution isn’t perfect and is not extremely intuitive or self-documenting. But it’s good enough for this project.

The extension methods and other code can be found at https://gist.github.com/929974

Mar 29

Why we left Team Foundation Server

We didn’t just leave TFS, we chose Subversion, TeamCity, and PivotalTracker. But leave TFS we did, and in a hurry. And mostly it was due to TFS 2010.

Background

My organization is a large government entity with many lines of business. Our team is about 18 people (FTE, contractors, managers), we focus on just 3 lines of business and create applications for (mostly) internal users. We’ve been a “.NET shop” for 10 years; one of the central apps was originally written in .NET 1.0 beta. VSS and, later, Team Foundation Server 2008 have acted as the SCM solution for as long as anyone remembers. We’ve adopted many agile practices and are currently developing with .NET 4.0, Silverlight 4, MVC 3, and Entity Framework; in other words, today we aren’t a stereotypical enterprise/government IT organization.

When I joined in 2009, the team was well-entrenched in TFS 2008; it served as source control, build server, project management platform, and bug tracker. I came from years of SVN and, though TFS is awkward, it wasn’t all bad. The Visual Studio integration is pretty solid and this is probably the most important factor for us. Because some of the team moved into .NET from MS Access and VBA, the level of familiarity with anything not Microsoft was low. TFS worked well for them and well enough for everyone else.

The Foundation Crumbles

We were eager to jump to TFS 2010 to resolve a few of our issues with TFS 2008: improved process templates, better source control performance, better integration with Visual Studio 2010 compared to VS2008, and improved build server. After a month or so breaking in our new TFS 2010 installation, we found most of these issues were improved to our satisfaction.

Strangely, we found the TFS build server had become unusable. After two weeks attempting to replicate what we had in TFS 2008, we gave up. The Windows Workflow Designer is as “simple” as advertised, but not the kind of simple we wanted. We’d become skilled at customizing the MSBuild scripts and creating MSBuild task assemblies to accomplish our one-click build/test/deployment process. This seems to have been lost in TFS 2010. We were left with an awkward, mouse-driven UI and the extensibility was built around snippets of VB.NET. It is completely unintuitive and simply awful. If TFS 2010 could support the customization we wanted, we didn’t have time left to discover how exactly to do it.

TFS had always been good enough and once accepted created a disincentive to puling up the stakes and moving on. If given the chance to choose just one element of the TFS ecosystem — source control, project management, build server, bug tracker, or Visual Studio integration — the only one our team would settle on was the VS integration. Carrying the other four elements just for a GUI-based source control is unbearable.

The manager take on TFS was the “tight integration” and “complete package”. The resulting product is focused more on integration of all parts rather than doing any one thing well. Look at many of the .NET teams within Microsoft and you’ll find many not using TFS. That was enough for our manager to allow us to consider alternatives.

Picking What Works

Our approach was to pick solutions that best fit our team’s culture and environment. Cost was not an issue but we intended to spend less than we did on TFS. Our selections:

Source Control: Subversion from VisualSVN

Subversion met the Goldilocks Principle for our team. TFS was far to little and Git/Mercurial are too much. With the VisualSVN Server, we get an installation suitable for a Windows 2008 server with integrated Windows authentication, an enterprise requirement. The critical GUI integration is accomplished with the VisualSVN Visual Studio plug-in that integrates Subversion and TortoiseSVN seamlessly with Visual Studio. While Git and Mercurial are next generation SCMs, they seem to require more expertise and awareness with source control than our team, as a whole, is able to commit to.

Build Server: TeamCity

TeamCity came with many positive reviews and personal testimony from my own friends. I have used CruiseControl.NET for a few projects and while it far surpasses TFS, there was always friction as you added more projects. Hearing John Hoerr talk about the transition from CC.NET to TeamCity and the ease of creating a build-per-branch sold me. TeamCity feels like the next evolution of the continuous integration server and our experience has shown this to be true. We had 12 active builds in TFS after 3 years and now have well over 20 on TeamCity after a few months. There is Visual Studio integration and integrated Windows authentication on the server.

Project Management: PivotalTracker

About a year ago, Obie Fernandez tweeted a chart from PivotalTracker showing the current progress of a project, similar to the image below. The ability to express the status of a project in one graphic does more for our project sponsors than heaps of spreadsheets out of TFS ever did.

We found PT fit very well with the agile approach within one line of business. For a year we had some projects within TFS and others in PT. TFS is a far superior project management tool because of the breadth of information it can capture. PivotalTracker is the best “customer expectation management” tool. Our project sponsor can see and touch PT whereas TFS was a dev only tool. This has lead to happier customers who are grateful for the transparency. I don’t think the projects have gone faster or smoother, but the customer perception has dramatically improved. And perception is reality.

Bug Tracker: PivotalTracker/Trac

PivotalTracker works great for about 10-15 bugs before the overload of bugs overwhelms the PT interface. We’ve decided that having 15 bugs in any project in active development means you are doing it wrong. We avoid bugs by discussing our features with the entire team (PM, BA, Dev, QA, and customer) before setting to work. Before “Finishing” a feature, QA usually takes a quick look. Most “bug reports” come from a QA dev in the chair next to me while we talk over a feature before I commit the changes to source control. In the last 18 months, we’ve had less than 15 bugs come from the four applications deployed to production in that period. If we ever encounter a bug-rich project, we have Trac on hand to handle the overload.

Conclusions

After 3 months in our new ecosystem, there are few complaints. In a way, we are thankful the TFS 2010 build server is so terrible as it served as the catalyst to our changes. We now have the best, or near-best, tools in each class.

The most difficult transitions were more cultural than technical. We’ve adapted slightly to the idiosyncrasies of the tools and changes to process. In the end, choose the tools that meet your needs for your team.

Pros

Cons

Feb 09

Apparently MSDN documentation now indicates which .NET members are supported by Xbox 360.

Apparently MSDN documentation now indicates which .NET members are supported by Xbox 360.

Feb 08

Could not load file or assembly

I’m working MVC/Razor into an ancient WebForms web application. In addition, I’m converting it from IIS Classic pipeline into an Integrated pipeline. This is far from trivial. Here is an error I ran into:

Could not load file or assembly ‘System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ or one of its dependencies. The system cannot find the file specified.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IO.FileNotFoundException: Could not load file or assembly ‘System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ or one of its dependencies. The system cannot find the file specified.

Source Error:


Assembly Load Trace: The following information can be helpful to determine why the assembly ‘System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ could not be loaded.


Stack Trace:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
[FileNotFoundException: Could not load file or assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.]
   System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) +0
   System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) +314
   System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) +95
   System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) +124
   System.Web.Configuration.ConfigUtil.GetType(String typeName, String propertyName, ConfigurationElement configElement, XmlNode node, Boolean checkAptcaBit, Boolean ignoreCase) +76

[ConfigurationErrorsException: Could not load file or assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.]
   System.Web.Configuration.ConfigUtil.GetType(String typeName, String propertyName, ConfigurationElement configElement, XmlNode node, Boolean checkAptcaBit, Boolean ignoreCase) +11360476
   System.Web.Configuration.Common.ModulesEntry.SecureGetType(String typeName, String propertyName, ConfigurationElement configElement) +69
   System.Web.Configuration.Common.ModulesEntry..ctor(String name, String typeName, String propertyName, ConfigurationElement configElement) +62
   System.Web.HttpApplication.BuildIntegratedModuleCollection(List`1 moduleList) +301
   System.Web.HttpApplication.GetModuleCollection(IntPtr appContext) +1332
   Microsoft.Web.Infrastructure.DynamicModuleHelper.CriticalStatics.Init(HttpApplication context) +302
   System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +546
   System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +325
   System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
   System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375

[HttpException (0x80004005): Could not load file or assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11529440
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4783925

It’s subtle, but this is the offending XML in the web.config:

Here is the correct XML:

Jan 12

Of my Google Alerts, the one for my name is the least interesting. The most frequent result is the publishing of a new book.

North Carolina Life Sketches 1st ed Chapel Hill in the Books

Of my Google Alerts, the one for my name is the least interesting. The most frequent result is the publishing of a new book.

North Carolina Life Sketches 1st ed Chapel Hill in the Books

Jan 10

Apple AirPlay from the iPhone as Intercom

We have an Airport Express upstairs in the bathroom that we use to listen to music or radio streaming from an iPhone while we get ready in the morning. This weekend, I was watching football on the couch while my wife was upstairs giving a bath to my 4 year old. I needed to let them know a friend was coming over in 15 minutes.

It’s only 20 steps up the stairs from the couch. I’ve counted. But I’m lazy efficient. I gotta be able to use AirPlay… right?

I started with the Voice Recorder and recorded the message. Unfortunately, the AirPlay icon never popped up while I was playing the audio. After emailing myself, the iOS email client stalled downloading the attachment. I used Safari to get to the email in gmail and played the m4a. That worked.

I had to run upstairs immediately to make sure it worked. It was only 20 steps.