Development Blog

March 01 2010

In other news

Posted 22:02 | by zhaph

A couple of updates on stuff:

  1. Just before Christmas I launched a new website for our church: Holy Trinity Beckenham (let's say it was a "soft launch" Wink). This was built using the amazing N2 CMS, which gave me everything I was looking for in a content management system, running in ASP.NET MVC, without me having to build the bulk of it - I'll do some posts in the future on the tweaks I made to it.
  2. You should now be able to subscribe to the latest blogs and (the new/re-instated) latest photos feeds directly from the homepage of this site. The latest photos can also be found on the albums page, and each album now has it's own latest photos feed as well.

I've also realised that I only mentioned half of the solution to a problem in my last post on moving from Linq to SQL to Entity Framework - namely how I solved the lazy loading of properties - it's there in the picture, but I haven't spelt it out, so there's another post coming on that.

February 02 2010

Moving from LINQ to SQL to the Entity Framework

Posted 00:50 | by zhaph

As I said in my last post, I've rebuilt the site using ASP.NET MVC - other view engines are available, might be better, or at least better suited to your ideology, but this was the impetus I needed to actually start looking beyond the realm of Webforms.

The other main shift was from LINQ to SQL to using the Entity Framework (LINQ to Entities) as the data layer - once again, other ORMs are available, and don't have the baggage associated with being produced by Microsoft, but they also don't have the visual tooling - and while this site is primarily a place for me to play with cool new shiny toys, I do have a life, and more importantly a family, and didn't have all the time to learn how to configure them correctly or use them.

What I'm going to talk about today is my experiences moving from LINQ to SQL, some of the reasons behind why I moved, the benefits I saw, and the pain points I encountered - and to be honest, from what I've seen at the last two Tech.Eds, and read online, it looks like a lot of those pain points have been removed - although I'm sure there will a future post where I go over the "issues" I've encountered when upgrading Wink

One of the key things that I disliked about LINQ to SQL was the fact that there was an absolute mapping between the tables in your database, and the classes in your model:

Showing the relationship between Album, Photo, Tag, and TagsPhoto tables

This is an image from my LINQ to SQL DBML file, and it looks exactly the same as the ERD that I'd see in SQL Management Studio's diagram of the database - finding the text for all the tags for a given image required code such as:

For each (var tag in photo.siteContent_TagsPhoto.siteContent_Tags) {
  tag.Text;
}

Which (regardless of the naming convention) was painful, and unpleasant, so what I ended up doing was creating a set of helper objects, with sensible names, that had the right collection of properties on them, including a list of tags, that I would then use as:

public static List<Photo> GetPhotos(int AlbumID) {
  var zhpCtx = new ZhaphCoreContentDataContext([...]);

  bool? filter = !(HttpContext.Current.User.IsInRole("Editors") ||
                   HttpContext.Current.User.IsInRole("SiteAdmin"));

  var photos = from p in zhpCtx.siteContent_Photos
               join a in zhpCtx.siteContent_Albums on p.AlbumID equals a.AlbumID
               where p.AlbumID == AlbumID && (a.IsPublic == filter || a.IsPublic)
               orderby p.PhotoID descending
               select new {p.PhotoID, p.AlbumID, p.Caption};

  var results = new List<Photo>(photos.Count());

  foreach (var photo in photos) {
    results.Add(new Photo(photo.PhotoID,
                          photo.AlbumID,
                          photo.Caption,
                          GetTags(photo.PhotoID, zhpCtx)));
  }

  return results;
}

private static List<string> GetTags(int photoID,
                                    ZhaphCoreContentDataContext zhpCtx) {
  return (from tp in zhpCtx.siteContent_TagsPhotos
          join t in zhpCtx.siteContent_Tags on tp.TagID equals t.TagID
          where tp.PhotoID == photoID
          select t.TagText).ToList();
}

There are some nice things in there - I can easily select just the elements from siteContent_Photos that I want - so I'm not pulling back the actual image data from the photo objects when I don't need it, however I've had to jump through all those hoops to get the text of the tags into the results list.

So what did I end up with Entity Framework?

Entity Framework tables, showing Photos, Albums and Tags

Notice that I've lost the object representing the mapping table between Photos and Tags - great! I can now go directly from a Photo to its Tags, and from a Tag to the Photos.

BUT, this wasn't without its issues.

There were two main issues I had with Entity Framework version 1:

  1. I was unable to lazy load properties in Entity Framework as I had done in LINQ to SQL
  2. It was a lot harder to filter on complex CLR entities in Entity Framework than it was in LINQ to SQL.

Taking those points in greater detail then.

Lazy Loading Properties

As I showed above, I was able to easily select just those properties from an object that I wanted to load, projecting them out into a new class:

var photos = from p in zhpCtx.siteContent_Photos
             [...]
             select new {p.PhotoID, p.AlbumID, p.Caption};

So photos contains a set of implicitly typed objects, that have three properties: PhotoID, AlbumID and Caption - this is effectively the same as using the following SQL statement:

SELECT [t0].[PhotoID], [t0].[AlbumID], [t0].[Caption]
FROM [siteContent_Photos] AS [t0]

All that is retrieved from the database then is those three columns.

In Entity Framework I would say (method name has changed, but the result was the same, an object with a number of photos in it):

public Album GetAlbum(int albumId, bool loadPhotos) {
  ObjectQuery<Album> albums = loadPhotos ?
                       m_DoodleContent.Albums.Include("Photos").Include("Photos.Tags") :
                       m_DoodleContent.Albums;

  return albums.FirstOrDefault(a => a.AlbumId == albumId);
}

Which ended up loading all the content for each photo in the album - the reason I had to do it this way was that Entity Framework doesn't expose the AlbumID property of the Photo object either - so there was no way to say "give me all the photos with an AlbumID equal to x" as I had done in LINQ to SQL.

This also shows one futher issue that I've not fully resolved - as the TagsPhoto table is hidden from my object model, I can't query directly into that to build up the Tag Cloud that I had previously - were I'd been able to perform a GROUP in the SQL and get the COUNT of the tag ids from the TagsPhotos table, and then find the TagText for each tag.

Filtering on complex CLR types

Now, I've read a few explainations of why this behaviour exists, but none of them really convinced me fully.

In LINQ to SQL I could write the following, basically saying "get a blog post where the path (after the date) is equal to "path", and the Date the post was published on is equal to the date part of "publishedDate"":

BlogPosts post = (from blogs in blogPosts
                  where blogs.PostPath == path &&
                        blogs.Published.Date == publishedDate.Date
                  select blogs).SingleOrDefault();

However, that wouldn't work with Entity Framework - changing "SingleOrDefault" to "FirstOrDefault" allowed it to compile, but the site would throw nasty exceptions at runtime, along the lines of "System.NotSupportedException: The specified type member 'Date' is not supported in LINQ to Entities".

I initially worked around this by searching for all posts with a given path, calling ToList() on the collection, and then searching that for date, but I didn't like that either, as it (obviously) loaded all the potentially matching blogs before it found just the one I wanted.

What finally worked for me was:

BlogPost post = (from blogs in blogPosts
                 where blogs.PostPath == path
                       && blogs.Published.Year == publishedDate.Year
                       && blogs.Published.Month == publishedDate.Month
                       && blogs.Published.Day == publishedDate.Day
                 select blogs).FirstOrDefault();

As Entity Framework did know how to pull out the Year, Month and Day properties of a DateTime object.

Overall neither of these were particularly big issues, but they caused some of the delays in getting the latest version of this site live - especially as most of the work on it is done late at night Wink

November 26 2009

I'd just like to thank...

Posted 19:32 | by zhaph

As you may have noticed, I've had a bit of a change on the site - I rolled out the new look and feel back in September, before I'd put in place all the authoring controls, but as you can tell, I've been able to upload new photos recently, and I now have the blog authoring interface back in place as well.

Thanks go out to:

Now that this is all up and running again (other than a few tweaks here and there), hopefully we'll be publishing more content - starting with some posts on how I've found working with ASP.NET MVC, why I moved from LINQ to SQL to Entity Framework, and why that fixed the problems I was having, but introduced new ones that were harder to fix (I need to write that soon, before EF4 is released in March and makes this obsolete).

It's good to be back! Grin

August 04 2009

Forays in Photography

Posted 22:02 | by zhaph

Inspired this morning by Scott Hanselman's tweet:

Some AMAZING High Dynamic Range photos. These are REAL photos.  http://bit.ly/kParz

I was inspired to do something. Limited by flat batteries, and missing the 5 minutes of exciting sunset this evening, I ended up with this image of the picture we bought on holiday last month, that is now hanging in the study. It's a mass produced photo on canvas, but quite nice:

Trees Triptych HDR Image
(Click for large version etc).

I thought I'd also quickly run through the steps I went through on this. I started with three seperate photos taken from my camera, each taken manually, at the same focus, aperture and shutter speed, but with three different Exposure Compensations: -2EV, 0EV and +2EV - I went straight for the extremes:

Trees Triptych -2EVTrees Triptych 0EVTrees Triptych +2EV
The three exposures: Left to Right: -2EV, 0EV, and +2EV (click for large versions etc).

I then dropped all three images into one layer in GIMP, in increasing order of exposure. this obviously resulted in the same image as the +2EV one above, however, once I started playing around with the layer modes, interesting things started to happen:

Trees Triptych -2EV base layer, 0EV Soft Light
The -2EV base layer, with the 0EV exposure with a layer mode of "Soft Light".

I then set the +2EV layer at the top with a layer mode of "Hard Light", and ended up with the image that started this post, which strangely seems to have more light coming from it that the original picture Grin

May 11 2009

Adding shipping methods to a Commerce Server Basket

Posted 23:26 | by zhaph

This week, I have mostly been using Commerce Server. Well, to be honest it’s more like this month, but there we go. Seeing as I've only really ever managed other developers using Commerce Server, and we stuck pretty much to the "Let's try and make our business requirements line up with the starter site", this has been a fairly steep learning curve - as we're currently building a system with no inventory, nothing to deliver, and we're using a form building solution to create a heavily designed site - it's going to look great, but it might be painful getting there.

As you may have noticed from twitter, there are some things about this experience that I really don't appreciate in this day and age - most notably the whole magic string setup - although I guess that's partly due to the "extensible" nature of the system. But then there's the mixing of types - most things a user creates, such as catalogues, products, variants, discounts, etc have a string identifier, or possibly an integer if you're lucky, but then we got on to shipping methods - there aren't any, it's an online subscription, we have no stock (but for the last week all our products have been "out of stock"), so we have nothing to deliver, but I'm still getting pipeline errors because there's no shipping method associated with the basket.

So to the meat of this post: How do I associate a shipping method with a basket? I don't. I associate a shipping method with a Line Item - each and every one in the basket - and no way to say "apply this setting to all line items" - how often do you think to yourself on Amazon, "Oh, I'd like that CD to arrive tomorrow, but I don't mind if that one doesn't turn up for 5 days on their Super Saver Delivery™ option"? I know I don't, I just order stuff and have it turn up when it does, which pretty much ends up like that, as I order books that aren't out yet.

All I can say is thank you Microsoft for Object Initializers - they mean that I can at least do this:

// Get the current line items from the Commerce Sever basket LineItemCollection currentItems = orderform.LineItems; // Loop over the line items from the webservice call foreach (wsLineItem wsItem in basketDetails.LineItems) { // See if we can find a line item in the basket that // matches the one from the web service csLineItem csItem = findLineItem(currentItems, wsItem.Catalogue, wsItem.Id, wsItem.VariationId); if (csItem == null){ /* We didn't find one, so add a new line item to the basket. * Here's where the magic happens - create a new line item with all * the properties we can set in the constructor, then add the remainder * through object initializers. */ currentItems.Add( new csLineItem(wsItem.Catalogue, wsItem.Id, wsItem.VariationId, wsItem.Quantity) {ShippingMethodId = basketDetails.ShippingMethod}); } else { // We found a match if (wsItem.Quantity == 0) { // The web service had 0 in the quantity - remove the item currentItems.Remove(csItem); } else { // The web service might have an updated quantity - update. csItem.Quantity = wsItem.Quantity; } } }

March 24 2009

Microsoft Certifications

Posted 22:42 | by zhaph

Why bother with certification? The key driver for me was my appraisals - it has been a goal pretty much since I joined cScape, and was one of the reasons for joining them over some others. The real sensible reason Microsoft give is that having a certificate shows your employers what you know. Other ancillary benefits of certification are pretty pieces of paper to hang on your wall, and Microsoft also have a selection of discounts organised with various other suppliers for MCPs.

Microsoft offer a large selection of exams and levels of certification, mostly building up on the ones before, covering all aspects of their software and increasing in technical expertise and the breadth of the applications supported.

Increasing expertise and breadth of applications

Desktop Support

Gives you advanced training for Office products and desktop operating systems. You will be a Microsoft Certified Application Specialist (based on Vista) or a Microsoft Office Specialist (Office 2007 – one for each application). There's usually only one exam for each certification.

Technical Specialist

This shows that you can implement, build, troubleshoot and debug a specific technology. You will be a Microsoft Certified Technology Specialist, with specialisations in BizTalk, Exchange, Server, SQL, Visual Studio, Vista, Mobile, Office and Office Server technologies for example. The application type certifications are usually one exam, the development ones usually have two exams – a foundation in the .Net framework, followed by the specialisation (Web, Windows, WCF, WPF, etc).

Professional Series

This validates the skills for specific IT or Developer jobs. You will be a Microsoft Certified IT Professional or a Microsoft Certified Professional Developer. The technology stacks available include Windows Development, ASP.NET Development and Enterprise Applications such as Business Intelligence, Consumer Support Tech, Database Developer/Administration, Enterprise Messaging, Support Technician and Server Administrator. These are usually one exam on top of the relevant MCTS specialisation.

The Master Series

This allows you to demonstrate extensive technical expertise. You will be a Microsoft Certified Master, specialising in (currently) Exchange, SQL, Windows Server Directory, Office Communications Server and MOSS. There is an intensive 3 week training course at Redmond, with up to three written and lab based exams. You really need to have been working with the technology for many years.

Architect Series

This is the pinnacle of MS certification. You need to hold a Masters certification, and then attend and pass a peer review. You will be a Microsoft Certified Architect, specialising in Messaging (Exchange), Database (SQL with Online Transaction Processing), Infrastructure and Solutions.

Build your own applicationsSo, how do you pass an exam? What sort of preparation is required? For me, it was mostly a combination of "on the job training" and self learning through doing – and that's the most helpful thing for me – just doing stuff – build and maintain your own site. I know there are plenty of off the shelf tools to host a blog, but what do you learn about web development using those? Write some helper applications to do repetitive tasks (bulk file renaming, deployment guide generation, etc), play with random features – I've written a couple of Debugger Visualisers, including one that will display a colour variable over an image to display it's colour and transparency, which came in useful when answering the questions on the graphics libraries in the foundation exam. I've also had a couple of goes on practice exams, and hunted around the MS Learning site, especially the recently launched "My Ramp Up" area – a massive, free resource with free book chapters, labs, web casts, etc for you to work through and gear you up for the exams. Also, make some time to read blogs and use all those things that appear in IntelliSense that you don't know about as learning opportunities to find out something new from MSDN.

Up till now, the exams have mostly all been based around Multiple Choice type questions – sometimes it's a simple "pick one" question, others are "pick x answers", and some are even "pick x options, and put them in the correct order". They have moved away from the old style of offering options that sound right, but don't exist at all, everything exists, but may not be the right solution. However, more exams are turning to lab based testing, checking the state of a server after you've completed the test to see if you've fixed the problem.

You get the time to take the exam, and are then offered about half as much time again to submit some feedback on the questions, and then you'll find out whether you've passed or failed. You will receive a set of graphs breaking down the exam into generally sensible groupings, rating your performance in those areas from Weak to Strong – apparently I'm not much good at reflection using the Framework, but if you need a website deploying, I'm your man!

Pass or fail, the exam is useful – like the IntelliSense above, take notes in the exam, there's bound to be an option you don't know about, or a question on something you're unsure of – go and learn about it afterwards, plus if you do fail, you will want to have a note of the areas you struggled with.

Microsoft are looking at introducing a set of certifications based around the Expression suite, and the foundation exams that are currently part of the MCTS developer tracks are going to be removed for the .NET 4.0 exams, instead you'll have relevant areas of the foundation tested in the specialisation exams – a good thing if like me you're heavily focused on web development, and rarely touch System.Drawing for example, but I can imagine that there will be quite a bit of overlap for people crossing many disciplines.

Taken from my recent cScape Breakfast Briefing "Certifications".

February 19 2009

Microsoft Office Live Connector makes Internet Explorer 7 "Downlevel"

Posted 14:22 | by zhaph

ASP.NET 1.1 Browser Capabilities are evil. We've already updated the out of the box BrowserCaps in our Machine.configs for our ASP.NET 1.1 sites as per SlingFive's recommended updates, and our clients were happy - Safari, Opera and Firefox all saw the site as they should do.

I was happy too - until I installed Microsoft's latest Live offering - Office Live Connector  - this updated my Internet Explorer user agent string to:

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.590; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; WWTClient2; OfficeLiveConnector.1.3; OfficeLivePatch.0.0)

(additions in bold)

I will go back and fix the BrowserCaps shortly, and when I do, I'll update this post, but in the mean time, I've removed the offending keys from IE's user agent string via the registry*

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent\Post Platform

Now, I may have just broken my Office Live integration, who knows, but that's a price I can live with until I've fixed the browser caps correctly.

Update: 24 March 2009

Looks like it's deeper than that - I've just upgraded my machine to Internet Explorer 8 and the downleveling has happened again - I'm seriously going to have to take a look at what's in my UserAgent, and understand the BrowserCaps section properly - no one else in the office seems to be having this issue however, so it's clearly me.

Update: 30 March 2009

Hmm, removing the World Wide Telescope (WWTClient2) seems to have also resolved the issue, which is odd, as I've had that installed for some time.

Belated Update: 23 June 2009

Thanks to this answer on StackOverflow, I was able to find an actively updated Browser Caps by Owen Brady. Not only that, but Owen's quite knowledgable on this issue, and a quick email exchange led me to discover that ASP.NET 1.1 gets upset when your User Agent string is greater than 128 characters - which is why removing the Office Live stuff worked I guess, but installing IE8 took me back over the limit Angry. Anyway, the other thing Owen pointed out was to set the default tagwriter to the HTML 4.0 tagwriter, rather than the 3.2 one:

<!-- 08-06-06 Think its safe to force the newer tagwriter --> <!-- tagwriter=System.Web.UI.Html32TextWriter--> tagwriter=System.Web.UI.HtmlTextWriter

*Use with caution, don't edit the registry unless you know what you're doing, I'm not responsible if you break your machine, etc, etc

February 09 2009

Visual Studio 2008 SP1 Deletes LINQ to SQL designer files

Posted 11:30 | by zhaph

We had the following issue: We'd gone back to an old .dbml file, and added a new table on to the design surface. Visual Studio proceeded to check out the project file, and delete the .designer.cs file from the system - which we failed to notice initially, as it's a nested file. What we did notice however was that nothing would compile, especially not our DAL, as the partial class within the data context contained lots of red squiggly lines and complained that most of our data objects no longer existed.

Looks like I'm not the only one seeing this, and MS fixed it last month, but I'm not sure when the fix is coming out.

Thankfully, there is a work around, and it seemed to work quite well for us:

In your partial class, move any using statements inside the namespace:

namespace DataContexts {   using System.Collections.Generic;   using System.Linq;   partial class ConfigDataContext   {     [...]   } }

Then right-click on the .dbml file in Solution explorer, and select "Run Custom Tool". This will then regenerate the designer files, and your code will now compile.

December 07 2008

Tech.Ed Day 5 Roundup

Posted 21:19 | by zhaph

TLA311: The Future of C#

The story for C# so far has been: Managed code (1.x), Generics (2.0) LINQ (3.0), however the trends in languages at the moment is towards:

  • Declarative: Less how you want to do something, but more what you want to do - this is supported by LINQ and PLINQ.
  • Dynamic: Not just dynamic languages, but objects whose type we don't know about at compile time.
  • Concurrency: No one's got this completely right for the last 30 years or so, mainly because it means many things to many people. As computers gain more cores, we need to work out how to make our sequential processes run in parallel.
  • Within Microsoft, there's a trend for VB.Net and C# to steal ideas: Going forward they are going to stop adding features separately to each language - many of the new things in C# 4.0 are already in VB, and the same goes for VB10.

So, what is coming in C# 4.0?

  • Dynamic Programming: The Dynamic Language Runtime, sits in the middle, offering Expression Trees, Dynamic Dispatch and Call Site caching, the languages sit on top of the DLR (IronPython, IronRuby, C#, VB.Net, etc), and under the DLR are binders to objects, etc.
    To access a dynamic object, you use the dynamic type, so member selection is deferred to runtime, when the actual types are substituted. Obviously, there's no IntelliSense for dynamic types.
    You will also be able to implement IDynamicObject, which will allow you to dynamically create properties on the object, which are stored in an internal dictionary - this gives you a kind of Duck Typing ("It looks like a duck, it acts like a duck, it sounds like a duck, let's just call it a duck").
    The ultimate proof of this was when Vishal Joshi copied some JavaScript from an aspx file into a cs file, and it all pretty much just worked.
  • Optional and Named Parameters: You can declare default values for parameters, and these will be used if no value is passed in. Positional arguments are processed first and then named arguments are processed. This is obviously of most benefit when it comes to COM interop. The ref modifier on interop calls is now optional, and the Primary Interop Assemblies are no longer needed - only the calls you actually use will be generated.
  • Co- and Contra-variance: See Eric Lippart's Fabulous Adventures In Coding series on the Future of C# for more on this, but my main notes were that the Out modifier will promise that you won't add to or modify the contents of the objects passed to you, and an In modifier states you only take input (e.g. Compare).

And what about after C# 4.0? There was a demonstration of the compiler being exposed as part of the API, allowing complete Meta-programming, dynamic languages that change at runtime, etc.

WUX402: ASP.Net AJAX Tips and Tricks

Something I probably should know about - the preventDefault method will disable the default url action on a link - quite handy.

AddHistoryPoint

This allows you to store Key-Value pairs, along with a title in a state bag, that then enables Back and Forward  navigation, along with Bookmarking support. Within the Script Manger you need to Enable History, set On Navigate, and set EnableSecureHistory to false. This can be done and accessed either server side or, when using sys.Application.AddHistoryPoint on the client side.

jQuery

This now ships with ASP.Net MVC and will be included in VS2010, Jeff King has lots of content on jQuery integration - some quite neat selectors are available:

$("#id") // basic select element by id. $(":text") // select all elements of type=text. $(".class_name") // basic select by css class name. $("#grd tr:even") // find element id "#grd" then select every even row within it.

Script Combining

Although modern browsers are getting better, the HTTP spec recommends only two active connections from a client to the server - so consider combining your scripts together to reduce roundtrips - or you can look into using the ToolKitScriptManager to assist with that.

AJAX with ASP.Net MVC

Handy additions - Ajax.BeginForm - wrap this in a using statement, and you automatically get the closing form tag as well.

There is a client only AJAX toolkit, and helper methods to go with it.

PDC01-IS: Cloud Services: The Story Behind the PDC Keynote Demos

Interesting interactive session on the work being done for the RNLI that has already saved lives, and BlueHoo, who rather frivalously use Azure platform to make little grey and blue blobs (or Hoos) dance. Oh, and enable you to network via BlueTooth and a data service.

WUX02-IS: Top 10 Web Mistakes and How to Avoid Them

A packed session (in fact, a repeat of a previously packed session).

10: Lousy and Out of Date Content

For best results, remove out of date content - at the very least, ensure you have a date on the content, so users can see when it was posted, and ignore it if they wish.

9: Errors in Code

Make sure your mark-up is valid.

8: No Easy Navigation

Sitemaps, breadcrumb trails, search all help.

7: Inconsistent Site Design

On larger sites, ensure that the site layout and design is consistent - especially the overall navigation.

6: Bad User Workflow

An example here was twitter: On the first page, the focus is in the text area at the top - this is good, because you probably went there to post a tweet, however, once you're browsing later pages, this is less important - you're more likely scrolling around, reading tweets, etc - lose the focus on those pages.

5: Only Providing Rich Media

4: Obtrusive Ads

Try and come up with a way to make them less obtrusive, more relevant, targeted, etc.

3: Not Optimising for Search

URLs, HTML markup (see 9 above), etc.

2: Non-Designers Designing

Again, 7, inconsistent designs, poor colour choices, etc - there are plenty of free or affordable templates and colour schemes out there, use them.

1: Not Planning for the Future

Locking people out because they have a later build than your browser sniffer, failing to work on browsers like Chrome or IE8, etc.

December 07 2008

Tech.Ed Day 4 Roundup

Posted 21:13 | by zhaph

TLA322: Writing a 3D Game in 60 Minutes

A walkthrough using the Spacewar Starter Kit, and turning it into a Space Invaders clone - not very 3D, as it was all top down, but I did learn where I went wrong adding my background in my own game - blending is important.

MS Exam 070-562: Microsoft .Net Framework 3.5 ASP.Net Application Development

I passed this one too! Great news! I'm now a Microsoft Certified Technical Specialist: .Net Framework 3.5, ASP.Net Applications - what a mouthful. Apparently I'm very good at configuring and deploying web applications Wink, but a bit weak when it comes to targeting mobile devices - no real surprises there.

WIN305: Parallel Programming Techniques in F#

See my earlier comments, only this time, my brain really did melt. The good news is that Parallel classes are coming in System.Threading v4.0.

PDC307: Microsoft Visual Studio 10: Web Development Futures

First a quick re-cap of what we have in VS2008 SP1, and the out of band releases - -vsdoc.js based JavaScript ItelliSense support added through a hotfix, ASP.Net MVC already in beta, ASP.Net AJAX toolkits and jQuery support.

Then on to VS2010

The biggest change to "Design" is in CSS: It is now standards compliant, it has better support of selectors, and the renderer passes the Acid 1 test.

On the "Source" side, as mentioned previously, there's a large number of HTML snippets that have been added, and "Selection Expansion" was demonstrated (double clicking will expand your selection).

JavaScript IntelliSense is even more improved, a lot faster parsing of JS files to generate IntelliSense. Return types can be parsed from comments, and also it no longer falls over when you have bad scripts.

A whole new deployment story was announced, alongside the Web Config transforms mentioned before. By default transforms are created for each build configuration, Debug compilation is on by default, but off for release builds, and MSBuild will power your deployments.

In the Project properties, there's a new Publish tab, that will allow you to define how you publish the project - you can set up multiple profiles, with different servers, logins, deployment methods. The publish tools will finally allow you to "Skip extra files on the server" so it doesn't delete things it doesn't know about, you can automatically mark the project as an Application on the server, and there's a Publishing toolbar for "one click deployments" - an early offering of this can be found at DiscountASP's MS Deploy Lab.