Friday, 19 December 2008
Loading this assembly would produce a different grant set from other instances
Localhost on IIS7
Thursday, 18 December 2008
Visual Studio External Tools Menu
Title | Command | Arguments | Notes |
---|---|---|---|
Run test | (full path to nunit.exe) | $(ItemPath) | |
Reflector | (full path to reflector.exe) | $(ItemPath) | |
FxCop | (full path to fxcop.exe) | $(TargetPath) | |
Explorer | (full path to explorer.exe) | /e, /select, $(ItemPath) | |
Open in Notepad | (full path to notepad.exe) | $(ItemPath) | |
Open | (full path to a batch file containing just "%1") | $(ItemPath) | |
Error Lookup | (errlook.exe, in VS\Common\Tools folder) | (none) | Not sure where this one came from; installed by default? |
Spy++ | (spyxx.exe, in VS\Common\Tools folder) | (none) | Installed by default |
I've excluded a couple of the others that are there by default (eg. Create Guid and Dotfuscator).
(Edited 19/12/2008)
Tuesday, 14 October 2008
Always set AutoPage to true in LinqDataSource
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="MyDataContext" TableName="MyTable" AutoPage="true"></asp:LinqDataSource>
Sadly, the AutoPage option doesn’t seem to be available in other DataSource objects, so a manual implementation is necessary for these.
Thursday, 4 September 2008
CustomValidator does not fire
<asp:CustomValidator ID="myValidator" runat="server" ErrorMessage="Error message" OnServerValidate="myValidator_ServerValidate ValidateEmptyText="true"></asp:CustomValidator>
Wednesday, 3 September 2008
Windows does not shut down
Thursday, 21 August 2008
FindControl Causes Null Reference Exception with NMock
PlaceHolder placeHolder =
(PlaceHolder) _view.MyPanel.FindControl("myplaceholder");
PlaceHolder placeHolder =
(PlaceHolder) _view.MyPanel.Controls[0];
ControlCollection ctrls = _view.MyPanel.Controls;
foreach( Control ctrl in ctrls )
{
if( ctrl.ID == "myplaceholder" )
{
placeHolder = (PlaceHolder) ctrl;
break;
}
}
Saturday, 2 August 2008
CruiseControl builds not working
- Comment out any custom tasks, such as running unit tests, in the ccnet config file (defined within <exec> elements)
- Find error details quickly within the build log by searching for the following words/phrases:
- could not
- failed
- success="false"
- Check whether the code compiled without error by:
- Running the project's team build as used by CCNET
- Searching for "csc" (or "vbc") in the build log
- Clear out temporary files on the build server to remove any sticky references
Wednesday, 23 July 2008
Friday, 18 July 2008
Could not find property 'Name' on object of type: Sitecore.Data.SqlServer.SqlServerDataProvider
Could not find property 'Name' on object of type: Sitecore.Data.SqlServer.SqlServerDataProvider
It took a while to figure out that this was due to the assemblies in source control being out of date. Once I'd copied the contents of the bin folder on the live web server to my local machine, I was able to browse the site.
Tuesday, 8 July 2008
Creation of the virtual directory http://localhost/ failed
The local IIS URL http://localhost/ specified for Web project DemoWebsite has not been configured. In order to open this project the virtual directory needs to be configured. Would you like to create the virtual directory now?
On clicking yes, I got the following error:
Creation of the virtual directory http://localhost/ failed with the error: The URL 'http://localhost/' is already mapped to a different folder location.
The rest of the solution checked out all right, but the above project did not; it was marked as unavailable. I right-clicked the project node in the solution explorer and selected the option to edit the project (.csproj) file. Near the bottom of the file, I found the following:
<iisurl>http://localhost/</iisurl>
I edited this entry to add a virtual directory:
<iisurl>http://localhost/myapp</iisurl>
Having saved the change, I then right-clicked the project node in the solution explorer again and reloaded the project. When I was prompted to create the virtual directory again, the creation was successful and the project checked out. The virtual directory is created under the running web site in IIS (on Windows XP).
Thursday, 12 June 2008
Songs and bands likely to appeal to IT nerds
- Motley Cruise Control
- Status Disk Quota
- Visio Killed the Radio Star (by De-Buggles)
- Iron Python Maiden
- The Google Dolls
- USB-40
- InXSlt
- Fleetwood (Apple) Mac
- Bob Marley and the E-mailers
- Sonny and SharePoint
- Black-eyed ASPs
- CultureInfo Club
- Re-bootylicious
- System of a Downtime
- Billy Blu-Ray Cyrus
- Snoop Blogg
- Shania Twain interface
- Silverlight Lady
- Public Image Limited Disk Space
- Don't believe the hyperterminal
- Token Ring of Fire (by Jonny Cache)
- Awk This Way (by Runas /user:DMC)
- Wired for soundcard
- Dragonforce shutdown
- Bat out of HTML
- Earth, Wind and Firewire
- MPEGgy Sue
- Great balls of Firefox
- Alien Ant Web Farm
Adam and the NAnts
[Edited 8 Oct 2008]
Monday, 12 May 2008
TableHeaderScope enum does not generate XHTML-compliant output
TableHeaderCell th = new TableHeaderCell();
th.Scope = TableHeaderScope.Column;
It generates the following HTML:
<th scope="column">
The value of the scope attribute should be "col". A work-around is to add the scope attribute manually using the Attributes collection:
th.Attributes.Add("scope", "col");
Thursday, 24 April 2008
Postback opens layout rather than the Sitecore item
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="Sitecore.Web.FormAdapter, Sitecore.Kernel" />
I had commented this out due to runtime exceptions I was getting that referred to this line in the file. However, it now seems perfectly happy with it left in!
The file exists in the App_Browsers folder in the web site root. If it isn’t there, copy it from a clean 5.3.1 installation.
[Edited 30/7/2008]
And thanks to my colleague Jason Linham for noting further that the folder should not be hidden.
[Updated 16/9/2008]
Wednesday, 23 April 2008
System.OutOfMemoryException during Visual Studio 2008 build
... 1 hour later... whoops, spoke too soon. A re-installation is now taking place.
[Edit 2/5/2008: Still no luck. I have noticed that massive amounts of data are generated in the temporary ASP.NET files folder (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files). The other day, VS created over 3Gb of data in there when building a solution that was only 187Mb in size. Might be part of the problem.]
Wednesday, 16 April 2008
Sitecore item content not showing
- If the item is in a workflow, check it has been submitted and approved
- If you’re referencing an item using @key (eg. item[@key='fieldname']), make sure the field name is all lower case
- Check the item has been published (do a full publish if changes have been made to templates too)
- Do a full publish (or re-save the web.config file) if you suspect Sitecore caching is having an effect
- Check the content of the item is in the web database by using the dbbrowser utility (in the same broswer session as your Sitecore instance, browse to /sitecore/admin/dbbrowser.aspx)
- If you’re using local IIS, do an IIS reset to refresh the cache
- Use the Access Viewer to check the permissions of the item for the extranet anonymous user
- Check the item’s rendering is assigned to a valid placeholder key (be particularly careful if you are attaching renderings dynamically)
- If applicable, view the HTML source and paste into the W3 validator to check for errors. Something like a self-closing script tag can throw the output.
Have I forgotten anything?
[Updated 7 Jan 2009; added bullet]
Friday, 4 April 2008
Using ASP.NET Log-in Controls with Sitecore Extranet
Your Login control definition will be similar to:
<asp:Login ID="Login1" runat="server"
OnAuthenticate="Login1_Authenticate"></asp:Login>
Your event handler will be similar to:
protected void Login1_Authenticate( object sender,
AuthenticateEventArgs e )
{
e.Authenticated = Sitecore.Context.Domain.Login(
Login1.UserName, Login1.Password).Success;
}
The user instance login flag is not supported on this version of SQL Server. The connection will be closed.
<add name="LocalSqlServer"
connectionString="Data Source=(local);
Integrated Security=True;User Instance=True;
Initial Catalog=dbname"
providerName="System.Data.SqlClient"/>
to
<add name="LocalSqlServer"
connectionString="Data Source=(local);
Integrated Security=True;Initial Catalog=dbname"
providerName="System.Data.SqlClient"/>
Saturday, 29 March 2008
Open Visual Studio Project Folder in Windows Explorer
Select Tools, External Tools to bring up the External Tools dialogue box. Enter a title in the title field. In the command field, enter the path to the Windows Explorer executable. In the arguments field, enter $(ProjectDir) or select Project Directory from the side menu. Your dialogue should look as follows. Click OK.
You could leave it there. You can now click on a project in Solution Explorer and select Tools, External Tools, and pick the item that you added. Windows Explorer will open at the project’s location. To make things even slicker, add the external tool as an item on the tool bar. To do this, right-click on the tool bar and select Customize. In the left-hand pane of the dialogue box, select Tools. In the right-hand pane, select the item you added and drag to the tool bar. This is tricky as the tools are just shown as External Command 1, External Command 2 and so on. You will need to work out the number assigned to yours.
Once you’ve dragged the right one to the tool bar, you can give it a name and icon as you like by right-clicking on it again (still in Customization mode) and tweaking the settings.
Wednesday, 26 March 2008
Cannot set a value on node type 'Element'
XmlDocument xdoc = new XmlDocument();
xdoc.Load( MapPath( "XmlSample.xml" ) );
XmlNode node =
xdoc.SelectSingleNode( "//element[@id=100]" );
// The following line will lead to
// an InvalidOperationException
node.Value = "New value!!";
xdoc.Save( MapPath( "XmlSample.xml" ) );
Instead, use the InnerText property:
node.InnerText = "New value!!";
[Edited: 4 Aug 2008]
Tuesday, 25 March 2008
Validate XML in IE using JavaScript
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XML Validator</title>
<script type="text/javascript">
function loadit()
{
var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.validateOnParse = true;
xmlDoc.async="false";
xmlDoc.load("MyXmlFile.xml");
if (xmlDoc.parseError != '0')
{
document.getElementById("error").innerHTML
= xmlDoc.parseError.reason;
}
}
</script>
</head>
<body onload="loadit();">
<div id="error">
</div>
</body>
</html>
Wednesday, 19 March 2008
Unable to find script library '/aspnet_client/ system_web/1_1_4322/WebUIValidation.js'
aspnet_regiis -c
Create a virtual directory under your web site root called ‘aspnet_client’ with all the default options and point it to the aspnet_client folder under the web root (eg. C:\Inetpub\wwwroot\aspnet_client).
Make sure you have appropriate backups before attempting these suggestions, in case you need to roll back.
Error Saving a Query String to a Cookie
Response.Cookies["RequestedPage"].Values.Add("Url", HttpUtility.UrlEncode(value))
Wednesday, 12 March 2008
The following applications should be closed before continuing with set-up
Superb.
Tuesday, 11 March 2008
Root element is missing
How many CMS developers does it take to change a light bulb?
(Sorry.)
Thursday, 21 February 2008
Extract the Month from a DateTime Field in Sitecore
sc:formatdate(sc:fld('MyDateField', .),
'd MMM yyyy @ h:mm')
However, extracting just the month as a number without padding is less obvious. Using the format string 'MMM' gives three-letter month names, 'MM' gives months padded with zeros (eg. 02 for Feb), while 'M' curiously gives full month name and date padded with zeros.
A workaround is to use substring-after in conjunction with the format '/M'. Example:
substring-after(sc:formatdate(
sc:fld('MyDateField', .), '/M'), '/')
Friday, 15 February 2008
Get the Path of a Sitecore File Field Given a Media Path
<a href="{sc:fld('Path', sc:item(concat('/sitecore/media library', sc:fld('filefieldname', .)), .))}">Download file</a>
How to Determine Sitecore System Field Names
Here are some of the available fields (obtained from version 5.2):
Workflow:
__Workflow
__Workflow state
__Lock
__Default workflow
Help:
__Short description
__Long description
__Help link
Publishing:
__Publish
__Unpublish
__Publishing groups
__Never publish
Tasks:
__Archive date
__Reminder date
__Reminder recipients
__Reminder text
Lifetime:
__Valid from
__Valid to
Statistics:
__Created
__Created by
__Revision
__Updated
__Updated by
Might be obvious, but I couldn’t find a list on SDN.
Monday, 11 February 2008
Setting Query String Parameters in Xslt
Here’s a workaround. Let’s say you want to add a parameter called ‘page’.
First, build up the rest of the query string. The following template checks the existence in the query string of parameter names passed to it. You need to know the names of the possible parameters. If they exist, they are written out.
<xsl:template name="SetQueryParameter">
<xsl:param name="name" />
<xsl:if test="sc:qs($name)">
<xsl:text>&</xsl:text>
<xsl:value-of select="$name" />
<xsl:text>=</xsl:text>
<xsl:value-of select="sc:qs($name)" />
</xsl:if>
</xsl:template>
This template would typically be called from within a variable definition, therefore saving the created query string. In the following example, we are checking parameters type and orderby and saving them if they exist so we can add them back in later:
<xsl:variable name="RestOfQueryString">
<xsl:call-template name="SetQueryParameter">
<xsl:with-param name="name">type</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="SetQueryParameter">
<xsl:with-param name="name">orderby</xsl:with-param>
</xsl:call-template>
</xsl:variable>
You are then able to append this query string to your newly-added parameter, which you add using a ‘?’:
<a>
<xsl:attribute name="href">
<xsl:text>?page=10</xsl:text>
<xsl:value-of select="$RestOfQueryString" />
</xsl:attribute>
<xsl:text>Page 10</xsl:text>
</a>
Sunday, 10 February 2008
ASP.NET Custom Validator of ISBN Numbers
To use an ASP.NET custom validator to apply the validation logic, proceed as follows. (The code validates ten-digit ISBN numbers.)
First, drag a CustomValidator control to the design surface of Visual Studio. Set its ControlToValidate to the ID of the control that is to be validated (eg. a TextBox). Set the ErrorMessage and Text properties as required. Double-click the CustomValidator control and add the following code to the ServerValidate event handler (this is example starter code: you will need to check its suitability against your particular requirements):
protected void cvISBN_ServerValidate( object source,
ServerValidateEventArgs args )
{
string strInput = args.Value;
if( strInput.Length != 10 )
{
args.IsValid = false;
}
else
{
int checksum;
if( strInput[9] == 'X' )
{
checksum = 10;
}
else
{
checksum = (int)strInput[9] - 48;
}
int total = 0;
for( int i = 0; i < 9; i++ )
{
total += ( i + 1 ) * ( (int)strInput[i] - 48 );
}
args.IsValid = ( total % 11 == checksum );
}
}
To perform client-side validation too, you can write a similar function in JavaScript and attach it to the CustomValidator’s ClientValidationFunction property. The function should have the following signature:
function myvalidationfunction(source, args)
Friday, 1 February 2008
Posting back to a page without aspx extension
<asp:Button ID="btnSubmit" PostBackUrl="mypage"
runat="server" Text="Submit" OnClick="btnSubmit_Click" />
The located assembly's manifest definition does not match the assembly reference
Thursday, 31 January 2008
Culture 'en' is a neutral culture. It cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture.
“Culture ‘en’ is a neutral culture. It cannot be used in formatting and parsing and therefore cannot be set as the thread’s current culture.”
To overcome this, open the User Manager and add a value in the RegionalIsoCode field for the user affected. For GB English, enter en-GB.
Wednesday, 30 January 2008
Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache
aspnet_regiis -ga machinename\ASPNET(substituting machinename as appropriate).
Ensure also that the web site is an application (create an application in the IIS home directory).
If the message is simply “Service Unavailable” and you’re using IIS 6, check the application pool associated with your web site is running.
Tuesday, 29 January 2008
Type conflicts with the imported type
The type 'namespace.class' in 'C:\MyFolder\Class1.cs' conflicts with the imported type 'namespace.class' in 'assemblyfilename.dll'.
Generating Custom Configuration Sections in web.config (Part 2)
If you wish to implement custom sections yourself, here’s a simple example of how. This simple example uses standard key/value attributes and data that is not strongly typed. I shall later post a more advanced example, using strongly-typed data.
First, within the
<configSections>
<sectionGroup name="MySectionName">
<section name="Portal"
type="System.Configuration.NameValueSectionHandler,system,
Version=1.0.3300.0,Culture=neutral,
PublicKeyToken=b77a5c561934e089,Custom=null" />
</sectionGroup>
</configSections>
This uses the built-in handler. No further development is necessary.
You can then add keys to your custom section:
<MySectionName>
<MyStuff>
<add key="fruit1" value="apples" />
<add key="fruit2" value="oranges" />
</ MyStuff >
</MySectionName>
Finally, you extract the keys as follows:
NameValueCollection settings =
ConfigurationManager.GetSection(
"MySectionName/MyStuff")
as NameValueCollection;
Monday, 28 January 2008
XHTML-compliant links: There is no attribute "target"
There’s an interesting work-around on here:
http://www.sitepoint.com/article/standards-compliant-world
In short, they attach target="_blank" using JavaScript.
It seems like a fudge just to bypass the check, but the author argues it’s perfectly valid approach. The only downside is the reliance on JavaScript.
Friday, 18 January 2008
Introducing MicroScrum!
Here’s what we are now doing:
We work in sprints—the tasks making up each sprint go into TFS as work items (or rather, they will be going into TFS: haven’t got around to that bit yet!). Every morning, we have a “Scrumlet”. We use it to run quickly through the tasks listed and attach estimated remaining times. It’s also a chance to re-focus efforts for the day. I keep a burn down chart up to date for my own and team’s reference. The chart is a great way to manage time and it keeps my project manager happy. Its visible nature means that the impact of moving someone onto another project is readily apparent.
I add to each sprint a couple of recurring tasks, namely the running of unit and functional tests, plus the updating of documentation. (I think of the latter as continuous integration for documentation.)
Early indications are that using “MicroScrum” is a great way to ensure project delivery remains on track, or at least that problems are seen earlier.
Tuesday, 15 January 2008
Implementing the MVP Pattern in Sitecore XSLT Extension Methods
In the example I use, a “for-each” loop is used to display a list of makes of car.
First, create the view interface, defining the property or properties you want to display in the XSLT. As we are returning an array of values, the XPathNodeIterator return type is used:
{
XPathNodeIterator Cars { get; set; }
}Create an interface defining the method that will get the data or information from store:
{
XPathNodeIterator GetListOfCars();
}In your data access layer (DAL), implement the method that gets the data:
public XPathNodeIterator GetListOfCars()
{var cars = from c in GetMyData()
orderby c.Make
select c;
XDocument xdoc = new XDocument();
XElement xmlTree = new XElement("Cars");
foreach( var car in cars )
{
xmlTree.Add(new XElement("Car",
new XAttribute("Make", car.Make)));
}
xdoc.Add(xmlTree);
return xdoc.CreateNavigator().Select("/Cars/Car");
}Create the presenter class, which will store references to the view and DAL method interfaces, and define the method(s) that will set the value of the property or properties on the view:
public class CarsPresenter
{
private readonly ICarsView _view;
private readonly ICar _icar;
public CarsPresenter( ICarsView view, ICar car )
{
_view = view;
_icar = car;
}
public void SetCarsProperty()
{
_view.Cars = _icar.GetListOfCars();
}
}
Create the extension method that implements the view:
public class CarsView: ICarsView
{
public XPathNodeIterator GetListOfCars()
{
CarsPresenter cp = new CarsPresenter(this, new CarsDal());
cp.SetCarsProperty ();
return Cars;
}
#region IAgreementsView Members
public XPathNodeIterator Cars
{
get; set;
}
#endregion
}
In the web.config file, add an extension element to the xslExtensions element that references the concrete view. Use one such element for each namespace:
<extension mode="on" type="XsltViews.CarsView, XsltViews"
namespace=" http://example.com/xsltviews/cars " />
In your XSLT file, declare the namespace prefix by adding it to the stylesheet element and including the prefix in the exclude-result-prefixes attribute:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sc="http://www.sitecore.net/sc"
xmlns:dot="http://www.sitecore.net/dot"
xmlns:view="http://example.com/xsltviews/cars"
exclude-result-prefixes="dot sc view">
Finally, you can now call the method from your XSLT:
<xsl:for-each select="view:GetListOfCars()">
<xsl:value-of select="@Make"/>
</xsl:for-each>
Monday, 14 January 2008
Creating Simple Loops in XSLT
I have defined a template that will do the work of the loop. It checks the value of a variable called 'counter' before calling itself. This is the loop condition. Before this test, you can add whatever it is you need the loop to do. In the following example, I print the letters of the alphabet, followed by "... Hello!":
<xsl:template name="DoLoop">
<xsl:param name="counter" />
<xsl:variable name="letter"
select="substring($alphabet, $counter, 1)" />
<!--Body of loop goes here-->
<xsl:value-of select="$letter" />... Hello!
<br/>
<!--End of loop body-->
<xsl:if test="$counter < 26">
<xsl:call-template name="DoLoop">
<xsl:with-param name="counter">
<xsl:value-of select="$counter+1" />
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
The loop is then initiated by calling it with the desired starting value:
<xsl:call-template name="DoLoop">
<xsl:with-param name="counter">1</xsl:with-param>
</xsl:call-template>
For info, the alphabet variable is simply defined as:
<xsl:variable name="alphabet">
<xsl:text>ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:text>
</xsl:variable>
Thursday, 3 January 2008
How to Change String Case in XSLT
<xsl:variable name="lowercasetext" select="translate($inputtext, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
To upper case a string, simply swap the position of the two alphabet literals shown.