.net
Binding Redirects, StructureMap and Dependency Version Upgrades
Dealing with the fallout in failing unit tests from a code merge is one of the most frustrating tasks in software development. And as one of a (very) small number of developers on our team that believes in unit testing, it fell to me to determine the cause of multiple instances of the structuremap exception code 207 error.
As it turned out, the culprit was a tactic I’ve used in the past to work with code that only works with a specific version of an assembly–the binding redirect. When the same person is in charge of upgrading dependencies, this tends not to be an issue because if they’ve used binding redirects, they know it’s necessary to update them when dependencies are upgraded. In this case, the dependencies were upgraded and the redirects were not. As a result, StructureMap tried to find a specific version of an assembly that was no longer available and threw exception code 207 when it failed.
Fixing MVC Sitemap Errors
When attempting to manually test a .NET MVC application, I got the following exception from Visual Studio:
Looking at the inner exception revealed this message:
An item with the same key has already been added.The sitemap file for our application is pretty long (over 1300 lines of XML), but a co-worker pointed me to the potential culprit right away. There was a sitemap node near the end of the file that had empty strings for its controller and action attributes. As far as I can tell, this generates the default url for the site's home page. Since it already exists, this results in the exception that's thrown. Removing the sitemap node resolved our issue. A couple of threads that I checked on stackoverflow (here and here) provide other possible causes for the error.
LINQ Aggregate for Comma-Separated Lists of Values
A couple of days ago, while pairing with my colleague Alexei on bug fixes to a new feature, we came across a bit of code that attempted to take an integer array and construct a string with a comma-delimited list of the numbers from it. The existing code didn’t quite work, so we wrote a basic for-each loop and used ReSharper to see what LINQ alternative it might construct. Here’s what ReSharper came up with:
int[] numbers = new[] {1, 5, 8, 26, 35, 42};
var result = numbers.Aggregate("", (current, item) => current + item.ToString() + “,");
Before ReSharper served this up, I wasn’t familiar with the Aggregate operator. When I checked out 101 LINQ Samples for it, the vast majority of the examples used numbers.
Filtering Heterogeneous Arrays in .NET
One of the bugs I was recently asked to fix for an application required me to determine whether or not to display one of the members of a list. This proved somewhat challenging since the lists in question were heterogeneous (two difference subtypes of an abstract base class). It turned out that LINQ provides a nice solution to this sort of problem in the form of the OfType<T> method.
Given an IEnumerable collection with elements of multiple types, calling OfType<T> on the collection where T is the desired type will return a collection containing only elements of type T. Before learning about OfType<T>, I’d been using the Cast<T> method. This was fine as long as all the collection elements were of the type T I wanted. The moment this wasn’t the case, my LINQ query threw a cast exception. OfType<T> seems to work similarly to the “as” operator in C#, in that it doesn’t complain if a list element isn’t type T–it simply excludes it from the returned collection.
ScrollViewer+ItemsControl vs. ListView
One of my most recent tasks at work was determining the cause of slow performance in one part of an application and coming up with a fix (if possible). We tracked the source of the problem down to a use of ItemsControl inside a ScrollViewer. Because the ItemsControl instance was trying to display hundreds of complex items, it took a noticeably long time to load. This turns out to be a known issue, with a few possible solutions. Simply changing the ItemsPanelTemplate of the ItemsControl instance to contain a VirtualizingStackPanel didn’t fix our performance problem.
What did resolve our performance issue was replacing the ScrollViewer and ItemsControl combination with a ListView. The list of what we changed includes:
- Giving the ListView the same name as the ItemsControl.
- Giving the ListView the same ItemsSource as the ItemsControl.
- Update the ItemsPanelTemplate of the ListView to use VirtualizingStackPanel.
- Set HorizontalScrollBarVisibility to "Disabled".
- Bound the Visibility property of the ListView to a Converter.
- Update the ItemContainerStyle with a ListViewItem style that sets the HighlightBrushKey and ControlBrushKey to be transparent.
The changes we made reduced the load time from around 20 seconds down to less than 2 seconds for 400 items.
The tradeoff in moving to a ListView (with VirtualizingStackPanel) from ScrollViewer+ItemsControl is scrolling speed. Scrolling through 400 items does go more slowly, but it’s preferable to waiting as long as we did just to see the data.
More on migrating partially-trusted managed assemblies to .NET 4
Some additional searching on changes to code access security revealed a very helpful article on migrating partially-trusted assemblies. What I posted yesterday about preserving the previous behavior is found a little over halfway through the article, in the Level1 and Level2 section.
One thing this new article makes clear is that use of SecurityRuleset.Level1 should only be used as a temporary measure until code can be updated to support the new security model.
Upgrading .NET assemblies from .NET 3.5 to .NET 4.0
Code access security is one area that has changed quite significantly between .NET 3.5 and .NET 4.0. Once an assembly has been upgraded, if it allowed partially-trusted callers under .NET 3.5, it would throw exceptions when called under .NET 4.0. In order to make such assemblies continue to function after being upgraded, AssemblyInfo.cs needs to change from this:
[assembly: AllowPartiallyTrustedCallers]to this:
[assembly: AllowPartiallyTrustedCallers] [assembly: SecurityRules(SecurityRuleSet.Level1)]Once this change has been made, the assembly will work under the same code access security rules that applied prior to .NET 4.0.
Set-ExecutionPolicy RemoteSigned
When you first get started with PowerShell, don’t forget to run ‘Set-ExecutionPolicy RemoteSigned’ from the PowerShell prompt. If you try to run a script without doing that first, expect to see a message like the following:
File <path to file> cannot be loaded because execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.The default execution policy for PowerShell is "Restricted" (commands only, not scripts). The other execution policy options (in decreasing order of strictness) are:
- AllSigned
- RemoteSigned
- Unrestricted
Unit testing strong-named assemblies in .NET
It’s been a couple of years since I first learned about the InternalsVisibleTo attribute. It took until this afternoon to discover a problem with it. This issue only occurs when you attempt to unit test internal classes of signed assemblies with an unsigned test assembly. If you attempt to compile a Visual Studio solution in this case, the compiler will return the following complaint (among others):
Strong-name signed assemblies must specify a public key intheir InternalsVisibleTo declarations.Thankfully, this blog post gives a great walk-through of how to get this working. The instructions in brief:
- Sign your test assembly.
- Extract the public key.
- Update your InternalsVisibleTo argument to include the public key.
Detect .NET Framework Version Programmatically
If you need to determine what versions of the .NET Framework are available on a machine programmatically, you’d ideally use a C++ program (since it has no dependencies on .NET). But if you can guarantee that .NET 2.0 will be available, there’s another option. The source code (written by Scott Dorman) is ported from a C++ program. I’m using the library for an application launcher that verifies the right version of the .NET Framework is available (among other prerequisites).
The unexpected home of IsHexDigit
I was about to write a method that checked to see if a character was a hexadecimal value when it occurred to me that I should google for it. I was going to name it IsHexDigit, and googling for that revealed this link. I’m not sure why it’s in the System.Uri class, but it’s less code for me to write.
.NET Utility Classes
I just came across this great post on overlooked .NET utility classes. I prefer to buy functionality or use open source rather than build from scratch, so it’s ideal when there’s already something in the .NET framework I can use.
App_Offline.htm
I came across a couple of useful posts from Scott Guthrie about App_Offline.htm. This page appears and disappears automatically when the “Publish Web Site” option is used. What I didn’t know is that it’s part of the .NET framework (not the IDE). This means the page can be added and removed manually. This will be especially useful in my current environment, where we depend on network engineers to deploy web applications to test and production sites.
Here are the posts: App_Offline.htm and IE Friendly Errors
ASP.NET Configuration File Handling
One of things I like the least about working with multiple development, QA, and production environments is messing around with configuration files to make sure the different versions point at the right databases. Add the use of the Enterprise Library, and there are even more files to manage.
In my last year at Ciena, I worked in a group where they’d put together some code that detected what environment it was in (development, QA, or production) and retrieved the correct settings from web.config. It was similar to the solution Mike Gunderloy describes in this article on ASP.NET 2.0 productivity.
When I was poking around for more information on config file handling, I came across another article that references Gunderloy’s that talks about a file attribute for the appSettings tag. I hadn’t come across the existence of that attribute anywhere else before. I’ll definitely use this on my next project.
Finally, this article provides another option for dealing with configuration files in multiple environments. The code and examples are well-explained. My group at Lockheed Martin should integrate something like this into the custom library we’ve been building.
"Free" Project Management Software
I was looking for information on the right way to modify the ASP.NET Issue Tracker starter kit to handle Windows Authentication. One of the things Google search returned was an app called Gemini that does a similar thing. Up to 10 people can use the version they offer for download before they start asking for money. Considering the way the current IssueTracker installation is behaving right now, I’m beginning to wish I’d found Gemini earlier.