Saturday, January 26, 2008

Error Rendering Control with ASP.NET WizardStep and Accordion Controls

If you're using the .NET Framework 2.0 with Visual Studio 2005 and ASP.NET AJAX 1.0, you may run into odd errors when you use the Wizard control and you try to embed an Accordion control inside a WizardStep.

When I did this, it was all in the ASPX code view and the code-behind file. The page and the project built cleanly and the run-time tests were fine, as well. But when another developer then tried to switch the ASPX to design view he saw an error for the entire Wizard control that said "Error Rendering Control" and then the project failed to build throwing errors complaining about the Accordion. We carefully tested this to make sure no other edits were made, that we could reproduce it, and that nothing in our configurations changed. When we reverted that file back to the original, the project built cleanly again and worked fine when deployed.

After some searching, all I could find was one post on the http://www.asp.net/ AJAX forums that said it was a known issue in VS 2005 that was fixed in VS 2008. We haven't purchased VS 2008 yet and we're not prepared to upgrade to Framework 3.5 on our production servers yet either, so the suggestions here are not that helpful.

If anyone has a fix for this using Framework 2.0 + VS 2005 + ASP.NET AJAX 1.0, I'd love to hear it.

Thursday, January 24, 2008

Modify an XML Fragment Retrieved by MarkLogic Server

Last week I was experimenting with a scenario where I wanted to retrieve a section of a larger XML document from MarkLogic Server, but modify it before passing it up to the web application layer (we're using MarkLogic -> XCC -> ASP.NET). This XQuery sample recurses through all of the element and text nodes, modifies what's needed, and passes the rest back unchanged. In the end we decided on a different approach, so this query is not tuned but the premise is interesting. I think there's probably a better way to structure the default handler, but for now ...

define variable $myId as xs:string external

define function recurse($node as node()) as node()*
{
for $i in $node/node() return modify-fragment($i)
}

(: Here we define which elements we want to modify and declare
a handler for them. :)
define function modify-fragment($node as node()) as node()*
{
typeswitch ($node)
case text() return text-handler($node)
case element(ref) return ref($node)
case element(see) return see($node)
case element(see-also) return see-also($node)
default return default-handler($node)
}

define function text-handler($node as node()?) as node()*
{
if(empty($node)) then ()
else (text {$node})
}

define function default-handler($node as node()?) as element()*
{
element { local-name($node) }
{ $node/@*, recurse($node) }
}

define function see($element as element(see)) as element()
{
let $destination-node := $element/ancestor::book/
descendant::node()[@local-id=$element/@seeref] return
if(not(empty($destination-node/ancestor-or-self::node()
[@fragment='true'][1]))) then
< see>
{ $element/@* }
{
attribute {"destination-node"}
{local-name($destination-node)},
attribute {"fragment-local-id"}
{$destination-node/ancestor-or-self::node()
[@fragment='true'][1]/@local-id}
}
{ recurse($element) }
< /see>
else recurse($element)
}

define function see-also($element as element(see-also)) as element()
{
let $destination-node := $element/ancestor::book/
descendant::node()[@local-id=$element/@seeref] return
if(not(empty($destination-node/ancestor-or-self::node()
[@fragment='true'][1]))) then
< see-also>
{ $element/@* }
{
attribute {"destination-node"}
{local-name($destination-node)},
attribute {"fragment-local-id"}
{$destination-node/ancestor-or-self::node()
[@fragment='true'][1]/@local-id}
}
{ recurse($element) }
< /see-also>
else recurse($element)
}

define function ref($element as element(ref)) as element()
{
if($element/@type='local-id') then
let $destination-node := $element/ancestor::book/
descendant::node()[@local-id=$element/@value] return
if(not(empty($destination-node/ancestor-or-self::node()
[@fragment='true'][1]))) then
< ref>
{ $element/@* }
{
attribute {"destination-node"}
{local-name($destination-node)},
attribute {"fragment-local-id"}
{$destination-node/ancestor-or-self::node()
[@fragment='true'][1]/@local-id}
}
{ recurse($element) }
< /ref>
else recurse($element)
else recurse($element)
}

(:let $myId := 'ID1234':)

for $i in (//chapter[@local-id = $myId] | //entry[@local-id = $myId])[1]
return

< fragment imagepath="{$i/property::imagepath/text()}">
{
recurse($i)
}
< /fragment>

Monday, January 21, 2008

My New Kakadu

About two weeks ago I was packing up my stuff and getting ready to leave work when I noticed something stunk. It was my 6-year-old black Eddie Bauer shoulder bag and it was not pleasant.

I had a little Christmas cash in my pocket, so I shopped around a little. After looking at bags from Timbuk2, Chrome, Manhattan Portage and many others I decided that a) they're all over-priced and b) they're all dangerously close to man purses.

I turned to various Army/Navy store outlets and companies that produced similar bags. Most were either way too small, way too big, or had some obnoxious logo on them. Then I found Kakadu Imports. At $49.75, their satchel bag is inexpensive, rugged, and cool. The bag is solidly constructed, the straps are sturdy, and the hardware is nice and heavy...heavy enough where I could club a purse-snatcher soundly. =)

If you're looking for a new bag, check them out. I'm definitely happy with mine.

Tuesday, January 15, 2008

XQuery Support in MarkLogic Server

It's a buried a little deep, but here's how to find out which version of the XQuery spec your version of MarkLogic supports.

Got to http://developer.marklogic.com/ and find the documentation. Find the release notes. Find the section called "Compatibility with XQuery Drafts."

Here's the information for 3.2.
This release implements the XQuery language, functions and operators specified in the May 02, 2003 W3C XQuery Working Group Draft Recommendations:
Additionally, much of the added functionality in the January 2007 W3C XQuery Recommendation is implemented in MarkLogic Server 3.2.

Friday, January 4, 2008

Vista Downgrade

As I mentioned in an earlier post, I have a computer with Microsoft Vista. Had. After several months of trying to live with it, I decided to downgrade to XP Pro. I want the OS to stay out of the way and just work and perform reasonably. Is that really so much to ask?

Getting all the drivers straight was a bit of a pain, but the machine is back up and running now. All I have to say is ... ahhhhhhh.

Tuesday, January 1, 2008

Get a Random Item from an Array in ASP.NET

Here's a quick and easy way to get a random item from an array in ASP.NET.
string[] myImages = { "/images/one.gif", "/images/two.gif", "/images/three.gif" };
string randomItem = myImages[ new Random().Next( 0, my.GetLength(0) ) ];

"The state information is invalid for this page and might be corrupted" Using ASP.NET AJAX

When you're using ASP.NET AJAX and the user accesses your site using Firefox, the user may see an error message that says "The state information is invalid for this page and might be corrupted." This seems to be caused by Firefox's methods for saving session information in its cache. There are a couple of ways to make sure this doesn't happen, depending on how extensive you want to disable the cache. In my case, I just wanted to do it on one page, so at the top of Page_Load I added:
Response.Cache.SetNoStore();
You could also set this in the page declaration with:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="account.aspx.cs" Inherits="Main" Title="My Account" EnableViewStateMac ="false" EnableSessionState="True" EnableEventValidation ="false" ValidateRequest ="false" ViewStateEncryptionMode ="Never" %>

You could also add something like the below to Web.config:

<pages validateRequest="false" enableEventValidation="false" viewStateEncryptionMode ="Never">