Changing the VS2015 Icon in Windows 8/8.1

So – you install VS 2015, pin the icon to the start bar and ‘whaaaaaa???’ you discover it’s exactly the same Icon as for VS 2013, which is not handy.

Luckily, it’s pretty simple to change that bad boy.

Step 1

In the start menu, right click on the program you wish to change the icon for, and select ‘Open file location’ (in these pics, I’ve already done the update)

image

Step 2

Right click on the icon and select ‘Properties’

image

Step 3

Then click on Change Icon

Step 4

Pick a new Icon (I used one from: http://www.iconarchive.com/tag/visual-studio)

Step 5

If you have it pinned to the TaskBar, you’ll probably need to unpin and re-pin, if you don’t then the job is done – well done you!

Extra notes for those not on Win 8+

It’d probably work in exactly the same way for Win 7, but I don’t have it so :p

Neo4j.AspNet.Identity is Back!

In fairness, it was never *away*, but after a brief hiatus - it is being developed again.

So changes – it’s moved - https://github.com/cskardon/Neo4j.AspNet.Identity

It’s also been repackaged and nuget-ed, the instructions on the Readme have been updated and the actual database structure is better than before, it’s not all there (of course) but I will accept pull requests and any issues, open up on the github page.

I’ll try to do some follow up posts with the db structure, but roughly:

image

Upgrading your Neo4J from XXX to 2.2.0–having authorization trouble?

I’ve recently upgraded one of my Neo4J dbs from 2.1.7 to 2.2.0, and instantly ran into troubles with the new Authentication that the db now has. You’ll notice it when you first login to your browser (http://localhost:7474/) and get asked for a login name and password. Of course, you can turn off authentication via the settings (conf/neo4-server.properties) by changing the ‘dbms.security.auth_enabled’ value to false, but now we’ve got it, we should use it!

Luckily neo4jclient already allows us to pass in basic auth via the uri, so we can do something like:

var client = new GraphClient(new Uri("http://user:pass@localhost.:7474/db/data"));
client.Connect();

9 times out of 10, that’ll work just fine for you, the problem is if your password has a character in it that the Uri constructor can’t parse – now I’m sure you can escape the character – but I’ve been unable to find out how, so something like:

new Uri(http://user:pass#@localhost.:7474/db/data)

will fail with a ‘UriFormatException: Invalid URI: Invalid port specified.’ message (I’ve added a ‘#’ to the password).

What to do???

Spiffily – the GraphClient has another constructor that takes in an IHttpClient, so we can create our own version that injects the Authorization header into any (and all) requests to the db:

private class HttpClientAuthWrapper : IHttpClient
{
    private readonly AuthenticationHeaderValue _authenticationHeader;
    private readonly HttpClient _client;

    public HttpClientAuthWrapper(string username, string password)
    {
        _client = new HttpClient();
        if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
            return;

        var encoded = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", username, password));
        _authenticationHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(encoded));
    }

    public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
    {
        if(_authenticationHeader != null)
            request.Headers.Authorization = _authenticationHeader;
        return _client.SendAsync(request);
    }
}

Which is used like so:

var client = new GraphClient(
    new Uri("http://localhost.:7474/db/data"), 
    new HttpClientAuthWrapper("user", "pass#")
    );
client.Connect();

All authorized and happy!

WebJobs QueueTrigger not working?

I’ve just spent quite some time trying to figure this out, you read many good things about WebJobs, and as luck would have it, you’re in the market for some nifty backend processing whenever something is added to a queue, so now seems a good time to take a proper look.

So, right click on my web app, and select ‘Add, New Web Jobs’ and create a new WebJob project.

image

Then start adding my code:

class Program
{
    static void Main()
    {
        var host = new JobHost();
        host.RunAndBlock();
    }

    public static void ProcessQueueMessage([QueueTrigger("myqueue") string msg, TextWriter log)
    {
        log.WriteLine("Got msg {0}!", msg);
    }
}

This is the file that opens up and is initially visible.

So far so looking good.

Run and it says:

image

Yay.

So I add a message to queue.

Nothing. The message stays there the webjob stays quiet.

The clue is in the console:

image

Functions???

Turns out there is another class called ‘Functions’ in the project (in it’s own Functions.cs) that there is no mention of, which is where the code should be. Specifically, Functions is a public class, I can make Program a public class and it’ll pick up my proper ProcessQueueMessage, but otherwise it stays hidden.

Getting VpnNetworkSetupFailure on Azure when setting up a Virtual Network from a Website Instance?

This is one of the most annoying errors I’ve come across purely as to find the information involved hunting through many layers. For those who want the quick ‘give me something to try please!’ solution, ensure the name of your website instance is 38 characters or less.

The explanation

Let’s create a new website using the Preview Portal:

image

The name in full is: Test-Virtual-Network-Error-Creating-Website which is 43 characters. Note that we have the Green Tick of Success next to the URL field, this name is perfectly valid (ace!)

So, funny thing, you talk about one naming issue and up pops another - you can also get the Green Tick of Success using spaces in things like the Web Hosting Plan (as I did above):

image

But that is all LIES!!!! If you do that, you’ll get this error and the website won’t be created

image

So getting back to the problem at hand, having changed the name of the Web Hosting Plan to a suitable one, the website is created, BOOM!

We want to add to a Virtual Network, but want to create via the website dialog blade, so we navigate (scroll) to the ‘Networking’ section and click on the Virtual Network, errr, button:

image

We Create new Virtual Network and give a nice succinct name, for example I’m choosing ‘TestVnet’

image

Easy money, press OK and keep the dream alive.

Oh noes!

image

We have an error of type: VPNNetworkSetupFailure, with a message of VPNNetworkSetupFailure. That’s cool though, we can click on that and get taken to more det…

ah no.

image

This is perhaps as informative.

We need info, but where from? Handily the Resource Group holds the key to this issue, so lets boogie on down there

image

What we’re after in this blade is the events. So, scrolly scrolly, and get to the Monitoring section, let’s click on the Events in the past week ‘button’:

image

We’ll take the first Failed event and investigate:

image

At the bottom of the event, in the ‘Properties’ section, we can see the error:

image

Or in copy/pastable text format:

The provided deployment name 'VPNNetworkSetupForWebsite-Test-Virtual-Network-Error-Creating-Website' has a length of '69' which exceeds the maximum length of '64'.

Azure handily hoofs up 26 characters by prepending ‘VPNNetworkSetupForWebsite-’ before the website name.

If you create the website with 38 characters or less for a name you’ll be just fine.

New Nuget Package for Neo4j Users - Neo4jClient.Extension

The defacto standard for .net users of Neo4j is the Neo4jClient nuget package, if you don’t have that, you’re basically rolling your own connection code, in some cases you might need to, but most of the time, the client will work well.

Today I was adding Neo4jClient to a new project, and searched via the Nuget package UI and up popped Neo4jClient.Extension, so, I went to the github repo, read the .md file and thought - I’ll download that bad boy and give it a go.

The general gist is to be able to pass things like your actual entities to the client without needing to write the Cypher, thereby adding even more type safety to your code, so instead of:

Client.Cypher.Merge(string.Format("(n:Label {{item}}.Id = {0})", entity.Id));

You can now just put in:

Client.Cypher.MergeEntity(entity);

Which certainly prevents typos. I’ll describe a bit more about it below, but the TL:DR of it is, whilst it’s in it’s early stages, it’s worth looking at for a .net developer, in particular with a new project. There are some issues to be aware of (see the bottom of the post) but all in all I look forward to seeing how this progresses.

Attributes Everywhere!

Neo4jClient.Extension uses attributes for most of it’s core functionality.

[CypherLabel]

I like the [CypherLabel] attribute a lot, it works well for simple cases, and is a neat way of putting labels in the code, the downside would come from wanting to add extra more dynamic labels, so you might have a class called Location looking something like this:

[CypherLabel(Name="Location")]
class Location {
    public string Name { get; set; }
}

But you couldn’t subsequently put something in the DB with (n:Location:USA) as there is no way to add the ‘USA’ label.

[CypherMatch]

Here we can do searches in a simpler fashion to the old way, so instead of:

Client.Match("(n:Model {Id:{myParam}.Id})").Return(n => n.As<MyObj>());

we instead just do:

Client.Cypher.MatchEntity(model, "n").Return(n => n.As<MyObj>());

Note, I’ve defined the ‘n’ parameter name in the MatchEntity call, if I left that out, the param name would (at present) be the lowercased name of the label.

[CypherMerge/MergeOnCreate/MergeOnMatch]

These are the main guts and where the work is really showing, the cool thing here is it removing the complexity and nightmare of curly brace nesting. Basically, the CypherMerge attribute defines the ‘key’ the Merge will work from, generally this will be the ‘Id’ property. The MergeOnCreate attribute is applied to all the attributes you would want to be created as part of the ‘ON CREATE’ bit of a MERGE query, and quite obviously the MergeOnMatch attribute is for the ON MATCH bit.

One thing to consider with the use of these attributes (and it affects the ‘CypherMatch’ one as well) is that you can only have one Merge/Create version, so if you decide you want to merge properties 1,2,3 one time and 4,5,6 another, you’re going to have to revert to the old .Merge technique for at least one of those cases. It’s not a huge issue because in at least one of the cases you’ve saved a bucket load of curly brace potential problems.

Some issues

It’s early days, and only version 0.1.0.1 but these are worth noting in case you want to use the package.

Case changing of Property names

For some reason the case of the properties in my classes is changed so the first character is lowercase, which is not something I’m overly pleased with, it’s not ‘end of the world’ type stuff, but I’m wary of code that doesn’t do what I expect, and I expect if I have a property called ‘Name’ that it will be stored as ‘Name’ in the DB.

Labelling

If you use any special characters in your labels, such as ‘/’, ‘ ‘ (space) or just the ` character you’ll run into issues, there is a pull request to fix this, so hopefully not an issue for long

AttributeUsage

You can apply the CypherLabel attribute to a property (and a CypherMerge* attribute to a class) but in both cases they won’t do anything.

Install Cypher Highlighting into Sublime Text 3

I’ve had Sublime Text (ST) 2 installed now for quite a while, purely because I use the Cypher highlighting package, and whilst I waited for ST3 to have it in the Package manager, it didn’t matter that I had both for a while. But I finally decided to bite the bullet and install Cypher manually into ST3.

Step 1.

Go to https://github.com/kollhof/sublime-cypher and Download ZIP of the repo.

Step 2.

Open ST3, and go to ‘Browse Packages’ (CTRL+SHIFT+P then type ‘browse’)

Step 3.

In the Explorer window, add a new folder called ‘Cypher’

Step 4.

Extract the contents of the ZIP you downloaded in Step 1 into the folder you created in Step 3

Step 5.

Restart ST3.

Step 6.

Switch to Cypher mode (CTRL+SHIFT+P then ‘Cypher’)

Step 7.

image

Ha! We all know that won’t work :)

CdnFallbackExpression for JQuery, JQuery.UI, Modernizr and Bootstrap

So, like a total chump, I didn’t really understand what the CdnFallbackExpression on a Bundle actually meant. It didn’t help that pretty much every example you find online shows you what to write for jQuery, but nothing else.

With Tournr, I want to use CDN’s where I can for obvious reasons – and so I dutifully tried the jQuery example:

var bundle = new Bundle("~/Scripts/jQuery").Includes("~/Scripts/jQuery-2.1.1.js");
bundle.CdnFallbackExpression = "window.jQuery";
bundle.CdnPath = "https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js";
bundles.Add(bundle);

Works just fine.

And this is the point things start to go awry. In my naivety I didn’t really understand what was happening. I didn’t twig that the CdnFallbackExpression has to be window.jQuery. It won’t work otherwise. Being a developer, I took it upon myself to wrap up the above into a method, something like:

private static Bundle GetBundle(string name, string cdnPath, params string[] includes){ /**/ }

Being snazzy and using the ‘name’ as a fallback expression.

That’s right, the name, (actually “window.{0}” where {0} was the name), which as you can imagine worked great for jQuery, not so for anything else. I believed that what I wanted was something like:

<script>(window.bootstrap) || document.write('<script src="~/Scripts/bootstrap.min.js><\/script>')</script>

I imagine you looking at this, perhaps with your palm attached to your forehead. You are right to do so.

So, I test tournr, hmmm bootstrap is no longer working. If I remove the CDN stuff, it’s all good, so I guess bundling must be b0rked?? I spent ages looking for errors in the Console windows of IE and Chrome Developer Tools – nada. Network was showing the files downloading, but curiously I noticed 2 copies downloading, so my local and my CDN loading. Odd. One or the other please, not both. This led to my eureka moment!

The CdnFallbackExpression has to be set CORRECTLY. No amount of time saving auto setting was gonna save me, so now the GetBundle  looks more like this:

private static Bundle GetBundle(string name, string cdnPath, string fallbackExpression, params string[] includes){ /**/ }

So, the fallback expressions for jQuery, UI, etc are listed below:

Library

Expression

jQuery window.jQuery
jQuery.UI window.jQuery.ui
Modernizr window.Modernizr
Bootstrap $.fn.modal

Tournr

A little while ago (2 months and 12 days to be precise) I launched my project I’ve been making for a while now: Tournr. I have the usual Facebook page (please like!), twitter account and even a blog for the features / tips etc. So this post is really to first introduce the readers of this blog to Tournr, but also as I’d like to post about the design decisions I’ve made here, anyhews, I’ll get on to that later.

Briefly Tournr is a site to help organisers run competitions, long term it’ll do loads, short term it helps with registration, providing one point for a competition entry and results recording so if you have a competition to run, please try it and let me know if there is something you want / need to help you!

Much more later!

BrowserStack Visual Studio 2013 Extension

So, if you download the extension from Visual Studio Gallery (here) you’ll find it won’t install into VS 2013, but it’s easy to fix.

Open up your downloaded file using your preferred zip solution (7zip in my case), edit the extension.vsixmanifest file, and change the following lines from:

<Installation InstalledByMsi="false" AllUsers="true">
  <InstallationTarget Version="11.0" Id="Microsoft.VisualStudio.Pro" />
  <InstallationTarget Version="11.0" Id="Microsoft.VisualStudio.Premium" />
  <InstallationTarget Version="11.0" Id="Microsoft.VisualStudio.Ultimate" />
</Installation>

to:

<Installation InstalledByMsi="false" AllUsers="true">
  <InstallationTarget Version="12.0" Id="Microsoft.VisualStudio.Pro" />
  <InstallationTarget Version="12.0" Id="Microsoft.VisualStudio.Premium" />
  <InstallationTarget Version="12.0" Id="Microsoft.VisualStudio.Ultimate" />
</Installation>

Save the file and make sure the archive is updated. Then double click and install the extension.