Wednesday, 15 December 2010

The DELETE statement conflicted with the REFERENCE constraint "FK_cmsPropertyData_cmsPropertyType" - Umbraco

The DELETE statement conflicted with the REFERENCE constraint "FK_cmsPropertyData_cmsPropertyType".



This was incredibly painful!

It occurs when you try to delete a property form a document type.

Here is a quick fix that does not involve manually deleting things....


Open up SQL Management Studio.
Change delete rule for the relationship between cmsPropertyType and cmsPropertyData to "cascade".

DONE!


Friday, 10 December 2010

Reseeding Umbraco

Back when I was working at The Farm we needed to do some sweeping changes to an existing Umbraco site.

To make sure the new content you upload does not conflict with additions the client makes during the development time, you must do the following... Take a back up of the live db for development, then reseed the tables of your new development db to a number much much higher. This allows you to synch up the database changes when it comes to deploy time. We reseeded the primary keys of some key tables to 500,000. (see http://www.farmcode.org/post/2009/09/09/How-to-sync-data-across-multiple-Umbraco-environments.aspx).

The issue we had though was that the time between reseeding and deployment turned out to be 3 months and the reseeding was no longer high enough. We learned this the hard way.

Today I'm about to begin the whole process on another existing Umbraco site, so I decided to check the current seeds.

Here is the script I used:

SELECT IDENT_SEED(TABLE_NAME) AS Seed,
IDENT_INCR(TABLE_NAME) AS Increment,
IDENT_CURRENT(TABLE_NAME) AS Current_Identity,
TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 'TableHasIdentity') = 1
AND TABLE_TYPE = 'BASE TABLE'


It turns out that in just over 2 months, the cmsPropertyData and umbracoLog tables had current seeds of 306208 and 145973 (respectfully).

Final deliverables for this site are not until March 2011. So it seems that a reseed of even 1,000,000 might not be enough.

So I've decided to reseed to 10,000,000

Here is all I needed to run:
DBCC CHECKIDENT (cmsContent, reseed, 10000000)
DBCC CHECKIDENT (cmsContentVersion, reseed, 10000000)
DBCC CHECKIDENT (cmsPropertyData, reseed, 10000000)
DBCC CHECKIDENT (umbracoNode, reseed, 10000000)
DBCC CHECKIDENT (umbracoLog, reseed, 10000000)



Saturday, 13 November 2010

Wednesday, 11 August 2010

Print this!

I have had some interesting discussions lately about web design, clients and coding in general.

My friend and I were talking about interface design and cool JQuery effects. I showed him a site I built which had a bajillion hidden divs which were displayed when the user hovers over and clicks on certain images, text and buttons.

I told him that the problem with pages that have a whole bunch of hidden content which is displayed by hovering and clicking etc is that when a user wants to print the page, what do you print? What if there are 10 pages worth of text and images (and a video)? The printed page is never going to look like it does on the screen. I know that there are CSS files for printing, but those types of pages are horrible to write them for.

My friend's answer: "It's a website. Why do people need to print it? You print word documents and pdf's. Why do you need to print a webpage? Seriously!"



Thursday, 1 July 2010

Formsy

Over the last few months I have been working on an open source forms engine I call Formsy.

"Formsy is an XML driven forms engine built with ASP.Net 3.5. Formsy is super easy to use, is completely extensible and generates clean markup for easy styling."

Today I finally launched it on Codeplex.

Formsy came about after my experiences with Umbraco Contour. I had to do some crazy code to get Contour to do things it was really not meant for. It was a real nightmare. Getting Contour to regionalize form labels, validation messages, and validation regular expressions was the least crazy thing we needed to do.

After the Contour experience I realized that I needed some practice with composite controls. So I started to make a little forms engine. Before long, I had all the extra functionality that we required in Contour (eg. custom data storage, custom emails to name just two). At that point I realized that Formsy might be useful to other people. So I set out to add even more functionality.

So here I am 3 days away from my flight overseas launching my Codess-Opess.

I think it's pretty rad.




Saturday, 27 March 2010

Regionalizing validation messages, and regex in Umbraco Contour




Umbraco Contour is a great package for ultra fast building of forms. What we used it for was not entirely what it was meant for.

We were asked to build a form where labels, validation messages AND the regular expressions to validate phone numbers were all regionalized. Contour uses Umbraco's dictionary to store regionalized labels, so we decided to store our validation messages and regex there.

Here is how we did it all...

Firstly, we name our field's in the form #Form_FirstName, #Form_LastName etc. In the dictionary, add your languages. Then create items with the same names as the form fields (without the #). This allows Contour to replace your labels. We create two matching items to handle regionalized values for validation messages and regex: #Form_FirstName_vmsg, and #Form_FirstName_regex respectively.

Contour installs RenderForm.ascx under \usercontrols\umbracoContour\ in your project. Noticing this, you can easily change it's CodeBehind property to your own "RenderForm.ascx.cs" which you inherit from Contour's. Overriding OnPreRender() is where the magic happens.

The code is pretty self explanatory. We override OnPreRender(), loop through the fields, use their caption property and a suffix ("_vmsg" or "_regex") to get the values from the dictionary.

Here is the code...



public class RenderForm : Umbraco.Forms.UI.Usercontrols.RenderForm
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);

// get the form fields
FormStorage fs = new FormStorage();
var form = fs.GetForm(new Guid(this.FormGuid));
var fields = form.AllFields;

foreach (var f in fields)
{
// get this field's validator
var fieldId = f.Id.ToString();
var vals = Page.Validators
.Cast()
.Where(x => x.ControlToValidate == fieldId).ToList();
if (vals.Count > 0)
{
foreach (var baseVal in vals)
{
// get the validator type and assign properties
BaseValidator val = baseVal as RegularExpressionValidator;
if (val != null) // it is RegularExpressionValidator
{
// get regionalized regular expression
string valExpression = GetRegionalizedValidationText(f.Caption, "_regex");
((RegularExpressionValidator)val).ValidationExpression = !string.IsNullOrEmpty(valExpression) ? valExpression : ((RegularExpressionValidator)val).ValidationExpression;
}
else // either a RequiredFieldValidator or another type which you must handle here!
{
// cast to another Validator type you are expecting, then set it's properties
}

// Get the error message
val = baseVal as BaseValidator;
if (val != null)
{
// get regionalized error message
string errorMessage = GetRegionalizedValidationText(f.Caption, "_vmsg");
val.ErrorMessage = !string.IsNullOrEmpty(errorMessage) ? errorMessage : val.ErrorMessage;
}
val.ValidationGroup = form.Name;
}
}
}
}


// Uses's the given string and suffix to get a value from the Umbraco dictionary.
public string GetRegionalizedValidationText(string key, string type)
{
if (key.Contains("#"))
{
string itemName = key.Split('#')[1] + type;

if (umbraco.library.GetDictionaryItem(itemName) != null) // note: item can exist and be ""
return umbraco.library.GetDictionaryItem(itemName);
}
return ""; // key does not contain #, or not found in dictionary
}
}



-- Copied from my post on Farmcode.org.





Monday, 1 March 2010

Flv mime type in IIS


I had to put a site live which had flv's that 404'd. From past experience I knew that it was a mime type issue. So I Googled the mime type for flv (video/x-flv) and added it to IIS. However it did not work.

It turns out that the correct correct definition for the mime type is actually:flv-application/octet-stream



Go figure!


Wednesday, 10 February 2010

Publishing PDF's from Visual Studio 2008

Here's something that annoyed me for a while. In VS2008 even when you include PDF's in the solution, when you hit publish, it doesn't copy them to the destination.

Here's how to fix it.

In the Solution Explorer, right-click the file and select Properties.
In the Properties window change Build Action to "Content"
Change Copy to Output Directory to "Copy always".

Done!

*Hint you can select multiple files but you cannot select a folder.

Wednesday, 3 February 2010

Freeing up space on Windows Server

Yesterday we went to install service pack 2 on a Windows Server 2008 machine. It turns out you need at least 5GB free on C: which we didnt have. After deleting everything we possibly could, including running CCleaner and making the Page File non-existant we were still 400MB off the mark.

Then I noticed a system file c:\hiberfil.sys which was 3GB.

Well it turns out that Windows Server 2008 still allocates space for a hibernate file. Who would want to hibernate their Live server?

Anyway, this is how to gain an exta 3GB...

C:\Users\Administrator>powercfg.exe /hibernate off

That's it!