Friday, June 26, 2009

Tuesday, June 23, 2009

Postback issues with Sitecore 6 - typesThatShouldNotBeExpanded

I've run into this a couple of times now. An ASP.NET control, say the FormView, posts back to the server to change the page contents, say transitioning from the view to edit mode. The page loads, but some of the state or the postback event get lost along the way.

If the same control/code works just fine outside of Sitecore start looking for a solution with the rendering/typesThatShouldNotBeExpanded element in the web.config.

According to ListView and DataPager under Sitecore context"

As Sitecore runs [the] "layout pipeline" during [the] page rendering process, some of the complex ASP.NET controls may fail due to changes in the control tree. Adding type to the mentioned list allows affected ASP.NET controls to work the way they were initially designed.
<!-- RENDERING -->
  <rendering>
      <typesThatShouldNotBeExpanded>
        <type>System.Web.UI.WebControls.DropDownList</type>
        <type>System.Web.UI.WebControls.GridView</type>
        <type>System.Web.UI.WebControls.Repeater</type>
        <type>System.Web.UI.WebControls.DataList</type>
        <type>System.Web.UI.WebControls.FormView</type>
        <!-- Fix issue with the LoginStatus logout link not working when nested in a LoginView -- >
        <type>System.Web.UI.WebControls.LoginView</type>
      </typesThatShouldNotBeExpanded>
  </rendering>

See also:

Thursday, June 18, 2009

Extending System.Web.UI.WebControls.Style to handle all style attributes. E.g. text-align

When using the Page.Header.StyleSheet.CreateStyleRule method I ran into a limitation of the System.Web.UI.WebControls.Style class. I could only set a small subset of the available CSS attributes. In particular, I couldn't set text-align using the WebControls.Style class.

By overriding the Style.FillStyleAttributes method I can add additional CSS attributes to the CssStyleCollection.

class ExtendedStyle : Style
{
    private Dictionary<System.Web.UI.HtmlTextWriterStyle, string> extendedAttributes;

    public string TextAlign
    {
        get
        {
            return GetAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign);
        }
        set
        {
            SetAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, value);
        }
    }

    private string GetAttribute(System.Web.UI.HtmlTextWriterStyle attribute)
    {
        return (extendedAttributes.ContainsKey(attribute))?extendedAttributes[attribute]:null;
    }

    private void SetAttribute(System.Web.UI.HtmlTextWriterStyle attribute, string value)
    {
        if (value == null)
        {
            extendedAttributes.Remove(attribute);
        }
        else
        {
            extendedAttributes[attribute] = value;
        }
    }

    public ExtendedStyle()
    {
        extendedAttributes = new Dictionary();
    }

    protected override void FillStyleAttributes(System.Web.UI.CssStyleCollection attributes, System.Web.UI.IUrlResolutionService urlResolver)
    {
        base.FillStyleAttributes(attributes, urlResolver);

        foreach (System.Web.UI.HtmlTextWriterStyle attribute in this.extendedAttributes.Keys)
        {
            attributes[attribute] = extendedAttributes[attribute];
        }
    }
}

Which allows me to do the following:

Page.Header.StyleSheet.CreateStyleRule(new ExtendedStyle() { TextAlign = "right" }, this, ".foobar");

Converting between HTML Hex color, int, System.Drawing.Color

using System.Drawing;
//...

        [TestMethod]
        public void ColorTest()
        {
            //HTML hex color values and expected int conversions
            Dictionary<string, int> testValues = new Dictionary<string, int> {
            { "#000000", 0 },
            { "#000001", 1 },
            { "#000100", 256 },
            { "#010000", 65536 },
            { "#666666", 6710886 },
            { "#AAAAAA", 11184810 },
            { "#FFFFFF", 16777215 },
            { "#C25454", 12735572 },
            { "#54C254", 5554772 }
            };

            foreach (string htmlColor in testValues.Keys)
            {
                //Drop the #
                string hexString = htmlColor.Substring(1);

                //convert the 6 char hex color value to an int
                //similar to the JavaScript parseInt(hexString, 16) function
                int convertedValue = Convert.ToInt32(hexString, 16);
                int convertedValueAlternative = int.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
                Assert.AreEqual(convertedValue, convertedValueAlternative);

                //convert the int to the 6 char hex color value
                string hexStringFromInt = convertedValue.ToString("X").PadLeft(6, '0');
                Assert.AreEqual(hexString, hexStringFromInt);

                //Check that the converted value matches the expected value
                int expectedValue = testValues[htmlColor];
                Assert.AreEqual(expectedValue, convertedValue);

                //Get the System.Drawing.Color from the hex color value
                Color c = ColorTranslator.FromHtml(htmlColor);
                //Get the hex color value from the System.Drawing.Color
                string htmlHexColor = ColorTranslator.ToHtml(c);
                Assert.AreEqual(htmlColor, htmlHexColor);
            }
        }

Friday, June 12, 2009

Determining your Sitecore CMS6 Version

The Sitecore version appears on the shell Login page. Which is typcally at http://domain/sitecore/login/

Sitecore CMS6 Version

It may also pay to check the DLL versions as the interface might be lying about the actual version.

From code try:

  • Sitecore.Configuration.About.GetVersionNumber
  • Sitecore.Configuration.About.VersionInformation
  • ~/sitecore/shell/sitecore.version.xml

Wednesday, June 10, 2009

Enabling Sitecore CMS6 logging in tests

I ran into an issue when writing unit tests code that used the Sitecore CMS6 Sitecore.Disagnostics.Log class. My App.config had a log4net section but nothing was being logged to the appenders.
Using reflector I found out the Sitecore.Diagnostics.Log.Enabled returns Sitecore.Configuration.Settings.ConfigurationIsSet. So I added the configSection:

<section name="sitecore" type="Sitecore.Configuration.ConfigReader, Sitecore.Kernel" />

and a stub sitecore section to get things working.

Tuesday, June 9, 2009

SettingsPropertyValue.PropertyValue throws a NullReferenceException

    SettingsPropertyValue settingsPropertyValue = new SettingsPropertyValue(settingsProperty);
    settingsProperty.PropertyType = typeof(string); //Must set the type to use the PropertyValue
    settingsPropertyValue.PropertyValue = "FooBar";
    Assert.AreEqual("FooBar", settingsPropertyValue.PropertyValue);

If the SettingsProperty.PropertyType isn't set you will get a NullReferenceException when trying to access the PropertyValue.

See Also: Profile Provider Exception

Friday, June 5, 2009

Nelson .NET User Group Presentation - ASP.NET MVC - 24th of June

Upcoming presentation

Owen Evans will be giving a presentation on Wednesday the 24th of June.

Title:
ASP.NET MVC

Abstract:
This is TBC. In general it will be covering -

  • What is MVC?
  • What is the ASP.NET MVC Framework?
  • How to get started in MVC?
  • What are the main concerns moving from WebForms to MVC?
  • Will MVC suit me?
  • Q&A?

Useful links:

When:
Wednesday 24th June 2009
Gather at 11:50 am, starting at 12:00 pm.
Approximately 1 hour plus pizza afterward.

Where:
FuseIT Ltd,
Ground Floor,
7 Forests Rd,
Stoke,
Nelson
(Off Nayland Rd and behind Carters)

http://local.live.com/default.aspx?v=2&cp=-41.299774~173.236231&style=r&lvl=16&alt=-1000
or
http://maps.google.com/?ie=UTF8&om=1&z=17&ll=-41.299774,173.236231&spn=0.005239,0.010042&t=h

If you are parking on site, please use the parks marked FuseIT that are at the back of the site.

Giveaways:
A Windows Game

Catering: Pizza & Drinks
Door Charge: Free

RSVP to me if you are going to attend so I can guesstimate the food and drink requirements.

However, feel free to turn up on the day though if you can't commit at the moment.

Please feel free to invite anyone who may be interested in attending.

Enabling code coverage in Visual Studio 2008 - "Code Coverage is not enabled for this test run"

After right clicking on a Test Result and selecting "Code Coverage Results" I'm taken to the Code Coverage Results area and shown the message "Code Coverage is not enabled for this test run". To enable it:

  • Test > Edit Test Run Configurations > Local Test Run (...)
  • Code Coverage
  • Check the artifacts/DLLs that you want to see code coverage for.

If you get the message "Code coverage instrumentation warning while processing file FooBar.dll:
Warning VSP2013 : Instrumenting this image requires it to run as a 32-bit process. The CLR header flags have been updated to reflect this." try unchecking Instrument assemblies in place

See also: Code Coverage is not enabled for this test run
TESTTOOLSTASK : warning VSP1024: Unable to open file 'file' for writing.