Source Code Released for User Control File Tree Umbraco Package
A few months ago I released the User Control File Tree package for Umbraco, this allowed developers to edit the front-end code/mark-up in their ASCX user-controls from the Umbraco back-end, (remotely), rather than editing them directly on the server via a text-editor.
Today I have released the source-code on the Umbraco Extensions project (on CodePlex) and created a project page on the new Our Umbraco community website.
If you have any comments, feedback or suggestions – please feel free to get in touch with me via the Our Umbraco forums.
MySql data-source support for ELMAH
Following on from my last post (a couple of months ago) about Integrating ELMAH with Umbraco, I received a comment if it was possible for ELMAH to use MySQL as a back-end data-source.
After a few emails back and forth between myself and Rajiv, (as well as Rajiv’s requests over at the ELMAH support group), the advice was to simpily develop some code that implemented the ErrorLog class, (making use of the 3 core methods: Log, GetError and GetErrors). Rajiv make a start with this code, but ran into a few problems, (mostly because he was trying to reference methods/properties that were internal to the core Elmah.dll).
Given that I’d said it was quick and easy to develop this code, I best put my money (or time in this case) where my mouth was. Fifteen minutes later the code was written… and then another hour later, the code was tested and bugs fixed.
For the MySQL connectivity, I used the MySql.Data.MySqlClient connector. For the MySqlErrorLog, I followed the code/design patterns that Atif had used in both the core SqlErrorLog and SQLiteErrorLog classes.
I have uploaded the Visual Studio (2008) solution to the ELMAH support group file repo (here is a direct link to the ZIP) – you will need to compile the DLL from the solution. If you need a pre-compiled DLL, then give me a shout, I’ll sort something out.
Once you have the compiled Elmah.MySql.dll, you will need to add following to your Web.config file:
In your <elmah> section, change the <errorLog> to: (if you haven’t installed ELMAH before, please see the WebBase)
<errorLog type="Elmah.MySqlErrorLog, Elmah.MySql" />
In the VS2008 solution, there is a script called MySql.sql – run this against your database to create the new table (called “elmah”) needed to log the errors/exceptions.
Then add your MySql connection string in the <connectionStrings> section:
<add name="ELMAH_MySql" connectionString="SERVER=localhost;DATABASE=elmah;USER=XXXX;PASSWORD=XXXX;" />
It is very important that you call the connection string “ELMAH_MySql” – as this is hard-coded in the backend. (Let me know if this is a problem, I think it could be moved to the <errorLog> section?)
Once you have saved the changes to your Web.config, you are all set to use MySql as your ELMAH back-end data-source!
Known issues:
- The “Sequence” column in the “elmah” table should be auto-incremental, but it isn’t! (I don’t claim to know enough about MySql to have multiple auto-incremental columns) – any suggestions?
- The MySql connection string is hard-coded as “
ELMAH_MySql“ - The code will only compile with .NET 2.0 and above (no support for .NET 1.0 or 1.1 – sorry)
I have mentioned to Atif about the possibility of including MySql support to the ELMAH core – to which he is willing to do, only if I support it. Which I will be happy to do – but only if there is a need for it. So my suggestion would be, if you would like to see MySql support in the ELMAH core – then raise a feature request on the ELMAH Google Code site. Once it gains momentum, we’ll take it from there.
Integrating ELMAH with Umbraco
I have a few Umbraco projects that have a lot of custom .NET code, mostly in they are in the form of user-controls and XSLT extensions. As far as I’m aware Umbraco doesn’t have an extendable mechanism for exception handling and sending out notification emails, (there is the umbraco.BusinessLogic.Log, which writes to the umbracoLog table in the database, but that’s all).
Initially I looked at Tim Gaunt’s Advanced Error Reporting – a great drop-in solution that does exactly what it says on the tin! Whilst reading the comments on Tim’s blog, Simon Dingley reminded me of the ELMAH project – which has been one of those web-applications that you keep meaning to try out, but never get around to.
What is ELMAH?
ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.
So I decided to see how nicely it plays with Umbraco… the result, it plays very nicely indeed.
If you are interested, here’s how…
- Download the latest ELMAH binary release (1.0 Beta 3 at the time of writing [direct link]) from the Google Code project page. (http://code.google.com/p/elmah/)
- Extract the files from the ZIP.
- Select the DLLs from the “
/bin/” folder, for Umbraco you’ll be using the DLL from “/bin/net-2.0/Release/“. For the benefit of this post, I decided to use the SQLite option to store the error logs in a database. I could easily have used the SQL Server or VistaDB options. - Drop the DLLs into the “
/bin/” folder of your Umbraco installation. - Open the web.config of your Umbracoo installation and add the following lines:
Add the following to your <configSections> section:
<sectionGroup name="elmah"> <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/> <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah"/> <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah"/> <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/> </sectionGroup>
Add the following just after the </configSections> section:
<elmah> <security allowRemoteAccess="yes" /> <errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="ELMAH.SQLite" /> <errorMail from="no-reply@domain.com" to="webmaster@domain.com" /> </elmah>
Add the following to your <connectionStrings> section, (if you have one, otherwise create one):
<add name="ELMAH.SQLite" connectionString="Data Source=~/data/errors.s3db"/>
In the <httpModules> section, add this:
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah"/> <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/> <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah"/>
… and finally, in the <httpHandlers> section, add this:
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah"/>
If you run into any trouble, there is a more detailed guide on Setting Up ELMAH from DotNetSlackers.
By now you should have ELMAH up and running. Open up your web-browser and go to http://localhost/elmah.axd, (obviously replace “localhost” with whatever your hostname is). You should see the ELMAH Error Log page. Since this is open to the public, you may want to secure it, see the Securing Error Log Pages article for further details.
The last part is to integrate the ELMAH Error Log page into the Umbraco back-end. I created a new user-control in the “/usercontrols/” folder called “ELMAH.ascx”, using the following HTML:
<%@ Control Language="C#" %> <iframe height="98%" width="100%" scrolling="auto" src="elmah.axd" style="margin-top:5px;"></iframe>
Then in the “/config/Dashboard.config” configuration file, I added a new section for the developer area.
<section> <areas> <area>developer</area> </areas> <tab caption="Error Logging Modules and Handlers for ASP.NET"> <control>/usercontrols/ELMAH.ascx</control> </tab> </section>
Now in the Umbraco back-end the developer area looks like this.
I have been very impressed with how well ELMAH functions. Aside from the essential email notifications, the RSS feeds are a great bonus!
Umbraco Package – User Control File Tree
A few months ago, Tim Geyssens (aka Umbraco rockstar) released a package that gave you access to the *.config files in the /config/ folder. This has been a lifesaver in those few times where I have only had web-access to an Umbraco install and needed to tweak some config settings.
Recently I found myself in the same situation, but this time I needed to quickly update a few text changes to an ASCX user-control. Due to the nature of the .NET user-controls in Umbraco, there is no native way of accessing/editing those files via the admin back-end.
… well, not until now …
Following on from Tim’s lead with the Config Tree package, I have developed a “User Control File Tree” for the developer section.
This package displays all the user-control files (from the /usercontrols/ folder), allowing you to edit the front-end ASCX code/mark-up. (There is no way to edit the code-behind using this package). If the user-control contains any inline code (C#/VB.NET), then you will be able to edit it. Keep in mind that there is no validation when editing the user-controls – so please be careful!
You can download the User Control File Tree package from here.
I created the package using Umbraco 4’s built-in Create Package Wizard. Please note that this package has been designed to work with v4 (and above), apologies to v3 users.
To install the package, go to the Developer section of your Umbraco back-end, expand the “Packages” folder, click on “Install local package”, select the “User_Control_Files_Tree_1.0.zip” (from wherever you saved it) and press the “Load Package” button. Follow a few more on-screen steps and you’ll be done in no time!
If you have any problems with it, please do let me know – either by leaving a comment here or posting a thread on the Umbraco forum.
Convert XmlReader to String
I was in the middle of developing a member look-up AJAX function for an Umbraco project, when I ran into a slight problem, (confusion rather), about how to pull the XML back from SQL Server and return it to the browser (AJAX).
The SQL statement was straight-forward, very simple, does a LIKE query against the members table, no problem there. Added “FOR XML AUTO” to return the result-set back as an XML data-type … all going well so far.
Umbraco makes use of Microsoft Data Access Application Block’s SqlHelper class, so I followed the same pattern.
XmlReader reader = SqlHelper.ExecuteXmlReader(connection, CommandType.Text, "SELECT n.id, n.text, m.Email, m.LoginName FROM cmsMember AS m INNER JOIN umbracoNode AS n ON m.nodeId = n.id WHERE n.text LIKE '%' + @query + '%' FOR XML AUTO", new SqlParameter[] { new SqlParameter("@query", query) })
At first I tried to return the XML as a String by calling XmlReader’s GetOuterXml() method. But it returned nothing. After a lot of googling, (of converting an XmlReader to a String), I found a suggestion of iterating through the XmlReader, appending the current node to a StringBuilder.
Here’s what I ended up with…
using (SqlConnection connection = new SqlConnection(umbraco.GlobalSettings.DbDSN))
{
using (XmlReader reader = SqlHelper.ExecuteXmlReader(connection, CommandType.Text, "SELECT n.id, n.text, m.Email, m.LoginName FROM cmsMember AS m INNER JOIN umbracoNode AS n ON m.nodeId = n.id WHERE n.text LIKE '%' + @query + '%' FOR XML AUTO", new SqlParameter[] { new SqlParameter("@query", query) }))
{
if (reader != null)
{
StringBuilder sb = new StringBuilder();
while (reader.Read())
sb.AppendLine(reader.ReadOuterXml());
return sb.ToString();
}
}
}
return String.Empty;
I hope it helps… any improvements and suggestions are welcome!
Tagged by Techn0tic
After years of dodging this tag-the-blogger (”you’re it!“) memes, it was Dave Kinsella who finally got me. So with pure fear of a little dead girl climbing out of my TV in 7 days time, I’ll continue the chain.
If you are tagged you should:
(a) republish these rules
- Link to your original tagger(s) and list these rules in your post.
- Share seven facts about yourself in the post.
- Tag seven people at the end of your post by leaving their names and the links to their blogs.
- Let them know they’ve been tagged.
(b) share seven facts about myself
- People believe that “North by Northwest” is my favourite film, but it’s actually “The Big Lebowski“
- Known as a Scouser, apart from being born in Liverpool, I have only lived there for 10 years, (I’m 30-years old).
- The remaining 20 years (so far) I have lived in the following places; Northop/North Wales, Hindley/Wigan, Westhoughton/Bolton, Columbo/Sri Lanka, Alicante/Spain and Backwell/Yatton/Bristol.
- Although I did a Computer Science degree, I consider myself to be a self-taught developer.
- Embarrassingly, I have calculated the VAT wrong 3 times on issued invoices! – how difficult can it be?
- I was in a band called Tremor… we played at The Cavern, Matthew Street!
- Made a few short films, which have been shown at the FACT and regularly on Canvas @ 3345 Parr St.
(c) Tag seven people. This is difficult, I don’t even know 7 bloggers, but here goes:
Using jQuery to swap form fields
Due to an technical decision early on in my project, the date-of-birth field on a profile edit page in a single text-input element. My client would now like the date-of-birth to be 3 dropdown lists, (day, month and year). The amount of work involved making changes to both the back and front ends would take at least a day. (It sounds a lot, but you know it would).
Here’s where a front-end developer’s best friend comes in… use jQuery to:
- create the 3 dropdown lists
- hide the original text-input field
- update any changes [to the dropdown lists] back to the original text-input.
After 15 mins of building up the HTML output string in JavaScript, here’s the code:
$(document).ready(function()
{
var $dob = $('input#ProfileEdit_DateOfBirth');
if ($dob.length > 0) {
var dob = $dob.val().split('-', 3);
var html = '<select name="dob-day" id="dob-day" class="dob-date">';
for(var i = 1; i <= 31; i++){
html += '<option value="' + i + '"';
if (dob[2] == i)
html += ' selected="selected"';
html += '>' + i + '</option>';
}
html += '</select> ';
var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
html += '<select name="dob-month" id="dob-month" class="dob-date">';
for(var i = 1; i <= 12; i++){
html += '<option value="' + i + '"';
if (dob[1] == i)
html += ' selected="selected"';
html += '>' + months[i - 1] + '</option>';
}
html += '</select> ';
var thisYear = new Date().getFullYear();
html += '<select name="dob-year" id="dob-year" class="dob-date">';
for(var i = (thisYear - 16); i >= (thisYear - 90); i--){
html += '<option value="' + i + '"';
if (dob[0] == i)
html += ' selected="selected"';
html += '>' + i + '</option>';
}
html += '</select> ';
$dob.after(html).css('display','none');
$('select.dob-date').change(function(){
$dob.val($('select#dob-year').val() + '-' + $('select#dob-month').val() + '-' + $('select#dob-day').val())
});
}
});
Any changes to the <select> elements trigger the jQuery .change() event, which are then updated back in the original text-input field. The server-side code (in this case ASP.NET) is non the wiser.
So there you go, that’s my quick-n-dirty approach to using jQuery to swap form fields.
Lil’ Bookninja
After helping Bookninja with their blog, George kindly sent me some swag, (or “thanking him by advertising on his chest“, as George put it), including a baby-grow (we were expecting Katelyn at the time).
Well, 9 months later, Katelyn fits into the baby-grow (she’s always been quite a small baby).
I promised George that I’d sent him a photo when we got chance. It was by pure coincidence that I was wearing a WordPress hoodie! (I’m such a geek!)
Setting up Visual Studio to work with Umbraco
Over the last 12 months I have been involved with developing several Umbraco-powered websites. During that time I’ve experienced many development frustrations; specifically with debugging and version control.
A while back I read Paul Sterling’s blog post on “Working with Umbraco in Visual Studio” – I used this as my basis. I have added to his orignal suggestions:
- Have a clean, working copy of Umbraco – using the installer – on your machine. I am using:
C:\inetpub\wwwroot\umbraco\for my working copy of the site. - My Visual Studio solution/project will be kept under version-control. Since I use Subversion, (with TortoiseSVN and VisualSVN), I prefer to keep all my code under:
C:\SVN\ - In the Visual Studio project, I create the following folders:
/_templates/css/scripts/usercontrols/xslt
These folders reflect the files that will be used in my Umbraco site. The “
/_templates” folder is used to store a text-based version of Umbraco templates, so that I can keep them under version-control; as I’ve had a situation in the past where someone copied over the wrong template – not very pretty. - In Visual Studio, create a post-build event [from Project > Properties > Build Events] to copy all your working files across to your Umbraco installation.
XCOPY "$(ProjectDir)bin\$(ProjectName)*.*" "C:\Inetpub\wwwroot\umbraco\bin\" /y XCOPY "$(ProjectDir)usercontrols\*.ascx" "C:\Inetpub\wwwroot\umbraco\usercontrols\" /y XCOPY "$(ProjectDir)xslt\*.xslt" "C:\Inetpub\wwwroot\umbraco\xslt\" /y XCOPY "$(ProjectDir)scripts\*.js" "C:\Inetpub\wwwroot\umbraco\scripts\" /y
You may notice that I am not copying across the
*.cssstylesheet files across to Umbraco. The reason for this is that the current version of Umbraco (v3.0.3) stores the contents of the CSS files in the database, and not on the file-system.You can either set the “Run the post-build event” whichever option you prefer.
- Once your files have been copied across to Umbraco, you can debug your code in Visual Studio:
- Open the site (usually http://localhost/) in your web-browser.
- In Visual Studio select the Debug > Attach to Process menu.
- Select the ASP.NET worker process from the list – this is usually called “
aspnet_wp.exe” or “w3wp.exe” – then press OK.
It’s important to note that I am developing on Visual Studio 2008; but the same prinicple should apply to VS.NET 2005. (Update: It isn’t so straight-forward in VS.NET 2005, see Brad’s comment for further details.)
I’m still looking at ways to improve my development set-up with Umbraco/Visual Studio, so if anyone has any tips – please pass them my way! I’m especially interested in ways of dynamically updating the stylesheets/templates via the Umbraco API.
Update: I originally wrote this post for use with Umbraco v3. If you are looking for a v4 post, check out the CG09 session write-up over at Our Umbraco. The main difference is that you wont need the /_templates/ folder, just replace it with the /masterpages/ folder, and add it to the post-build events.




