Notes from Daily Encounters with Technology RSS 2.0
 
# Monday, June 17, 2013

What’s wrong with the following piece of code?

It might seem just fine to you, but if you try to run it, it will throw a NotSupportedException in the last line: Collection is read-only. How come?

If you read closely the documentation for the constructor used, it might become clear. When you pass an instance of IList<T> to the constructor, the BindingList<T> doesn’t create its copy. It serves as a wrapper for it, supporting only the operations also supported by the underlying collection. Since an array implements IList<T> as a read-only collection, BindingList<T> throws the above mentioned exception when you try to modify it in any way. Interestingly enough, array doesn’t implement non-generic IList as read-only:

Anyway, keep in mind that BindingList is only a wrapper for the collection you pass it, therefore any changes made to BindingList will automatically also be applied to the underlying collection. This might be okay if you’re aware of it, otherwise make sure you pass a copy of your list to the BindingList to keep it unchanged:

As far as passing an array to BindingList constructor goes: I can’t think of a case when this would be useful.

Monday, June 17, 2013 5:59:00 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | C#
# Monday, June 10, 2013

In the world of connected applications programmatic HTTP requests are more and more common. In Windows Store applications HttpClient class serves most purposes as long as communication is targeted at services or at least the results are processed programmatically and don’t need to be shown directly to the user:

There are cases, though, when its necessary to display the response to the user unchanged in a web browser, e.g. when displaying search results he will use as a starting point for further navigation. The simplest approach would be to just display the string response as HTML in a WebView control:

Unfortunately this doesn’t work as expected in all but the simplest cases. As soon as there are any relative links included in the page or external files referenced the page won’t work correctly. The browser needs to be aware of the actual page URI. For GET requests there is built in support in WebView control:

POST requests are a tougher nut to crack. There’s no method available to directly invoke it on a WebView control, therefore we need to find another approach. Since the POST request needs to be sent from the WebView context, InvokeScript is a good candidate as long as we can ensure a Javascript method invoking the required request. This means making the POST request will be a two step process:

  1. Display a web page containing custom HTML and Javascript required for the POST request in the WebView control.
  2. Automatically invoke the POST request by calling the Javascript method.

We can wrap all that in a WebView extension method to make it easier to use:

There’s an additional complication in the above code because InvokeScript doesn’t find the Javascript method if it' is called immediately after NavigateToString. The web page must first complete loading for the call to succeed, therefore an event handler is required.

Monday, June 10, 2013 6:38:00 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | C# | Metro | Windows Store
# Monday, June 03, 2013

When moving a Windows Phone project referencing Microsoft.Bcl.Async package to a new computer I was unpleasantly surprised. Although I had NuGet package restore enabled on the solution, it not only failed to build, it even failed to load. After some investigation I found out that this was a known limitation in NuGet: if a package imports additional .targets files into the project, package restore can’t restore the package in time because project loading fails before it is even triggered.

Since the issue isn’t yet fixed in NuGet 2.5 (current version at the time of writing this), I thought I’d post instructions on how to quickly get such a project loaded:

  1. Open the solution and wait until any offending projects fail to build.
  2. Check the Output window for the error message (View > Output menu item if you don’t have it open). You should find one similar to the following: “The imported project "<SolutionFolder>\packages\Microsoft.Bcl.Build.1.0.5\tools\Microsoft.Bcl.Build.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.” Note the name of the package marked with bold in the text above.
  3. Switch to Package Manager Console (Tools > Library Package Manager > Package Manager Console menu item) and execute the following command: “Install-Package Microsoft.Bcl.Build”. Of course replace package name with the one from your error message.
  4. Once the package is successfully installed you can load the offending project by right clicking on it in the Solution Explorer window and selecting Reload Project. Now you can rebuild the solution to restore any other required packages that are missing. Since you have the Package Manager Console open, you can instead click on Restore button that appeared in a pane at the top of that window.

It’s not a perfect solution, but at least for me it’s a good enough workaround until the issue finally gets fixed.

Monday, June 03, 2013 3:24:00 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | NuGet | Software | VisualStudio
# Monday, May 27, 2013

If you’ve only been using NuGet in typical scenarios with a single solution containing a couple of projects, it probably worked great for you. As soon as the project structure is a bit more complex, things start falling apart. There are two main reasons why it doesn’t work as expected when individual projects are included in multiple solution files residing in different folders:

  • By default packages are downloaded to a subfolder inside the same folder as the solution file. Projects reference libraries inside this subfolder using a relative hint path. If not all solution files are in the same folder Visual Studio can’t find the libraries when the project is open from a different solution than when the library was originally added. To make this work the libraries would need to be in multiple folders.
  • Package restore feature also adds a .targets file and a couple of supporting files to a subfolder inside the same folder as the solution file. Since the .targets file actually implements this functionality, package restore doesn’t work if the file is not in the expected location. Until recently the projects even failed to load in such cases making it impossible to open them without a solution or add them to a solution without package restore enabled.

For a long time this has a been a limiting factor for introducing NuGet to the development process in the company I work for. Trying to use it often caused problems for other developers, until we have finally found a permanent solution based on Eddie Garmon’s post to a discussion thread on NuGet’s CodePlex site.

The first part of the solution takes advantage of hierarchical NuGet.config file support introduced in NuGet 2.1. It should be put in the repository root (trunk in Subversion or master in Git terminology) containing the following settings:

As long as you don’t have other NuGet.config files in your project directory structure overriding the setting, this should make sure that when installing NuGet packages to any project in your source code repository, they will be put to a common Packages repository at the root level. Libraries will also always be referenced from there preventing the build from failing because Visual Studio can’t locate them.

The second problem is a bit harder to crack and involves a couple of steps:

  • First temporarily enable NuGet package restore for a single solution from within Visual Studio to create the .nuget folder in the same folder as the selected solution.
  • Remove the .nuget solution folder from inside Visual Studio
  • Move this file system folder to the root of your source control repository where you have already put your NuGet.config file.
  • Delete the NuGet.config file inside this .nuget folder.
  • Open and modify a single line in NuGet.targets file inside .nuget folder:
  • Edit all project files inside the previously selected solution (you need to unload a project before the edit command on its file becomes available in Visual Studio). Again you only need to modify a single line pointing to the NuGet.targets file:

Once you do this NuGet package restore feature should already work for this solution. You can simply test it by deleting the Packages repository folder and rebuilding the project: it should succeed and restore the folder with all the required packages.

To add package restore support to other projects you only need to add the modified Import line from above to each of them, modifying the relative path as required so that it points to the actual location of the .nuget folder. Don’t use the Enable NuGet Package Restore from Visual Studio any more as it will only add unnecessary files to the solution and incorrectly modify the project files.

Monday, May 27, 2013 7:35:00 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | NuGet | Software | VisualStudio
# Monday, May 20, 2013

Recently I encountered strange and inconsistent behavior in exceptions being thrown by different file operations in WinRT. Let’s start with a snippet:

Although there is a file named Text.txt in Assets folder of the application package, the above code throws an exception. If you were paying close attention while reading the code you might have even noticed the problem. There’s no exception thrown in the first line, though. Instead the second line throws an ArgumentException: Value does not fall within the expected range. Strange, isn’t it?

Let’s take a closer look by putting a breakpoint on the second line. The problem lies in the value of file.Path property: C:\Users\Username\Documents\Visual Studio 2012\Projects\SlnName\ProjName\bin\Debug\AppX\\Assets\Text.txt. Did you notice the two backslashes before the Assets folder? They’re causing the problem. CopyAsync method can’t find the file because of it and throws the non-descriptive exception which doesn’t really help pinpointing its cause. Calling ReadTextAsync on the file instead would’ve make it much easier:

In this case the second line throws FileNotFoundException: The filename, directory name, or volume label syntax is incorrect. Definitely much clearer. Too bad, CopyAsync doesn’t throw the same exception. It would have made troubleshooting the original issue much easier.

That’s not all, though. I still think the exception should already be thrown in the first line. If we replace the filename with a non-existent one (e.g. Text1.txt), it does throw FileNotFoundException as expected: The system cannot find the file specified. It seems that for some reason GetFileAsync can handle paths with double backslashes. It even sets file.DateCreated correctly, so there can be no doubt about that. The other methods don’t seem to support this same syntax. That’s not a problem per se, but in my opinion all methods should behave the same to avoid confusion: either support the syntax or not. Until that happens, I’ll keep in mind the described anomaly, just in case I stumble upon it again.

Monday, May 20, 2013 6:00:00 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | C# | Metro | Windows Store
Sponsored Ads

About Me
Currently Reading

Visual Studio 2012 and .NET 4.5 Expert Development Cookbook

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2013, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)
Social Network Icon Pack by Komodo Media, Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.