Author Archives: aidandegraaf

XBox Music – We are unable to confirm the media usage rights for this content

So I thought I’d give it a go. I’d check out this Xbox Music and the aptly titled “Xbox Music Pass”. For some reason the widespread animosity towards Microsoft and all things Windows had triggered my internal switch… that switch which causes me to fight whatever trend is trending… to support the “underdog”. You know that multibillion dollar international software conglomerate… underdog… yeah… right. So cast aside the HTC Desire and let’s check out this highly praised Lumia 920 Windows 8 shiny bright future partnership for Nokia and Microsoft thing with the native Xbox Music app with the streaming and downloading and the kit and the caboodle with the box and the dice.

And it worked well, I was surprisingly surprised. I found much to do of my current obsession. And it wasn’t Bruno Mars or Katy Perry. I’d discovered a piece of the 70s and early 80s I never understood… a piece of my childhood that was never explained… something I felt but never… knew. It was something that put BMX and skateboarding and skinny jeans and army shirts into perspective. Permanent marker, painting up your canvas bag with all the fuck-you-you-don’t-understand-me-so-fuck-you feeling you could get. It was the Frog Brothers. It was the first time round… the underground in the 80s… punk… hardcore… hardcore-punk… before Kurt walked out into the spotlight and disintegrated.

My point…

Oh yeah… my point… if all this underground hardcore punk stuff that was mostly distributed on cassettes… yeah tapes… and had album covers drawn with texta, could be found easily on the fucking Microsoft music store… then they’d probably have what I’m looking or next time I need to find something obscure.

So I signed up… I said “Let me trial your service!” and I thought those thoughts and I downloaded those tapes and I synchronised and streamed and downloaded and streamed and synchronised and sang and danced and streamed. And when the month did end my time for decision did come, I did say “Let it roll over!”, thinking of both Chuck Berry and Jet and favouring neither, and I woke to my first day as a full paying customer.

Twelve bucks… per month… three coffees, a jug of beer, a hamburger, a half-decent curry… it’s nada… it’s nothing. Compared to what I usually waste on food and drink … and music is food and drink! And right now this is not waste this is feeding my soul. Praise the lord!

“We are unable to confirm the media usage rights for this content.”

What?!

What?!

Why?! … No … not me … I gave you a chance.

And the music died.

So I went to The Google and I searched for the error message and I found there were more like me. Many more. The trial ended, the error started. Solutions were recommended.

“Turn the such-and-such off and then go to the third thingy and turn it off and then on again and it’ll start working”, said one.

Another proposed, “hold it upside down on a Thursday but only in a thunderstorm so that the static zoom will zamm it back to its correct quantum state.”

My most loved and my most hated however said, “Reset your phone to factory settings.”

Ok, drastic. But hey, I’m a programmer. I understand state. I understand that sometimes things can just get into such muddle that the easiest way out is to just start again. But really? In 2013? The age of the smart phone?

Settings > About > Reset Phone > OK Go!

Spin.

Spin.

Spin.

Spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin-spin.

Shit.

Fuck.

Reset.

Reset.

Reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset-reset.

Fuck.

Shit.

Oh. Oh.

No. Oh No. Oh Shit.

And so my phone was bricked. Dead. Useless. Because I signed up to a music streaming service. Because I signed up to a fucking music streaming service. Fucking what?

I was however able to bring the brick back from the depths of hell. It was not sent to the great big bucket in the sky, the bucket of leads at the back of the hall cupboard. I went back to The Google (because fuck you Bing… fuck you to hell and back. I’m not giving you the fucking pleasure). And Google did tell of solutions. Solutions to download new firmware and flash the phone and properly get that device running like a new phone again.

I downloaded the such-and-such and copied the zang into the zum and selected the bub and reset the bob (but not before the bib!) and the progress bar progressed and screen flashed back to life in all its colourful magnificence. It came back to life. And run again it did. I started it up. It restored my apps. I opened the music app and it worked. It fucking worked.

It downloaded the music and streamed the music and synchronised my catalogue and did all the godly things required of the streaming downloading music subscribing app thingy.

But why did it take me two hours of searching and downloading hacks to restore my phone back to its original state? Why? And why did something so simple as progressing from trial to full subscription fail?

This is embarrassing for Microsoft. This needs to be dealt with. Cataclysmic failure should not happen for such a simple process.

My mind is wandering away from Redmond and back towards Mountain View.

Advertisement

Rendering Parameter Standard Values – where the bloody hell are you?!

If your Sublayout Parameter values are coming through as null in your sublayout control, it may be because the standard values on the parameter template itself aren’t passed through*.

Standard Values for your parameters on the template that uses the sublayout will be fine, and the values will appear when used on any particular template. But if you are tearing your hair out wondering why your value is null, head on over to the template and set the value directly on its own standard values**. You should find the value appears.

* I am using Sitecore version 6.5.0
** or even the item in question, but that’s just messy

Tagged , , , ,

PowerShell and Sqlcmd

While PowerShell is very, er… powerful, I’m never a fan of using a particular tool just because I can. If I’m doing SQL work, then I generally prefer to do it with SQL scripts. However, as a lot of my build and process work is already built with PowerShell, it’s very easy to call out to my scripts from TeamCity with a simple PS script:

Add-PSSnapin SqlServerCmdletSnapin100
Add-PSSnapin SqlServerProviderSnapin100

"Restoring Production Backups"

Invoke-Sqlcmd -InputFile "D:\Scripts\Restore Production Backups.sql" -ServerInstance "localhost" | Out-File "D:\Scripts\Output.txt"

I also found the following article a big help after getting errors calling the Invoke-Sqlcmd cmdlet. I would recommend trying the steps in the reverse order though, as all I had to do to my script was add the snap-ins, rather than installing all the tools which were already present.

http://jasonq.com/index.php/2012/03/3-things-to-do-if-invoke-sqlcmd-is-not-recognized-in-windows-powershell/

Tagged

Today’s Sitecore Quirk – The IconCache

The other day I moved my Sitecore data folder into App_Data as that has special-protections (read: diplomatic immunity!) at the machine level. Along with this, I moved the Sitecore temp folder there as well, and also the IconCache folder…. bad move, Aidan.

Sitecore uses its temp/IconCache folder as place to store cached versions of the icons (the ones that were moved into zip files a couple of versions ago to help with file system performance). But unlike MediaCache, which loads the images via the media handler, icons are accessed directly via the temp folder path. So when I moved things into App_Data I got this pretty little path used for the icons in the Content Editor.

~/App_Data/temp/IconCache/People/16x16/cubes_blue.png

Your eyes do not deceive you. Furthermore, when I look in the temp folder, there are also a lot of images there that appear to be cached icon files, but aren’t put in the IconCache directory. God might know why, as I certainly do not.

So your lesson for today*

Make sure your temp and IconCache folders are accessible from the web, not put in a protected folder like App_Data. I really hope Sitecore isn’t using the temp folder as a location to process or store potentially sensitive or protected files, because it makes sense to me that it should be moved out of the web folder completely (as I used to do), or into a protected folder such as App_Data. Am I wrong in thinking this way?

Update

Don’t use a tilde (e.g. ~/temp) in your temp folder path either. A file system request to an image such as ~/temp/IconCache/People/16x16/cubes_blue.png will throw a 404 as it won’t be processed by the ASP.NET application.

* I’m working with 6.4.1 rev. 110720, this may or may not be fixed in later versions.

Tagged

Lucene.Net.lockdir

I’ve been working in Sitecore for probably half a decade now (hmmm, really Aidan?) and until the last couple of weeks I have never come across this problem. And now I feel like I’m picking at a scab by being proactive in dealing with it.

You see, when Lucene writes to an index it creates a little .lock file so that no other pushy little processes can come along and try to write at the same time. And where does it put this lock file? You would think putting it in the index folder might make sense. If you didn’t, you should have because that’s where I think it should go. But I’ll give the Lucene developers the benefit of the doubt because in matters related to computer science I’d put money on them to smack me down in a fair fight.

So where does it go? Well, C:\Windows\Temp of course!

On my machine I didn’t have access to this folder. Our IT department rightly believes giving non-administrator users access to the Windows folder a bit of a.. risk. So when Lucene crashed the other day I had quite a bit of trouble getting at those pesky little lock files to remove them.

While I had a friendly email exchange with IT to open up temp folder access for me. I came across the Lucene.Net.lockdir app setting. Great, thinks I, and says to me self, “we’ll just set this to somewhere app-local, such as my App_Data folder that contains the indexes”.

But ’twas not to be so simple! After a few too many hours testing the various path combinations I wanted to use and blindly ignoring the posts I’d already read on the subject, I had finally satisfied myself that I now understood what this setting could do… and it’s quite simple:

You can only use an absolute local path

That means no relative paths, no ~/App_Data/indexes, no UNC paths to share folders. Just a plain old simple C:\yada yada yada\put my temp files here\ type of folder path.

I’d really prefer not to have to manage file system permissions for my app at another location, particularly in C:\Windows, but it means I now have to manage folder paths across my environments. It’s quite a trade off, because now I’m more likely to have problems setting up a new environment. Or, God forbid, another developer setting up their environment and troubleshooting the app when they’re not familiar with it.

What makes matters worse is the problem is not obvious to begin with.

When there are problems with the lockdir, you’re Sitecore application isn’t going to start up properly. And you don’t get a message, there’s nothing in the logs – it just hangs.

And boy can it take a while before you know whether it’s just a slow start-up or whether it is proper fucked. It’ll hang when you hit your front-end site, it’ll hang when you try to log into Content Editor. You can actually access the /sitecore/login page (hooray!), and perhaps if your front-end site doesn’t use Lucene you may be able to get to that also. But that’s your message – hang.

So next time you’re hanging about staring as your Sitecore app starts up.. just double check your Lucene folders. Check the path and check for the .lock files. It could just stop you having that psychotic episode on the way home from work.

Tagged , , ,

telnet ftw!

Another nifty debugging story today.

The goal was to unify my Sitecore keepalive URL across all environments. You see when you have not one but three production servers, managing your web.config becomes a real bitch of a problem, and the Sitecore UrlAgent is one of the most annoying.

For the purposes of this post, let’s call our site www.bobble.com. Why? Well the Bob part is obvious, and there’s no denying that Bubble Bobble wasn’t one of the greatest games ever. But I digress…

So, the solution is pretty simple. I create a local hosts entry and binding in IIS. I ensure the IIS binding uses the local IP so this will only work on the server.

127.0.0.1        bobble.localhost

I do this on all environments from dev through to production. I can now set my keepalive URL to:

http://bobble.localhost/sitecore/admin/keepalive.aspx.

Simple. Done. I fire-up IE (because this is Windows 2008 production and we don’t have luxuries like Firefox and Chrome installed) and hit the URL to make sure it’s working… FAIL.

WTF?! Why would this happen.. this is simple. 1) Update hosts file. 2) Update IIS binding on website. 3) THERE IS NO 3.. it’s that simple! I’m perplexed, completely perplexed. I check, I double check, I double check the double check. My checks become sextuplets. I’ve got a whole family of checks for my complex DNS configuration. I refresh the browser at least 20 times. So you get it, I’m banging my head against the wall. All I keep getting is the STUPID IE FAIL SCREEN!

I ping the host name. All good – IP is correct. I try it with the real IP instead of the loopback IP. No change. There must be someway to get some real info on the problem.

telnet to the rescue

It hits me.. I wonder if I can telnet to the site and get some kind of response? A quick Google, and… Yes!

Here is the eventual command line process. Open Command Prompt and enter the following:

  1. telnet
  2. set localecho
    so we can see what we are doing. If we couldn’t before we can now see the prompt
  3. Microsoft Telnet>set crlf
    something to do with the enter key behaving how we want it to.
  4. Microsoft Telnet>o bobble.localhost 80
    connects to the site. The cursor will probably jump back to the top of the command window but the output won’t be cleared. You’ll need to just type over the existing output.
  5. GET /sitecore/service/keepalive.aspx HTTP/1.1
    Host: bobble.localhost

Hit enter twice to send the request… we should now get the full HTTP output of the request.

UHUH!! Here’s our answer..


HTTP/1.1 301 Moved Permanently
Content-Type: text?html; charset=UTF-8
Location: http://www.bobble.localhost/sitecore/service/keepalive.aspx
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 26 Jul 2012 01:13:06 GMT
Content-Length: 182
.
<html><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="http://www.bobble.localhost/sitecore/service/keepalive.aspx">here</a></body>

I remember now. There is an IIS rewrite set up in the web.config that redirects all non-www domains back to the www.* domains. And because I don’t have http://www.bobble.localhost set up (in IIS nor DNS) the browser can’t even get close to finding it!

With telnet I was able to get the exact request details, without any silly attempts by the browser to redirect. This is going to be mighty useful in the future.

Enjoy!

Tagged , , , , , ,

To slash or not to slash (Website Urls)

I was updating a custom LinkProvider for Sitecore today and began wondering about whether or not to use a trailing slash on the generated Urls. Of course the first search result gave me the official recommendation from Google:

http://googlewebmastercentral.blogspot.com.au/2010/04/to-slash-or-not-to-slash.html

I hadn’t ever considered the implications that such a minor difference could have on indexing and SEO. If links with both formats get out there, you’re going to end up with two valid index entries which although may not have a great impact, if it could be avoided, then why not?

So, a lunchtime project! I’ll add a redirect at the start of each request that creates a 301 from one Url to the other. I decided to remove all trailing slashes, as that way I can test any Url for the existance of one and remove it (which is a lot easier than defining the logic about where to add one). It brought me straight to another fork in the road however. If I want to set up a redirect from one to the other, do I created a .NET HttpModule and add a BeginRequest handler, or do I create a Sitecore Pipeline Processor and wedge it into the PreprocessRequest pipeline?

Personally I like to go with whatever performs best and if I can find somewhere earlier in the request lifecycle to put this kind of thing I like to do so. I created one of each and let the debugger break at the first one it reached.

In my initial test, Sitecore won, but why? Well, I’d added my HttpModule at the end of the list in the web.config. Once I moved it above the Sitecore.Web.RewriteModule, it hit my module first. I decided to go with the .NET HttpModule, as I can now reuse it in non-Sitecore projects.

This is what it looks like:

    public class TrailingSlashModule : IHttpModule
    {
        private HttpApplication _app;

        public void Init(HttpApplication app)
        {
            _app = app;
            _app.BeginRequest += new EventHandler(OnBeginRequest);
        }

        public void OnBeginRequest(object sender, EventArgs e)
        {
            var pathAndQuery = _app.Context.Request.RawUrl.Split("?".ToCharArray());
            string absPath = pathAndQuery[0];
            string query = pathAndQuery.Length > 1 ? pathAndQuery[1] : string.Empty;
            if (absPath.EndsWith("/") || absPath.EndsWith("\\"))
            {
                string url = absPath.TrimEnd('\\').TrimEnd('/') + (string.IsNullOrEmpty(query) ? "" : "?" + query);
                _app.Context.Response.Status = "301 Moved Permanently";
                _app.Context.Response.StatusCode = 301;
                _app.Context.Response.AddHeader("Location", url);
                _app.Context.Response.End();
            }
        }

        public void Dispose()
        {
        }
    }
Tagged

JSON: not just an object literal

For a while I’ve considered JSON to be the same as an object literal in JavaScript.

How wrong I’ve been.

JSON doesn’t support half of this stuff. The JSON format has been developed specifically for data exchange and supports only a subset of what an object literal does.

First of all, property names must be qualified by a double-quote. Single-quotes are not valid. That one had me confused for while as I tried to validate my code.

Secondly, values can only be one of the following: null, string, number, boolean, array, or another JSON object. Functions are definitely not gonna fly.

Generally you’ll be using some other library to generate JSON based on your objects (that’s what kept me so unelightened for so long).

However, for when you need to cut it by hand, there’s a nice little tool at jsonlint.com which you can use to validate your objects.

Tagged ,

Layout inheritance in Sitecore

I was recently tripped up by a publishing error in Sitecore that dragged me kicking and screaming into understanding the new inheritance logic that underpins layout settings. The error was the usual helpful Value cannot be null, directly after a Database.GetItem() call. OK thinks I, there must be a broken link somewhere. Two hours later of adding and removing sublayouts, publishing, re-publishing, staring at XML, commenting in, commenting out, copying and pasting, I had me an understanding of how the oh-so-important  __Renderings field now functions. Now I look forward to the fix that stops the following error occurring when I forget to publish my standard values item that contains half, yes half, of my presentation data.

So, what’s new?

I recently had a meeting with Sitecore Australia’s Steve Green, in which he mentioned in passing the upcoming changes to presentation. It “stores the delta between your standard values and the item”. This sounded interesting, we’ll save countless man hours usually spent updating settings on multiple items due to a tiny change in the UI. I left the meeting looking forward to the next version, 6.5. Unbeknownst to me, this functionality was already alive and kicking on our current implementation on version 6.4.1.

The Delta, you say?

You might be familiar with the XML structure that is used to store presentation. The following image shows the basics, an opening r element(for Renderings), one or more d elements (for Device) and a number of r elements (for Rendering.. or Sublayout as I’ll refer to them here). Each Device element will have a GUID that defines the Layout to be used for that Device, while each Sublayout element will have a GUID reference to the Sublayout, the placeholder it will be added to, the parameters containing settings and/or content .. plus a number of other attributes and settings that describe its functionality.

Usually you’d configure this using the Sitecore interface by editing the __Standard values item of your template. Any items based on this template will then use these presentation settings until the time you make a change to the item presentation – for example, by updating the RichTextContent parameter and adding a promotion to the content_right placeholder. Previously at this point, the entire XML would be updated and stored in the item’s __Renderings field, replacing the XML from the standard values item.

As of version 6.4 however, the layout XML on the item contains just the differences between the standard values and the item. The new layout info is distinguished by an attribute namespace, s. In our example, the majority of the configuration for the RichText Sublayout remains within the standard values item, and is now referenced by its uid attribute, with the updated RichTextContent value stored within s:par, signifying that it overrides the original par attribute from the standard values item. Likewise, the new promotion Sublayout is added with all attributes but with the s: attribute namespace.

Sitecore will now get the standard values information and merge it with the delta in the item, allowing you to change common info. For example, if we needed to move the RichText Sublayout into a new placeholder, or update caching options, this could be done on the standard values item and published with one simple change, rather than update every item that uses the template as we had to do in the past. Great stuff.

So that’s it, basically. Whatever you do, don’t forget to publish your template’s __Standard values item before the item, or you’ll get that nasty publishing error. The null reference error occurs because the uid attribute is the reference to the same rendering in the standard values. As of version 6.4.1, Sitecore won’t let you publish an item without the target uid existing.

Update: the publishing error was fixed in Sitecore CMS 6.4.1 rev.110928 (6.4.1 Update-4). Fear not the publish – fire at will.

Using Fiddler2 and jsbeautifier to debug minified javascript

You’ve deployed to production, everything is tested. You’re quietly confident your AM and the client will be hitting the publish button on the content, high-fiving with gusto and heading downtown for Martini’s while you trudge to the bus stop in the rain. But no. Ten minutes after you send the email, alarms start ringing – “the compact search isn’t displaying in IE!”. That’s the compact, front-and-centre most highly used feature of home page and gateway to the gazillions in sales we receive every hour, search. And that’s IE, the browser (still?!) with the highest god-damned user base. OK, time to investigate.

The compact search is an ajax-driven form that is displayed on page load, so you’re 99% sure the problem is JavaScript. Firing up IE, you hit F12 to launch the developer console, hit the script tab and start debugging. Refresh.

IE9 JavaScript Error - SCRIPT16385 Not implemented

Oh great. 3rd Party Library. Minified. It’ll be a breeze making sense of that code … <Insert more blasphemy here>.

JavaScript Error Code

But there is light in this tunnel.. just down aways.

Open up Fiddler, says Tony. I’ll show you a trick. Refresh the page. Woila, there’s all the files the browser requested for that page, include the culprit, Modernizr. Now, generally speaking there’s nothing special there – nothing that standard browser developer tools don’t give you. But look a little deeper, and we can do some fancy stuff.

  1. Here is our Modernizr include file
  2. Here is the file output – notice it is Gzipped and encoded, hit the button to convert this stuff: Gzipped code, into your actual minified JavaScript code.
  3. Next let’s look at AutoResponder, home of aforementioned fancy stuff. Hit that tab and let’s have a look.

Fiddler Output

So now that you’ve found your javascript file, decoded it and moved over to the AutoResponder tab, drag that file from the list over into the AutoResponder window. You’ll end up with something like this:

Fiddler AutoResponder 1

OK, so look at that… instead of loading the js file from the server now, Fiddler is going to intercept the request and serve this version of the file. Let’s just right-click that sucker and select Edit Response. That’ll give us this window:

Fiddler AutoResponder 2

OK, now we can edit this code to debug the problem. No need to touch anything on the production server. How about we copy the code from this window, head over to jsbeautifier.org and BANG, readable javascript code. Paste that back into the Fiddler AutoResponse, save it and refresh your page. Check your console now and you’ll have the real line where that error occurred. You now have some context.

JavaScript - CleanError Code

Let’s have a quick Google to see why Modernizr 1.6 is crashing in IE9… oh look at that: https://github.com/Modernizr/Modernizr/issues/224. Windows Server 2008 doesn’t deal with the video tag properly because HTML5 isn’t enabled without setting up “Desktop Experience” on the server. But wait a sec, this is happening on a desktop, not a server. Let’s look at that, oh Windows 7 Enterprise ‘N’ .. what the fuck is ‘N’?! More searching reveals this: http://www.techarp.com/showarticle.aspx?artno=619&pgno=3. So looks like ‘N’ is causing a similar issue because Windows didn’t have Media Player and IE set up properly from the start. Nuts.

Side note (rant)

But why does Windows come with this crazy ‘N’ version that has the messed up Html5 / media player features. Well let’s go back in time a bit kiddies, to when Microsoft was a great ogre, rolling over the top of their competition, selling Windows with the web browser already installed!!! Yes, that’s right, already installed! Netscape the other great browser maker of the time were losing market share rapido. All of Microsoft’s competitors freaked out and thought this giant was going to take over the entire world – all because Windows came with IE (and Windows Media Player) installed.

So up rose the mighty US government, pitchforks in hand, and headed to the courts, in both the US and Europe. George W Bush came along and gave the smack down to the case in the US, but Europe ruled that MS had to split the Windows from IE. Enter ‘N’ version of Windows causing me my headache today.

Ten years later, Internet Explorer is still the most widely used browser. But nobody really cares about whether browsers and operating systems and media players are integrated. In fact just look at what Apple do these days. Mac OS comes with everything you need, from Safari to iPhoto. Look at Google, they’re turning the browser into the OS. What’s going on there? Integration is the way of the future.

So why did we stop Microsoft doing this ten years ago?

Haters gotta hate.


Tagged