Online Tool: UnminifyCode

If you’re a web developer, regardless of what programming language you are using, you’ll be familiar with minified CSS, Javascript and HTML files. For the uninitiated these are files which have had unnecessary whitespace, line breaks and formatting removed with variable/function names shortened where applicable.

While this results in files that are difficult for humans to read, browsers are still able to load and parse the data (unless the minification process has been a bit heavy-handed).

These files are normally used in preference over the unminified versions because of the reduced file size – making for quicker page load times.

That’s all well and good, but what happens when all you have is a minified file, from say a third party library, and you want to edit or, in the case of Javascript, add breakpoints to debug one of these files?

Continue reading “Online Tool: UnminifyCode”

Roll my own DDNS? Why Not.!

Update: Well, there’s certainly more to Dynamic DNS than meets the eye – who knew.

Investigations led to the decision that I should put my hand in my pocket and spend my time better elsewhere.

Not that I opted for the overpriced offering from Oracle, signing up with NoIp instead.

Like many devs I have been known to host websites and services behind my home broadband router and therefore needed a Dynamic DNS resolver service of some description. But in my recent moves to limit my reliance on third-party services – including those provided by Google – I wanted to see what would be involved in creating my own service.

Why would I want to roll by own?

Over the last few years I’ve moved my hosted websites outside of my home network and onto services offered by Digital Ocean so I was only really using my DDNS provider for a single resource – my Synology NAS.

Now, in the past I’ve used DynDNS (an Oracle product) and while I’ve had no issues with the service it’s not what you could call cheap – currently starting at $55 a year. When a previous renewal came through, and after reviewing what I was using it for, I decided to let it expire and do without the access to the NAS from outside my network.

Continue reading “Roll my own DDNS? Why Not.!”

Online Tool of the Month – unminify.com

Minification and bundling of Javascript and CSS files is obviously a good idea when you are deploying your websites to production – but if you want to use a third-party, minified, resource and want/need to look at the unminified version – it can be a bit of a pain.

I recently purchased a theme for a website which came as a set of CSS, Javascript and image files. There were a number of pages which demonstrated the theme and it was pretty much what I wanted – but not quite, I needed to make a few very minor changes.

These changes were limited to styles which specified ‘hero blocks’ with image backgrounds. I didn’t need a block with an aircraft in the background – I needed one with a camper van.

Continue reading “Online Tool of the Month – unminify.com”

Online Tool of the Month – SelfSignedCertificate

In this day and age everything needs to be encrypted to prevent nefarious access to our data. Whether it’s our banking or medical records, our online email inboxes or our browsing and searching habits.

So, when developing websites or APIs I always start with an SSL enabled configuration – and in Visual Studio that’s a pretty easy thing to do, it’s just a checkbox really.

When deploying websites to production servers I, like millions of others, use LetsEncrypt to generate and renew my SSL certificates.

But what about that gap between Development and Production? I am of course talking about ‘Test Servers’.

Continue reading “Online Tool of the Month – SelfSignedCertificate”

Online Tool of the Month – realfavicongenerator.net

Following the migration of this website to WordPress I installed the ‘redirection’ plugin in an effort to handle the difference in the url structure used by Squarespace (my previous host/platform). This plugin allows me to redirect users using the old Url to the correct content and also see any 404 errors for resources I may have missed.

While reviewing this 404 log I noticed a few rather odd entries, such as

  • apple-touch-icon-precomposed.png and
  • apple-touch-icon.png.

Knowing that I never had such content on the site before I did a bit of Googling and found that these are favicons (the little square logos that reside on your browser tabs) that Apple’s Safari browser will attempt to load along with your page.

Now that I knew what the problem was, how do i fix it? I mean, I had a favicon on the site – why couldn’t Safari just use that one?

After a bit more searching I found the Real Favicon Generator site where I was able to enter the Url of my site and it would generate a report on what it found (or didn’t find as the case maybe).

This is actually for another site I manage but the result is similar to when I ran it on this site

Now, that’s a lot of red but fear not – help is at hand. As the sites name eludes, it is also able to generate the appropriate icons as well. But how will I get these into WordPress – it only has the facility to allow me to specify a single favicon file.

Well – as well as the testing of the site and generation of the icons, there is also a WordPress plugin which makes things super easy.

With the plugin installed, navigate to the Appearance menu and select ‘Favicon’.

Select your desired image, they recommend 260x260px but mine was 150x150px and it looks fine for my purposes.

Click Generate and you will be taken to an editor page which allows you to tweak a few colours and settings – I didn’t bother with this, I just clicked the ‘Generate your Favicons and HTML code’ button at the bottom of the page.

And that’s it – I re-scanned the site and (unsurprisingly enough) everything was now green – and the 404 errors are no longer appearing in the redirection logs.

A New Freelance Project – and a Chance to Use .Net Core on Linux

I was recently approached by a website owner, who had seen the FillLPG for Android application and wanted a similar mobile application, i.e. an app which displayed a number of points of interest on a map and allowed it’s users to select a location and have further details displayed.

With my experience with FillLPG I was happy enough that I would be able to create applications to render the map with the points displayed in the appropriate location. The big question is – where is the data coming from?

The current situation

The website in question is fairly dated, in the order of 10 years old, written from scratch in PHP (not something like Drupal or Joomla) and backed up by a MySQL database.

The existing database is somewhat badly structured (in terms of todays programming practices) with no foreign keys, endless bit fields for HasThis and HasThat properties and a disjointed table structure (properties which you would think would reside in one table are in fact in another – manually linked by an id value).

There is no API that I can access from the mobile application – it’s just not there and there is no resource to create one.

The way forward

So, how do I access the data return it in a sensible format?

After a bit of thought I decided that the best option would be for me to create a WebApi project for the mobile apps to access. This project will access a separate MySQL database (with a structure more in line with what I need) which will be populated & updated by a utility program that I will also develop and execute on a regular basis (this is not highly volatile information that changes frequently).

So why .NET Core? You don’t need that to develop a WebApi project!

Glad you asked and my initial reply would probably be – ‘Why not?’. As a contractor I feel it is vital to keep your axe sharp and your skills up to date. I’m starting to see a few contracts now for .NET Core so it makes sense to keep my skills relevant.

After come careful analysis I decided that the most cost effective hosting for this solution was on a Linux based server. Yes, I know I can do that on Microsoft Azure but there are far cheaper services out there offering Linux hosting, so I’m going to use one of those.

Now, the only reason I can even consider using a Linux host is because of .NET Core. This allows me to develop using .NET technologies and C# – my development stack of choice.

But would it allow me to do what I intended to do? Could I create a WebAPI application to allow the mobile applications to access the data? What about the ‘Data Shuttle’ utility that will populate and maintain the data between the website database and the new WebAPI one?

Well, I’m happy to say that the answer to that question is yes, it will – and it did.

I’m writing this post after developing the initial, server side components, i.e. the Data Shuttle and WebAPI, and everything it working well – you would not know from the outside that the endpoints are not hanging off an Azure instance.

There were some pain points along the way and I’ve not answered all of my questions quite yet, things like logging and error notification, but everything I need for a Minimum Viable Project (MVP) are now in place from a server side perspective.

I have a handful of posts drafted at the moment which will dive deeper into the development for this project but here are a handful of links that you may find helpful in getting started:

 

Online Tool of the Month – BuiltWith

Have you ever looked at a website and thought ‘I wonder what that’s written in’? Well, even if you haven’t I certainly have which is why I was interested to hear about BuiltWith.

Simply put, BuiltWith puts websites under the microscope and produces a detailed report about what it sees.

From Webservers and SSL Certificate providers through programming languages, Javascript libraries, content management systems and advertising platforms it sees it all. The produced report contains links to allow you to see technology trends across the Internet which may well assist with infrastructure decisions for your next project.

Pointing BuiltWith at this site I was able to see that not only were the current technologies being listed, including the current version numbers where applicable, but it also reported that 56 technologies had been removed since July 2012 (I migrated from SquareSpace to WordPress fairly recently).

Registering for a free account would allow me to see much more detail and view historical data but for now I have found the open version sufficient for my needs.

 

Online Tool of the Month – Polyfill.io

Browser compatibility is a pain – and that’s a fact. But when your client says, “we need to support IE9 and upwards” you can feel the dread come over you.

Well, fear not as help is at hand in the form of Polyfill.io, a CDN hosted service which will serve up a custom set of polyfills to fill those functionality  gaps in whatever browser makes the call.

Need some of those ‘Math’ or ‘console’ functions that are so readily available in non-IE browsers? Well, Polyfill.io has your back.

Add a single line of code to your mark up and voila – you’re good to go. Remember, before you start panicking about large request sizes the CDN will tailor the response to only those features that the current browser is lacking, which is pretty neat.

From the feature list on their site it is easy to see what is included naively in each browser and what can be polyfilled.

But there’s more – what if you only wanted a single feature, say ‘Function.name’, in IE9/10&11. Even though the service will return a tailored set of polyfills it is possible to view the detection and polyfill scripts for any feature by clicking on the ‘hamburger’ menu to the right of the feature – this takes you to the appropriate location in the Github repo (yep, this is all open source stuff).

The downside to using a CDN though is that if it goes down (and it did once for a client of mine) then it could leave your site somewhat ‘hobbled’ depending on the features you were relying on

Stackify Prefix – first thoughts

Listening to one of my favorite podcast (.Net Rocks) I heard a plug for the Stackify Prefix tool which claims to help the developer fix problems before anyone else sees them – a bold claim. Well as I am currently working on a greenfield development project I decided to give is a whirl – it’s free after all so why not.

Now I was not expecting to find too much wrong with the application and thankfully I was right – but I was getting errors.

The highlighted call is to a WebAPI method from an AngularJS controller (a JavaScript file on the client) and as you can see from the right hand pane it does succeed. In fact the data is returned as I’d expect and the application works without any issue. So why is Prefix flagging this?

Well, looking at the stack trace a little more carefully I see that the exception is being raised by the XmlMediaTypeFormatter when it is creating it’s default serializer. But the WebAPI is returning JSON so why it is spinning up an XML serialiser?

Well, my WebAPI endpoint took this form:

https://gist.github.com/OnTheFenceDevelopment/c8bc6729ad09d3b60579f191ffafeec7.js

The problem is on line 8 where I’m returning the OK status with the required content – which is an anonymous object that I’ve just put together on the fly. The WebAPI is configured to accept the ‘application/json’ header and to use an appropriate JSON Formatter – which it does.

The problem is that I still have the default XML Formatter in the list and for some reason the framework is trying to use it to serialize my anonymous object – and failing (silently).

So all I need to do is to remove the Formatter during the WebAPI registration – within WebApiConfig.cs in the App_Start folder (see line 12 below).

https://gist.github.com/OnTheFenceDevelopment/5441c335465d87e2c9addb19d29eed2c.js

Now this was fairly trivial but a bug is a bug and as we know – exceptions are expensive. They take time to raise while they pull the required information together and work their way through to the calling code – which in this instance appeared to simply discard it. A small performance hit but if this scaled then it could have become a bigger problem in the future – and probably harder to find.

Prefix highlighted it straight away and the issue is now fixed. It never made it to production, in fact it never made if off my desk – it was Pre-Fixed!

StructureMap and MVC5 – Resolving the resolution exception for IUserStore

I’m currently working on an MVC5 website which uses StructureMap for Inversion of Control operations. Everything was working fine but then I started to get exceptions when I ran the application and attempted to login (not sure if Update 3 was responsible for surfacing this problem but it certainly worked without any problems previously)

Now, clicking ‘Continue’ in Visual Studio (or pressing F5) allowed the application to continue with no further issues but I wanted to get to the bottom of this issue – I certainly didn’t want this coming back at me when the site goes live.

Clicking on ‘View Detail’ I found the following error message which seemed surprisingly informative;

No default Instance is registered and cannot be automatically determined for type ‘IUserStore<ApplicationUser>’

There is no configuration specified for IUserStore<ApplicationUser>

1.) new ApplicationUserManager(*Default of IUserStore<ApplicationUser>*)
2.) MyDiveLogs.ApplicationUserManager
3.) Instance of MyDiveLogs.ApplicationUserManager
4.) new AccountController(*Default of ApplicationUserManager*, *Default of ApplicationSignInManager*)
5.) MyDiveLogs.Controllers.AccountController
6.) Instance of MyDiveLogs.Controllers.AccountController
7.) Container.GetInstance(MyDiveLogs.Controllers.AccountController)

So – what does that mean?

Well, in a nutshell it means that StructureMap could not determine how to create a concrete instance of IUserStore, which is required to create an ApplicationManager instance which is in turn required to create the AccountController.

This is caused by StructureMap being ‘greedy’ and will attempt to use the constructor with the most parameters. In the case of the AccountController it will ignore the parameterless constructor and try to use the one that requires an ApplicationUserManager (the root of my issue) and an ApplicationSignInManager.

Having trawled around the web trying to locate a resolution I’ve found a couple of options;

  • Tell StructureMap to use the parameterless constructor instead or
  • Tell StructureMap how to instantiate the instances correctly

The first option is a simple matter of adding an attribute to the AccountControllers parameterless constructor as below;

[DefaultConstructor]
public AccountController()
{
}

This works fine and if you are worried about how the AccountController will function without being given an ApplicationUserManager and ApplicationSignInManager to use then fret not – take a look at its UserManager and SignInManager properties. The getter will perform a null check and create the appropriate instance as required.

Interestingly, this helps us with the second option for resolving this problem, i.e. telling StructureMap how to create the instances for us.

Locate the IoC.cs class (mine was in a folder called DependancyResolution in the main MVC project) and update the Initialize method as below (note that you may have to import some namespaces)

public static IContainer Initialize() {
    return new Container(c =>
    {
        c.AddRegistry<DefaultRegistry>();

        // ADD THESE LINES
        c.For<Microsoft.AspNet.Identity.IUserStore<ApplicationUser>>().Use<Microsoft.AspNet.Identity.EntityFramework.UserStore<ApplicationUser>>();
        c.For<System.Data.Entity.DbContext>().Use(() => new ApplicationDbContext());
        c.For<Microsoft.Owin.Security.IAuthenticationManager>().Use(() => HttpContext.Current.GetOwinContext().Authentication);

    });
}

And that’s it – you should now be able to access Actions within the AccountController without this exception being thrown.

Parsing Json Dates from MVC Controller Actions in Client-Side Javascript

Recently I’ve been working on a couple of MVC projects where I was using jQuery to perform an AJAX call to a controller action which in turn returned some JSON data. This is pretty run of the mill stuff but each time I hit a problem with dates.

Dates are always a problem in development, whether it’s storing them in a database or displaying them on the screen. How do you deal with timezones and formatting between cultures? As it turns out the solution to my issue was pretty straightforward and a single line of Javascript resolved the problems.

Consider the following MVC Controller Action

public ActionResult GetJSONData(){
    return Json(new{ Id = 1, 
                     Name = 'Joe Bloggs', 
                     DateOfBirth = '21/05/1970'});
}

If you now add a JQuery AJAX call from a View like so;

$.ajax({
    url: 'Home/GetJSONData',
    method: 'GET'
}).success(function (data) {
    .
    .
    $('#dateOfBirth).text(data.DateOfBirth);
});

You may expect the DateOfBirth value to be displayed as defined in the controller action but it will instead be displayed as “/Date(1423124521)/”

You’ll probably recognise that as a UNIX epoch Timestamp value and you’ll know that Javascript has a built-in function to convert it to a Date object – but what’s the best/easiest way to actually get the value out of the JSON data, i.e. remove the surrounding text?

I looked at Regular Expressions and string manipulations etc but in the end I settled on this;

var dateOfBirth = 
    new Date(parseInt(data.DateOfBirth.substr(6)));

The ‘trick’ (if that’s the right word here) is the parsing of the string to an Int while only removing the leading text – the trailing characters, “)/”, are ignored by the conversion and a corresponding Date object is created.

Of course, stripping off the trailing characters would certainly have been possible but that looked quite ugly in comparison. This single line of code does the job so there is no need to complicate the process and degrade readability/maintainability.

Validating Start/End Dates with Fluent Validation for MVC 4

In my current contract I needed to add date filtering to a grid of search results in and MVC view – how hard could it be?
Well the filtering was the easy bit, validating the user input proved to be much more problematic. The view that I had contained, among other things, a couple of fields for Start and End Date where the user would select the dates using a jQuery date picker. I knew that I could rely on standard MVC validation to make sure that the user had entered a valid date, but how do I ensure that they have entered an End Date that falls AFTER the Start Date? This simple requirement is not something that can be acheived with the standard Data Annotation attributes but I was lucky as the project already had made use of the FluentValidation extension.

Creating a custom validator using FluentValidation is pretty simple as below:

public class SearchValidator: AbstractValidator
{
    public SearchValidator()
    {
        RuleFor(m => m.StartDate)
            .NotEmpty()
            .WithMessage("Start Date is Required");
 
        RuleFor(m => m.EndDate)
            .NotEmpty().WithMessage("End date is required")
            .GreaterThan(m => m.StartDate.Value)
                            .WithMessage("End date must after Start date")
            .When(m => m.StartDate.HasValue);
    }
}
This validation will ensure that the user has entered something in the Start Date (standard validation will ensure that the date is valid) and that an End Date has been entered and is later than that Start Date.

Wiring this up to the view model is a simple matter of adding an attribute to the class:

[Validator(typeof(SearchValidator))]
public class SearchViewModel
{
    public DateTime? StartDate { get; set; }
 
    public DateTime? EndDate { get; set; }
}
The final steps are to add the markup to display the resulting validation messages;

Start Date: @Html.EditorFor(m => m.StartDate)
@Html.ValidationMessageFor(m => m.StartDate)
 
 
End Date: @Html.EditorFor(m => m.EndDate)
@Html.ValidationMessageFor(m => m.EndDate)

and to ensure that the validation is triggered in the Action Method;


if (ModelState.IsValid)
{
    // do stuff and return the Search view
    return View("Search");
}
else
{
    // Validation has failed, return the same view with the model
    return View(model);
}
Now when the user clicks the Search button the validation will ensure that Start and End Dates are entered and that the End Date is later than the Start Date. What's more, will be applied on the ViewModel wherever it's used - you don't have repeated code in your action methods.

Discovering T4MVC – Replacing Literal Strings with Strongly Typed Helpers

One of the things I love about working as a contractor is getting exposure to technologies, tools and utilities that will improve my coding and help me produce better code – geeky but true.
My most recent contract is no exception and this time I’ve decided to share this little gem of an extension which will remove those pesky literal string from your MVC Views.

Any developer who has worked with MVC will have written code similar to the following:

@Html.ActionLink("Edit", "Edit", "Magazine", new { Id = Model.Id }, null)
This will create a simple "Edit" Hyperlink which is call the "Edit" action method on the "Magazine" controller passing an "Id" parameter and there's nothing wrong with it. But what if you change the name of the action method, or come to that, the controller itself? Imagine hunting down every instance of the of a string literal and changing it; possible yes but time consuming and can you be sure you got them all.

Enter T4MVC – a simple T4 Text Template which generates a new class within the project that provides strongly typed helpers that can be used in place of the string literals.

The extension can be installed via NuGET and will add a few files to the project, the most important of which is ‘T4MVC.tt’. By right-clicking on the file and selecting ‘Run Custom Tool’ the magic happens and a new helper class called ‘MVC’ is generated.

With the helper class generated the above code could now be written as follows:

@Html.ActionLink("Edit", MVC.Magazine.ActionNames.Edit, MVC.Magazine.Name, new {id = Model.Id}, null)
Notice how the action and controller names have been replaced with strongly typed string values.

Whenever you add, remove or change an action method (or a controller come to that) just right-click on the ‘T4MVC.tt’ file and run the custom tool to regenerate the helper class. If an action method had been renamed or removed then every instance of it being referenced as above would now cause a design-time compiler error which makes them super simple to locate and when the build succeeds you can be sure that you have no errant references to non-existent action methods.

Hopefully you will find this as useful as I did – I’ll be sure to include this in all my MVC projects from now on.

One drawback I found with using T4MVC was that I had to remember to regenerate the files each time I made a change to the controller methods, if I didn’t then I could get a compiler error – which is of course the point of the extension, but frustrating when you forget.

Well, help is at hand with another, zero configuration, Visual Studio extension called AutoT4MVC – which essentially triggers the regeneration whenever the project is built.
To install the extension just open up the NuGet manager and search for AutoT4MVC, install, restart Visual Studio and you’re off – no configuration and no face/palm when you forget to regenerate before building/debugging. Simple!

Using Client-Side jQuery to Send Data to Server-Side .NET

Back in March 2009 I wrote a blog post about calling code-behind methods using Javascript and while looking at my Google Analytics recently I was surprised to see that this post still receives about 650 hits a month. Why am I surprised? Well the post is almost three years old now and with technology moving on at a rapid rate there are much better (i.e. easier and cleaner) ways of sending data from the client to the server. In this post I’ll demonstrate just one of them which uses jQuery and a standard ASP.NET web application, i.e. not MVC although there is no reason why this approach will not work just as well there as well.

The original code was taken from a DotNetNuke module I wrote to add geocoding functionality to blog posts. The user would locate their position on the map and when the post was saved the coordinates would be sent back to the server and associated with the it. The issue at the time was that I was using Virtual Earth for my mapping and as it was not a server-side .NET control but generated by a Javascript library on the client it was not a simple case of writing

long latitude = map.Latitude;

While working on a recent contract I was using the Google Maps API and jQuery on the client with ASP.NET user controls written in C# on the server and was surprised how easy it was to hook everything up.

In case you experience any problems (if I don’t explain something well enough or miss something out) I’ve uploaded a fully working VS2010 solution to this post.

After creating a standard ASP.NET Web Application using Visual Studio there are a couple of things that need to be done before we can get started.

When Visual Studio created the project it placed three jQuery files in scripts folder – but these are now out of date and we will be using functionality which is not available in these older versions.

  1. In Visual Studio expand the Scripts folder and delete the three files it contains
  2. Download the latest version of jQuery from here
  3. In Visual Studio, Right Click on the Scripts folder and select ‘Existing Item’ from the ‘Add’ menu
  4. Locate the jQuery file you downloaded above and click ‘Add’

Your Solution Explorer should look something like this:

With the latest version in our solution we now need to reference it in our web page so that we can actually use it.

  1. Double-Click on the Default.aspx file in the solution explorer to open it
  2. Add the following line within the head tags (you may need to change the jQuery filename depending on the version you downloaded)

While we are at it we may as well add the reference to the Google Maps API – add the following line between the head tags (you can add this as a single line)

"text/javascript"
    src="http://maps.googleapis.com/maps/api/js?sensor=false">

Now to add some controls to the page. We need a div element where the map will be injected, a couple of textboxes to display the latitude and longitude and a button to trigger our save operation.

Replace the content of the body tags so that it looks like this:

<body>
“map” style=“width: 450px; height: 300px;”>

    Latitude:
    <input id="txtLatitude" type="text" />
    Longitude:
    <input id="txtLongitude" type="text" />
    <input id="btnSave" type="button" value="Save Coordinates" />
“message”>

</body>

If you run the application now you will see the text fields and the button but not the Map because it’s not wired up yet – so let’s do that now.

Beneath the two script tags we added to the head add the following (I’ll explain what it’s doing afterwards):

"text/javascript">

 
 
    // Global Variable for the Map itself
    // This allows us to access it from multiple functions
    var gmap;
 
    $(document).ready(function () {
        // Initialise the map
        initialiseMap();
    });
 
    // Initialise and configure the map
    function initialiseMap() {
 
        // Options array to set the initial center point, zoom level 
        // and map type.
        var myOptions = {
            center: new google.maps.LatLng(53.8693, -1.4941),
            zoom: 4,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
 
        // Initialise the map and send it to the map div
        gmap = new google.maps.Map(document.getElementById("map"), myOptions);
 
        // Place Crosshairs Marker in centre of map
        var marker = new google.maps.Marker({
            map: gmap,
            icon: 'cross-hairs.gif'
        });
 
        marker.bindTo('position', gmap, 'center');
    }
 
//-->

You’ll notice that on line 29 we refer to an image called cross-hairs.gif which is not currently in our solution. You can download the one I’m using from here and then add it to the root of the project in the same way as you did with the jQuery file earlier (just right-click on the main project file rather than the Scripts folder).

Lines 7-10 form the jQuery .ready function which will be executed when the page DOM has fully loaded. In this instance we are calling out to a Javascript function called initialiseMap which is defined between lines 13 and 33 and in itself it quite unremarkable.

The myOptions variable is essentially a JSON object which contains the following settings which will be applied to our map:

  • The initial position of the center of the map – in the form of a Latitude/Longitude pair
  • The initial zoom level
  • The initial map type

Line 24 is where the mapping magic happens – a single line of code but this generates the map, using the options we provided, and injects it into the map div.

After that we are creating a marker in the form of the cross-hair image we added earlier. Line 32 fixes this to the center point of the map – i.e. it will remain in a fixed location while the map pans beneath it. This lets us ‘target’ a specific location on the map.

If you run the application now you should see something like this (you should be able to see the cross-hairs in the Leeds area):

You should be able to pan the map around, zoom in/out and change the map type to your hearts content but the latitude and longitude values will not update and clicking on the button won’t do anything yet.

First let’s wire up the coordinate fields to update as we pan the map. Add the following lines to the jQuery ready function beneath the call to initialiseMap.

// Add a Listener to the Map to trigger when the user pans the map
google.maps.event.addListener(gmap, 'center_changed', function () {
    // Update the Lat/Long Fields
    getCoordinates();
});

This adds a listener which will be triggered when the center coordinate of the map is changed, i.e. when we drag the map around. When it is triggered it calls the getCoordinates function – which we’ll add next.

Add the following somewhere within the script tags.

// Update the Coordinate fields with the current map center-point values
function getCoordinates() {
    var centre = gmap.getCenter();      // Will return a LatLng object
    $('#txtLatitude').val(centre.lat());
    $('#txtLongitude').val(centre.lng());
}

All we are doing here is resolving the coordinates of the maps current center point and placing the values into the appropriate fields.

Run the application now and pan the map around – you should now see the coordinate values update as you do.

So at this point we are able to pan and zoom the map around and see the latitude/longitude coordinates represented by the cross-hairs. What we want to do now is to send them to the server for processing without causing a postback.

To do this we will use the jQuery $.post function – which will, unsurprisingly, perform a POST request containing the values to the location we specify.

The first thing we are going to do is to create a server-side ‘handler’ for the POST request to call into. I say ‘handler’ because we are actually going to use an ordinary webform in this instance – just to keep things simple.

  • In Visual Studio, Right-Click on the project and select ‘New Item’ from the ‘Add’ menu
  • In the Add New Item dialog, select ‘Web Form’ and call it CoordinateHandler.aspx
  • Click ‘Add’

Update the Page_Load event as below (you will also need to add the System.IO namespace):

protected void Page_Load(object sender, EventArgs e)
{
    if (Request.Form["Latitude"] != null && Request.Form["Longitude"] != null)
    {
        try
        {
            // Lat/Long have been specified - save them
            using (StreamWriter sw = 
                      File.CreateText(Server.MapPath("/") + "coordinates.txt"))
            {
                sw.WriteLine("Latitude: " + Request.Form["Latitude"]);
                sw.WriteLine("Longitude: " + Request.Form["Longitude"]);
                sw.Flush();
                sw.Close();
            }
        }
        catch (Exception)
        {                    
            throw;
        }
    }
}

Nothing too scary here – we are just checking the Request to see if it contains form values for Latitude and Longitude. If so we are just going to extract them save them to a file on the server (to prove they made it from the client). Your logic will obviously be more involved but once you have the values server-side you can pretty much do as you please with them.

While we are in Visual Studio we can remove everything except the @Page directive from the CoordinateHandler.aspx markup – we don’t really need it as the page will never be displayed anyway.

All we need to do now is to wire up the Save button to perform a POST request to our CoordinateHandler and pass the values displayed in the textboxes.

In the real world you probably would not use textboxes as the user could enter anything into them and send it to the server – which is not a good idea. I’d also resolve the coordinates directly from the map at this point but I’ve left is as is just for simplicity.

Add the following lines to the jQuery ready function beneath the listener we added previously.

// Attach function to Save button
$('#btnSave').click(function () {
    // Send the coordinates to the server via the CoordinateHandler page
    $.post(
        'CoordinateHandler.aspx',
        { 
          Latitude: $('#txtLatitude').val(), 
          Longitude: $('#txtLongitude').val() 
        },
        function (responseText, textStatus) {
            // This function will execute if the post was successful
            $('#message').text('Coordinates Saved Successfully');
        })
        .error(function () {
            // This will execute if there was an error with the post request
            // Note: jQuery 1.5 or higher required for this 
            $('#message').text('There was an Error');
        });
});

What we are doing here is binding a jQuery $.post() function to the Save button which will send a request to the CoordinateHandler (line 5) containing the current Latitude/Longitude values (line 6). Note that the names (and case) of the values being POSTed match those in the Page_Load of the CoordinateHandler. Lines 7-10 defines what should be done if the POST is successful while line 11-15 defines what should be done if there was an error.

With all this in place we are ready to go – run the application and pan/zoom to a location of your choice (it will probably by your house!) and then click Save. All things being equal you should see a Success message and if you navigate to the project location you should also find a file called coordinates.txt which will contain the saved values.

To test for an error condition we will edit the Page_Load event in the CoordinateHandler code behind file. Change the using statement for the StreamWriter so it looks like this:

using (StreamWriter sw = File.CreateText("coordinates.txt"))

By removing the Server.MapPath call the application will now try to save the file into a folder deep within Program Files – which should throw an IO Exception.

Run the application again but this time without debugging enabled, either from the Debug menu or by pressing CTRL+F5 – this will stop Visual Studio from interrupting when the exception gets thrown. This time when you click save the error message should be displayed as below.

So there we have it – a simple way to send data to the server using the AJAX capability of jQuery.

You can download the working source code from here.