Secret Orange Web Log

Print if True/Not NULL - MVC Html Helper Extensions

Here are a few HtmlHelper extensions for ASP.NET MVC. Use them to print small conditional strings from within views.

using System;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace SecretOrange.Extensions
{
    public static class HtmlExtensions
    {
        public static string PrintIfTrue(this HtmlHelper htmlHelper, bool expression, string text)
        {
            return expression ? text : null;
        }

        public static string PrintIfTrue(this HtmlHelper htmlHelper, bool expression, string text, string elseText)
        {
            return expression ? text : elseText;
        }

        public static string PrintIfNotNull(this HtmlHelper htmlHelper, TObject obj, Expression> trueExpression) where TObject : class
        {
            return (obj != null) ? trueExpression.Compile().Invoke(obj) : String.Empty;
        }

        public static string PrintIfNotNull(this HtmlHelper htmlHelper, TObject obj, Expression> trueExpression, Expression> falseExpression) where TObject : class
        {
            return obj != null ? trueExpression.Compile().Invoke(obj) : falseExpression.Compile().Invoke(obj);
        }
    }
}

You can also print strings if an object is NOT NULL by using the following syntax:

<%= Html.PrintIfNotNull( Model.Person, p => p.Shoes.Colour ) %>

The above line of code is basically saying: If Model.Person is not null then print Model.Person.Shoes.Colour

jQuery tabs and Stylish Select disabling all tabs in IE

There is an issue with an incompatibility beween jQuery tabs and The Stylish Select plugin.

Stylish Select defines Array.prototype.indexOf which doesn't well with jQuery.

Calling .tabs() will result in all tabs being disabled, apart from the selected tab (I've only noticed this in IE).

As a workaround I temporarily destroy the reference to indexOf, call tabs() then hook the reference back up again. Pop the code below into a common js file.

SecretOrange._ArrayIndexOfTempStorage = null;
SecretOrange.RemoveIndexOfReference = function() {
    SecretOrange._ArrayIndexOfTempStorage = Array.prototype.indexOf;
    Array.prototype.indexOf = null;
}

SecretOrange.RevertIndexOfReference = function() {
    Array.prototype.indexOf = SecretOrange._ArrayIndexOfTempStorage;
}

And then use:

SecretOrange.RemoveIndexOfReference();
$("#MyTabs").tabs();
SecretOrange.RevertIndexOfReference();
All should be fine.

nunit assert byte arrays are equal

Using NUnit? Want to Assert that two byte arrays are equal?

Dont use Assert.AreEqual(a,b);

Use: CollectionAssert.AreEqual(a,b); instead!

Ning to phase out all free social networks

I just recieved this email from Ning stating that they are planning to phase out all free social networks starting in July. Sounds like the base pay for package is cheap as cheaps but I bet there will still be a couple of disgruntled cusomters out there!

Hello! We're writing today to let you know about some new and exciting changes coming to Ning. In July, we're doing two very important things:

1. We'll be phasing out all free Ning Networks.

We want to provide a new level of innovation to Network Creators - and build all the valuable features Network Creators have asked us to. To get there, we need to focus 100% on paid Ning Networks. This phasing out of free services won't happen until July, so you'll have plenty of time to weigh your options. We'll do our best to provide you with a migration path if you don't wish to continue with Ning, but we'd love to have you come along for all of the exciting future developments.

2. We're introducing new plans and pricing.

To help make it easy for you to come along with us, we've created new plans for every kind of Ning Network: big, small and in between. We think you'll find these new options affordable for almost every budget - as little as $3/month. That's an unprecedented deal that even allows you to go ad-free.

The plans will be available in July, but you can get a sneak peek at the details here.

What does this mean for my Ning Network?

While nothing is going to be changing today, we encourage you to check out the upcoming plans. If you don't wish to continue as a Network Creator, we'll be following up with you in the coming weeks to provide you with details on how to close out or migrate your Ning Network. You'll have plenty of time to make the best decision for you and your members, and we'll do our best to make that decision as easy as possible.

What if I have more questions?

We thought you might! We've put together a list of FAQs that will help answer many of your questions. Nothing will be changing immediately, and we'll be contacting you again via email with more details.

Give me top n comments for all my entities please

A quick TSQL Nugget.

I recently needed to pull from the database a list of top 3 comments for all "objects"

Using the TSQL ROW_NUMBER() function with PARTITION makes this easy!

SELECT 
  ObjectID, CommentID, ROW_NUMBER() OVER ( PARTITION BY ObjectID ORDER BY CommentID DESC ) AS RowNumber
FROM 
  dbo.Comment

Set hidden value jquery

Setting the value of a hidden field with jQuery is easy. Simply use the val() function.

$("#MyHiddenField").val("my value");

Control alt delete remote desktop

How do you perform a Control - Alt - Delete when using Remote Desktop?! Simple, just use Control + Alt + End instead....easy!

LINQ to SQL UPDATE SET WHERE 0 = 1 WTF?!

Ok, just a quick one...this had me stumped for over an hour!

I wanted to simply update one column on a "user" object in the database. So, I retrieved the object from the DB, set the new value and called SubmitChanges. I then get hit with a ChangeConflictException.

It was a fresh DataContext and the property in the DBML file looked OK. I then checked the output of the SQL and it looked something like:

UPDATE User
SET CalendarID = @p0
WHERE 0 = 1

What was the 0 = 1 where clause all about? As it turns out I think its meant to be some kind of LINQ to SQL optimisation gone wrong...anway this started to lead me down the right path and I ended finding out that it was another "user" property in the DBML file that was causing the problem. I had a column name "DisplayName" which was set as NULL in the DB but not nullable in the DBML file. Fixing this seems to have solved the problem...even though the DisplayName property had nothing to do with the UPDATE.

Could not translate expression LINQ to SQL UNION

I just got the following error when trying to UNION two LINQ to SQL queries:

Could not translate expression 'Table(EventMembership).......blah blah blah...' into SQL and could not treat it as a local expression.

To see what was going on I ToList() the two queries individually and pasted the generated output into SQL Server Management Studio and then tried a UNION ALL on the two queries.

Guess what? The SQL blew up!

All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

But the shapes of my LINQ classes are identical...whats going on? Why is the translated SQL dropping some of the columns and causing the shapes of the two queries to be different?

I then noticed that the second query was referencing the same column twice...something like:

select new { FirstName = e.EventName, LastName = e.EventName }

Now, when LINQ to SQL translates to TSQL it spots the identical columns and thinks to itself "ok, I could be smart here" and decides to only pull back one of the columns and fixes it clientside. This is good for performance but NOT when you want to UNION the result sets!!! Presumably, LINQ to SQL should check first if a UNION operator is be used and if so then makes sure the shape of the data for all queries involved is the same...but it looks as if we are going to have to live with this bug for now.

So, to get round the problem you are going to have to ensure that each property of your select object is referencing a different column or atleast do something that will force LINQ to SQL to include it in its translated SELECT list.

IIS 7 Compression Problems

I noticed recently that IIS7 wasn't compressing my static files even though IIS looked as if it was configured correctly.

After an hour of googling and tinkering I had found a great feature in IIS which allows you to view the cycle of a request to which helped diagnose the problem.

First of all I had to install and enable failed request tracing.

Once you have enabled failed request tracing select your site node and then in the features view, click 'failed request tracing rules'. Click add, next, enter 200, next, click finish.

Now, request a file which you expect to be compressed...this should generate some log files.

By default you should be able to find them in c:\inetpub\logs\FailedReqLogFiles\w3svcx. Open some of the files in IE and find one which is a request for a static file. Next, click the 'request details' tab and have a look at the request cycle.

Search for STATIC_COMPRESSION_START

On my server I then found the following trace:

STATIC_COMPRESSION_NOT_SUCCESS

Reason 14
Reason  NOT_FREQUENTLY_HIT

The NOT_FREQUENTLY_HIT reason seemed like that could be the issue as the website in question isnt busy at all. As is turns out it looks as if IIS doesn't bother compressing files which aren't frequently hit...which I dont really see the point of (but I'm sure there must be one!) as long as the server has enough spare CPU why not send back a compressed response?

Anyway, I ended up finding the config element below:

<serverRuntime frequentHitThreshold="1" />

Which I set in:

C:\Windows\System32\inetsrv\config\applicationHost.config

Setting frequentHitThreshold="1" seemed to do the trick...all my js/css files etc are now compressed. Happy days.