Nesting Layouts in MVC

I try to contribute to the MVC section on the asp.net forums and I sometimes see interesting questions about things I think are either obvious or that I’ve just not thought to do. This post is one such scenario: nesting layouts in MVC (master pages for WebForms people looking over the fence at MVC). Sounds easy and it pretty much is until you come to using sections.

Sections appear to catch people out as they need to be declared in the Layout specified by the content page, so if you have a sub-layout calling a master layout, how do you pass over a scripts section from the content to the master layout. This might catch a couple of people out who consider themselves proficient in MVC. The answer is as simple as nesting the sections too.

To make it nice and easy/familiar, I’ll stick with the scripts section as many people who deal with layouts will be used to that. Now imagine a site  that deals with cars. The cars are split up into categories and lets say we have a controller dedicated to the topic of sports cars.

Our graphics designer has worked hard for at least 10 minutes creating a photoshop image of a race inspired page and its layout is completely different to that of the city car topic and the family car topic.

To get every ounce of rendering speed out of our users’ browsers, we’ve decided to use a stylesheet just for this area of the site – no family car styles or city car styles.

Next up there is a script on one of our pages that needs to be rendered just for that page. Don’t ask questions, just go with it. Now we could just use the master layout page and include the sports car styles as a section in each page under the sports car area or we could be a bit fancier and use a sports car layout that includes the necessary styles and elements for the sports car pages but still calls the main layout for the site-wide common html (html declaration, the header and footer, etc.). Who wants to remember to include the styles in each new view in the sports car area. You’re not writing the html, head and body tags in each view (are you?) so why bother to repeat the style link in each view if we can use a common layout.

Now have something along the lines of a sports car page, index.cshtml for example, calling the SportsCarLayout.cshtml which is turn calls the site’s _Layout.cshtml. Everything seems to work right up until we reach the page with the custom script, the test drive page. TestDrive.cshtml plays nice and renders the script into the scripts section. Unfortunately, this now throws an error as SportsCarLayout.cshtml doesn’t have a scripts section, that scripts section is in our main layout page. If you try to add a RenderSection call (as shown below) for scripts in SportsCarLayout.cshtml it will place it in the body of the MainLayout, before our other javascript libraries. Assuming of course that you are placing your javascript at the bottom of the page, following that best practice, you are doing that aren’t you..?

@{
 Layout = "~/Views/Shared/_Layout.cshtml";
}
@section ExtraStyles
{
 @Styles.Render("~/Content/racey")
}
@RenderBody()
<!-- below code is wrong -->
@RenderSection("scripts", false)

If our test drive script relies on jQuery which is loaded via the site’s _Layout.cshtml just before the call to render the scripts section, the test drive script will fail as jQuery isn’t available as you’ve rendered it in the call to “RenderBody” of the main layout page.

Let me cut to the chase as I’m tired of writing about this imaginary car website now, you can nest sections as well as nesting layouts.

If you use the following nesting method you can call the section inside another section that will be passed on to the _Layout.cshtml page, so in your SportsCarLayout.cshtml write the following.

@section scripts
{
 @RenderSection("scripts", false)
}

This will write the script code inside the section code block which means it will then be passed along to this page’s layout. Code/script/style duplications can now be safely removed thanks to nesting layouts along with nesting sections where necessary.

Entity Framework – Model binding private properties

I’ve recently started looking on the asp.net forums and answering a few questions here and there which led me to this scenario of binding private properties in Entity Framework.

The basics of the problem were as follows:

  • MVC application storing data via Entity Framework into a database (lets face it, its going to be SQL Server)
  • A class held a value that had to be encrypted when saved to a database
  • The value needed to be visible when in the application.

Seems pretty simple and I ended up advising that the value should be kept encrypted all the time (in the database and in the model) and only decrypted by a helper called in the View.

However, I was interested to know if the path we started to take would work. The original design of the class had a public property with a setter that encrypted the value and a getter that decrypted the value. Now if Entity Framework was bound to this, the value would be read via the getter and so would be stored in the database in plain text. The idea then was to add a private property that used the same backing field but never encrypted or decrypted it. This would only be used by Entity Framework to save the encrypted value. This is not a great solution and I’d advise you take the other option of storing it encrypted all the time, then have a helper that the views call to decrypt when necessary. However, part of the poorer solution is quite interesting and may come in handy in other scenarios – binding private properties of a class with Entity Framework.

To make the chosen solution work, we needed to unmap the public property from Entity Framework which was achieved via the “NotMapped” Data Annotation. Then another private property was added to the class which would access the public property’s backing field without decrypting it. A code example it probably required here:

private string _topSecret;
[NotMapped]
public string TopSecret
{
  get
  {
    return Decrypt(_topSecret);
  }
  set
  {
    _topSecret = Encrypt(value);
  }
}

Where Encrypt and Decrypt could be any encryption algorithm. My proof of concept for the model binding tests just reversed the string. Not overly secret but effective for the testing.

 
[Column("TopSecret")]
private string ValueForDB
{
  get
  {
    return _topSecret;
  }
  set
  {
    _topSecret = value;
  }
}

You’ll see that the ValueForDB has the Column Data Annotation which allowed me to store the encrypted value in the database in a column with the same name as the publicly accessible property for the model.

By doing this we can use the TopSecret property of the model when writing LINQ queries against Entity Framework.

Since ValueForDB accesses the backing field directly, the value it will store/retrieve will always be the encrypted version.

TIP: If you are trying to use this slightly odd method of one property for the Application and one for DB access, generate your Controller and Views before you add the “NotMapped” Data Annotation to your public property. That way the auto generated Views will have HTML elements for the property.

The next step to slip our encrypted value into the database is telling Entity Framework how its supposed to bind against the private property ValueForDB.  We can do this by using a subclass in our model that inherits from EntityTypeConfiguration.

public class FortKnoxConfig : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<FortKnox>
{
    public FortKnoxConfig()
    {
        Property(b => b.ValueForDB);
    }
}

Edit: I missed a bit of code out (a somewhat vital piece) on the application specific DbContext class:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // model definition is additive so other declaration will be applied on top rather than replacing this one
    modelBuilder.Configurations.Add(new FortKnox.FortKnoxConfig());

    // no harm leaving this in as EF binding is additive
    base.OnModelCreating(modelBuilder);
}

In the generated Views I added in the TopSecret member to the include property of the bind attribute. I only needed to do this for the Create and Edit views as it wasn’t included by default, due to the NotMapped attribute being on the Property when I chose to Scaffold the Controller.

public async Task<ActionResult> Create([Bind(Include="ID,TopSecret,OtherDataWeDontCareAbout")] FortKnox fortknox)

Then after that it was pretty much run and go, firstly choose to Create a new record, in the screenshot below we choose every letter of the alphabet in order.

Screenshot of the Visual Studio 2013 scaffolding layout for the Create View of our Model

The next screenshot shows the data in the database after we created it. Notice that the TopSecret column has the letters of the alphabet, but they are all reversed. This means the “encryption” (and I use that term very loosely) has been applied and the data is “secure” (I just use that term plain incorrectly).

Screenshot of the Database Viewer built into Visual Studio2013 showing the database table holding our secret in encrypted format (not really encrypted, just reversed)

Finally this screenshot shows the index view after the create was executed. Inside the application you get to see the secret without its “encryption”.

Screenshot of the Visual Studio 2013 scaffolding layout for the Index View of our Model, showing  the record we added from the earlier create

This is not an exercise in how to secure data, it’s meant to show you how to enable binding private properties in Entity Framework.  The only way the database could get the encrypted (reversed) data would be through the private property. It is a bit of a roundabout way of showing this but it was a real world question. Also, I believe the person who asked the question is using a much better encryption algorithm than mine, something that actually encrypts.

The code for the whole project is available on github.

Trouble uninstalling sharepoint 2013 hosted app

I recently (this afternoon) had a problem with a local sharepoint 2013 install.  It was refusing to install apps fully then also refused to uninstall those failed installs.  Turns out my setup was missing the App Management proxy and I hadn’t configured the CNAME record for the application subdomain properly (it was pointing to the DNS server rather than the app server).

This post from MSDN covers everything you need to do from start to end.  http://technet.microsoft.com/en-us/library/fp161236.aspx

I just picked a couple of things from it that I could see were missing and et voila, all fixed and running properly.  It even managed to finish off the uninstall that was left pending, clever, no more sharepoint uninstalling apps problems for me (well, today at least)

 

could not be started because the hypervisor is not running

Hypervisor is not running – blaming BCD

I’ve recently been hit with the “could not be started because the hypervisor is not running” error.  I’ve attributed it to my new Windows Server 2012 install which is set to dual boot with my Windows 8 Pro install. The error goes on to give 3 explanations of why this is. The first two options didn’t apply as my hardware supports virtualisation and the BIOS had the settings enabled.  I know it supports virtualisation as it was working before the server installation.  I remember having to modify the BCD to get my system to play nice between Windows 8 and 2012 due to a linux partition I’ve subsequently removed.

My awesome powers of deduction led me to believe Option 3 was the thorn in my side.  Fixing that problem was made reasonably difficult thanks to shoddy documentation from Microsoft. Over the last few months I’ve noticed this as a recurring pattern, Microsoft’s documentation is somewhat lacking compared to how it used to be around 5 years ago.  I’m guessing a big organisational shift is responsible.

Hypervisor is not running – the solution

bcdedit /set hypervisorlaunchtype auto

If you have the required hardware and its enabled in the BIOS then the above command should fix your “could not be started because the hypervisor is not running” issues.

You don’t need to specify {current} when using the set command. I actually found it throws an error rather than setting the value if you pass across {current}.  You can check the parameter has been set by running the following command.

bcdedit /enum

Under the bootloader that has an identifier of “{current}” you should see the value at the bottom of the list. Reboot your machine and your virtual machines should now be working.

As a word of warning, don’t go playing with the “hypervisordebug” parameter in the BCD as I did. I discovered the USB keyboard and mouse no longer worked when the PC got to the login screen. Annoying. Thankfully I could remote in to it and delete the debug parameter.

Microsoft have made things more difficult by replacing boot.ini with this BCD functionality. Their lack of easy to find, good documentation makes things harder than it should be to fix anything other than trivial “how do I change the background picture” questions.

How to install Hyper-V on Windows 8 Pro

This is just a quick note to anyone who want to start with Hyper-V but can’t find it in the start menu. I had to search for how to install Hyper-V as I didn’t realise it wasn’t enabled by default, it took more than one search too as most sites advertising “Getting started with Hyper-V” advice assume you already have it installed?! So here is a quick description of how to install Hyper-V on Windows 8 Pro.

The steps necessary to install Hyper-V on Windows 8 Pro

Its an optional extra Windows component so you can add it by using the Programs and Features control panel utility (Win+W then type Program and select the Programs and Features icon OR Win+I choose Control Panel and find the Programs and Features Icon).  Once inside the utility, click on “Turn Windows features on or off”. In The resulting window, select Hyper-V. Click OK and your system will start to install Hyper-V.

The screen that let's you install Hyper-V on Windows 8 Pro (Windows Features)

Next, go read some of the getting started with Hyper-V articles and see how virualisation works. I managed to skip that step as I’ve been using Fedora’s built-in virtualisation tool (VMM) for a year now, Hyper-V doesn’t do anything drastically different other than being installed out of the box.

Linux network on Hyper-V

One thing to note, if you are installing Linux (for instance a minimal install of CentOS as I did) you might run into the issue I did with the Virtual Switch.  Using the normal Network Adapter results in Linux not detecting any network adapters and therefore leaving you stranded inside effectively a standalone air-gapped linux system.  This results in a very secure VM but maybe of limited use if you require it to work with anything else on your real or virtual networks.  If you add a Legacy Network Adapter, you can configure Linux to use DHCP and connect to the internet to install/update packages.