MVC Deployment – JavaScript – ReferenceError is not defined …

This had me stumped for a moment.

All the Javascript was there (linkable from bundle links in the page source), all the files were there, everything worked in dev (doesn’t it always?).

Anyway, if you’re seeing this error in your deployed applications there are a couple of steps to take.

Firstly you should download and install the Visual Studio tool JSLint.VS2012. Then set this up to show warnings and don’t set it up to fail the build. JSLint is not kind and very strict about things (your adherence to BP is your choice but recommended for sure!)

So, you deploy your app and BANG all your lovely JS is twatted. Never fear … pop over to your web apps Global.asax file and in the Application_Start method include this:

BundleTable.EnableOptimizations = true;

So now with this setting set you can launch your app in debug mode with all the Optimizations forced on to test minification and more closely model your testing to the deployed version.

Once you have that working and are seeing the problems more clearly you can start to work through the potential issues using the reports from your new JSLint VS plugin to fix the syntax and other formatting issues.

Share

MVC – Display Version Number in Your UI

If you ever want to display the version of your app in the UI (useful in development with lots of environments) you can do the following.

In your Global.asax start method you can add:

Version version = Assembly.GetExecutingAssembly().GetName().Version;
Application["Version"] = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision);

This somewhere in your site UI you can do this:

@HttpContext.Current.ApplicationInstance.Application["Version"]
Share

Build Process – TeamCity, NUnit, dotCover & Octopus Deploy

I’ve blogged about TC a bit in the past but I’ve just setup a whole new build process for my current project.

Added into the mix these days is dotCover and Octopus deploy. Have to say that I’m seriously impressed with the simplicity of this flow to release. Still a few elements of Octopus Deploy to get my head around (deceptively simple tool!). Anyway, as ever getting some of the reports configured took a while …

Get your coverage filters right in TeamCity:

+:<SomeString>*
-:*Test

If for instance your project is called JamSoft and all your application dlls are called JamSoft.blah or JamSoft.blah.blah then somestring should be “JamSoft” and of course you’ve suffixed all your test libraries with .Test haven’t you … 🙂

Unless you already have a tool you’re using I found the TeamCity internal instance of dotCover a good solution. I tried to get NCover 1.5.8 working and just gave up in the end, it’s old and getting problematic as far as I’m converned and since the TC internal solution is available use it. Saves some potential headaches.

I also had a few teething problems getting NUnit working this time around. I was using an installed version of NUnit 2.6.2. However on first build in TeamCity it could completely the initial compile process as it couldn’t find the dlls. I ended up switching over to using a NuGet NUnit package and then the compilation steps were fine. Bit odd since I was running the TC builds on my development machine so NUnit was definitely available.

As soon as I’ve got a couple of things ironed out with my use of Octopus Deploy I’ll no doubt blog about that as well, however for now I’m total noob so …

Share

Entity Framework Code-First Stored Procedures & Foreign Key Entities

I was recently looking at some changes I’d made to a project I’m working on using the Entity Framework for data access. I realised that as I had moved to using a stored procedure for the data retrieval I had lost the immediate loading of some of he object related by foreign keys. If you want to load the related entities, don’t do this:

var searchResults = _context.Database.SqlQuery<MyObject>("GetMyObjects" @UserId", inputTerm);

Do this! 🙂

var searchResults = _dbSet.SqlQuery("GetMyObjects" @UserId", inputTerm);

Executing the stored procedure on the DbSet rather than the DbContext object will load the foreign key related entities.

Tip: If your entities still aren’t loading, check to make sure you have marked them as virtual in the entity class:

public virtual Organisation Organisation { get; set; }
Share

Using HttpClient to Send Dates in URL Using AttributeRouting

After doing a lot of reading it appears that it is possible to do what I was attempting to do but it requires relaxing a lot of useful security measures in order to do so. Since there is a simple workaround it just doesn’t make sense to relax these measures in light of increased security risks.

The error I was getting at the API was:

A potentially dangerous Request.Path value was detected from the client (:)

Obviously this is the colon characters used to separate the elements of the time portion of the DateTime string. So I have made the following changes.

My Api action method now looks like this:

[System.Web.Http.HttpGet]
[GET("range?{startDate:datetime}&{endDate:datetime}")]
public HttpResponseMessage Get(DateTime startDate, DateTime endDate)

The dates are now defined as part of the query string rather than parts of the path itself.

To handle the creation of the query string I also have the following extension method:

public static string ToQueryString(this NameValueCollection source, bool removeEmptyEntries)
{
    return source != null ? "?" + String.Join("&", source.AllKeys
        .Where(key => !removeEmptyEntries || source.GetValues(key).Any(value => !String.IsNullOrEmpty(value)))
        .SelectMany(key => source.GetValues(key)
            .Where(value => !removeEmptyEntries || !String.IsNullOrEmpty(value))
            .Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), value != null ? HttpUtility.UrlEncode(value) : string.Empty)))
        .ToArray())
        : string.Empty;
}

Which is used in my client code like this:

var queryStringParams = new NameValueCollection
    {
        {"startDate", start.ToString(_dateService.DefaultDateFormatStringWithTime)},
        {"endDate", end.ToString(_dateService.DefaultDateFormatStringWithTime)}
    };

var response = httpClient.GetAsync(ApiRootUrl + "plots/range" + queryStringParams.ToQueryString(true)).Result;

The date service in my application simply provides the default date formatting string and uses this pattern:

“yyyy-MM-ddTHH:mm:ss”

The complete URI that is produced from this looks like:

http://localhost:51258/plots/range?startDate=2013-07-30T21%3A48%3A26&endDate=2013-08-06T21%3A48%3A26

Share

C# Query String Builder

Here is a nice little extension method for building your query strings in C#


public static string ToQueryString(this NameValueCollection source, bool removeEmptyEntries)
{
    return source != null ? "?" + String.Join("&", source.AllKeys
        .Where(key => !removeEmptyEntries || source.GetValues(key).Any(value => !String.IsNullOrEmpty(value)))
        .SelectMany(key => source.GetValues(key)
            .Where(value => !removeEmptyEntries || !String.IsNullOrEmpty(value))
            .Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), value != null ? HttpUtility.UrlEncode(value) : string.Empty)))
        .ToArray())
        : string.Empty;
}

Share