Monday, 16 February 2015

NuGet insanity (Could not load file or assembly 'System.Web.WebPages, Version=3.0.0.0...)

I am relatively new to the entire NuGet ecosystem. What I expected is for things to just work. You know... Microsoft. However the web of interdepencies seems to be too much even for them. The problems that appear when updating MVC versions, .NET Framework versions, etc, are as annoying as they are unclear. One example: I was trying to publish a project that worked perfectly on my system. I moved it to the server machine, and weird things began to happen. The most annoying of them all is that the errors that occur do that at runtime instead of at compile time. Such an error was "Could not load file or assembly System.Web.WebPages, Version=3.0.0.0...". The project reference for WebPages was 2.0.0.0. If I removed it and tried to add a reference, only versions 1.0.0.0 and 2.0.0.0 were available. Meanwhile Razor was complaining that it didn't find the 3.0.0.0 version of WebPages.

Long story short: don't try to resolve only the library dependencies, but also the framework dependencies. In this case, System.Web.WebPages 3.0.0.0 is only available for the .NET framework 4.5.1. The project was configured as 4.5. Updating the MVC framework after the change to .NET 4.5.1 solved it.

Steps:
  • Change the project version to 4.5.1 (or whatever the newest usable .NET framework version)
  • go to the NuGet Package Manager Console in Visual Studio
  • Run command Update-Package -reinstall Microsoft.AspNet.Mvc

This, of course, is not a panacea for all problems, but just remember that the .NET framework is important in these scenarios.

Thursday, 12 February 2015

Always send the CORS headers with your HTTP error responses

I met this situation where I wanted to implement an http interceptor, a piece of JavaScript code that would do something on unauthorized access to my API. The way to do this is irrelevant (and different from jQuery and AngularJS sites), but there is a problem that affects every situation and that is when you access the API from a different domain than the API's. You see, the browser needs the API server to authorize CORS for every Ajax request that accesses that server from another domain. You might think you did that already in your API, but let me ask you: when there is a problem, like not authorized access, are you sending CORS headers with your error response? Because if you do not, everything you send, including the http code, will not be parsed by the browser and any interception will just show a code of 0. The situation is a little confounded by the fact that the browser does announce that you have a CORS access problem, but also displays the status message, which in this case would be "Unauthorized access". This might make you think you can access that message or the status code. Well, you cannot.

The solution is to send the CORS headers: Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers. Just set their value to "*" and send them with your error response and now your JavaScript can read the error code and message.

Saturday, 7 February 2015

A light speed trip from the Sun to Jupiter

This is a great film. It shows what it would look like to travel with the speed of light from the Sun to Jupiter. It takes 45 minutes (the length of the film) and it is one of the few things that show really how space is, how large, empty, unforgiving it is and how small and almost insignificant are the small islands of dirt we are fixated on. Don't worry, you have a little indicator of when something is about to appear, so you can fast forward. Really loved this. I only wish it would have continued to Pluto and beyond (just so you understand how awesome the New Horizons probe really is)

Thursday, 5 February 2015

Javascript "arguments" weirdness

I was using this JavaScript function that I wanted to accept an array of arguments or just a bunch of arguments that would be interpreted as an array. As you probably know, for each function in JS you get a variable called arguments which contains the arguments to the function. It is a pseudo array, not a real array, and has some extra properties. My code looked like this:
function x(arg) {
if (!arg) {
arg=[];
} else if (!arg.length) {
arg=[];
for(var i=0; i<arguments.length; i++) arg.push(arguments[i]);
}
// do something with arg
}

The logic is simple, if there is no first parameter, arg becomes an empty array, else, if there is a first argument, but it doesn't have a length property (not an array) set arg to an array and push all arguments of the function as items of the array. But it doesn't work! The point is this: you set arg to an empty array and at that moment arguments[0] is no longer the original argument, but the empty array. Even worse, the code then adds the array as an item of itself, which makes the object be infinitely recursive.

Let's make this simpler:
function x(arg) {
arg=[];
console.log(arguments[0]);
}
After you execute x() with any arguments, the console will show an empty array, not the original argument. Weird, huh?

Monday, 2 February 2015

Childhood's End, by Arthur C. Clarke

Book cover Childhood's End is a really interesting book. It is actually a series of medium length stories set in the same world. It starts with a sort of Independence Day kind of invasion - a peaceful one, though - it continues with the effects on the human world after decades have passed and then it ends with a human evolutionary leap that explains the entire book so far. The reason why I loved it so much is that a vast majority of the ideas in the book have withstood the test of time. Written in 1953, Childhood's End is remarkably modern and rational. Well, maybe today's world is not particularly rational, so maybe it is more modern that the present, which is remarkable :)

Arthur C. Clarke seems to have had an obsession with alien encounters - and by this I mean advanced species that have good reason to come to Earth, other than wanting to steal our water or mine our gold or other stupid thing like that. He wrote 2001: a Space Odyssey and Rendezvous with Rama, both about humans suffering of culture shock after a meeting with an alien species. Personally I think Rendezvous with Rama should not have had sequels, perhaps even Space Odyssey; for me it seems like Clarke continued some stories that had great success, rather than needing to continue those stories.

Anyway, Childhood's End is like that: alien creatures just oversee the evolution of our species on Earth, intervening only on minimal occasions. I loved the idea because it is a quick and dirty sci-fi solution for historical and all too present issues like borders, religion, corruption, politics and all those ugly things that appear like magic when enough people get together. I also loved the kind of Christian metaphor of daemons being directed to oversee and guide the human race, without them being privy to "God's grace", so to speak.

It is not an easy to finish book, as it isn't really an emotional story. There are no heroes that one can identify with; it is just a descriptive, rational, logical narration. It is a good book, though, one that I am glad to have read listened to as an audio book.

Thursday, 29 January 2015

Monday, 26 January 2015

Run Chrome with file access AND in a separate instance

Sometimes you want to run your browser without some protections that are enabled by default in it. One of these is the cross-origins protection when running a local filesystem script. For Chrome, the solution is to run the browser with the command line switch --allow-file-access-from-files. Seems straight forward enough, but if your browser is already open (usually I have at least 10 active tabs, ranging from documentation pages, email to the music I listen to), the command line switches will be ignored and your script will be run as just another window in the same instance of Chrome. In order to fix this, you need to use another switch called --user-data-dir. Just make sure this folder exists and it can be deleted (because it will be filled with a zillion useless files).

So, how do I run a test.html file that can access files and is located in C:\SomePath ? Like this:
start "Chrome with access to files" chrome --allow-file-access-from-files "file:///C:\SomePath\test.html" --user-data-dir="C:\SomePath\UserDir"


In your path a UserDir folder will be created which you can delete after you finish your work.

Of course, this issue applies to any other flags that you want to use ad-hoc while Chrome is already open.