SiteMapProviders Source#

Scott Guthrie posted the link to the source for the the ASP .NET 2.0 Providers which includes the SiteMapProviders.  It is much easier to look at the source than to hurt your eyes looking at reflector.

Wednesday, May 31, 2006 2:28:17 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Presenting Abby!#

I’m proud to present the newest member of my family, Abby.  Yesterday my wife and I went down to the Denver Dumb Friends League and we fell in love with Abby at first sight.  Abby is an interesting Lab/Shar Pei mix which gives her very cute wrinkles on her face.   We had to wait an hour to have a chance to see if we could get her before anyone else.  They brought her into an office and she crawled into my lap and fell asleep.  Enough said.

AbbyPuppy

Monday, May 29, 2006 2:19:40 AM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Automated web testing with Selenium#
A coworker pointed me to this Selenium post by Jeremy Miller and it is pretty impressive what you can do with minimal effort.  I sent it off to my wife and she started using it right away and it is making her life much easier.  If anyone if looking at automating some of  web testing it is worth a look.
Monday, May 22, 2006 4:56:11 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Working with the SiteMap in 2.0#

The SiteMap class is new in .NET 2.0 and provides a new way to manage navigation in 2.0.  Before I get too much further you can download the ExtendedXmlSiteMapProvider I wrote here.  There are some limiting factors that I found and had to deal with. 

  • It is not possible to add nodes at runtime to an existing node using the default SiteMapProvider which is the XmlSiteMapProvider.
  • The Web.sitemap does not support a definition for the key in the SiteMapNode definition.

My first bullet point was easy to solve, since the SiteMap uses the provider pattern I was able to create my own provider which derived from the XmlSiteMapProvider.  First a little more background on the problem.  Why was I not able to add to the ChildNodes collection, well this collection is readonly which does not help much.  There are protected methods for adding nodes on the XmlSiteMapProvider so I just exposed public methods to add nodes which called the protected add method.  To replace the default provider add the below lines to your web.config.

            <siteMap enabled="true" defaultProvider="ExtendedXmlSiteMapProvider">

                  <providers>

                        <add name="ExtendedXmlSiteMapProvider"

                              type="ERA.PT.Common.Web.ExtendedXmlSiteMapProvider"

                              siteMapFile="Web.sitemap" />

                  </providers>

            </siteMap>

Whenever you want to dynamically add nodes you probably want to also remove/clear them at some point.  I chose to be able clear child nodes for the current node or specifying a specific node.  The add methods and clear methods I used are shown below.

        /// <summary>

        /// Calls base functionality to add a new node.

        /// </summary>

        /// <param name="node">new node to add</param>

        /// <param name="parentNode">parent node for the new node</param>

        private void AddNewNode(SiteMapNode node, SiteMapNode parentNode)

        {

            if (node != null && parentNode != null)

            {

                base.AddNode(node, parentNode);

            }

        }

 

        /// <summary>

        /// Adds the new node.

        /// </summary>

        /// <param name="key">The key.</param>

        /// <param name="url">The URL.</param>

        /// <param name="title">The title.</param>

        /// <param name="parentNode">The parent node.</param>

        /// <returns></returns>

        public SiteMapNode AddNewNode(string key, string url, string title, SiteMapNode parentNode)

        {

            SiteMapNode node = new SiteMapNode(this, key, url, title);

 

            this.AddNewNode(node, parentNode);

 

            return node;

        }

 

        /// <summary>

        /// Adds the new node to current.

        /// </summary>

        /// <param name="key">The key.</param>

        /// <param name="url">The URL.</param>

        /// <param name="title">The title.</param>

        /// <returns></returns>

        public SiteMapNode AddNewNodeToCurrent(string key, string url, string title)

        {

            return this.AddNewNode(key, url, title, this.CurrentNode);

        }

 

        /// <summary>

        /// Clears the nodes under the current node.

        /// </summary>

        public void ClearCurrentChildNodes()

        {

            this.ClearChildNodes(this.CurrentNode);

        }

 

        /// <summary>

        /// Clears the nodes.

        /// </summary>

        /// <param name="parentNode">The parent node.</param>

        public void ClearChildNodes(SiteMapNode parentNode)

        {

            if (parentNode != null && parentNode.ChildNodes.Count > 0)

            {

                SiteMapNodeCollection nodes = parentNode.ChildNodes;

                for (int i = nodes.Count - 1; i >= 0; i--)

                {

                    base.RemoveNode(nodes[i]);

                }

            }

        }

For my second bullet point of the Web.sitemap not supporting the definition of a key.  Well I have not done anything with this one yet.  By default your key is the url defined in the Web.sitemap so that is what I use to find nodes.  What I would like to do is write my own BuildSiteMap in the provider that would use an attribute in siteMapNode element defined as key to set the key of the node.  Keys are much easier to manage than url’s when it comes to finding nodes.  Not sure when I will get around to this, if ever.

One question I asked myself is: How do I set the current node?  You may ask why would you want to do that.  If you have a link in a page that corresponds to the navigation and you would like the bread crumb to show the location.  This can be done by listing to the SiteMapResolved event which gets called each time the current node is asked for.  In the handler for SiteMapResolved you can search for what is your current node or you could expose a method to set the current node.  I did this using the code shown below.

        private SiteMapNode currentNode;

 

        /// <summary>

        /// Initializes a new instance of the <see cref="T:ExtendedXmlSiteMapProvider"/> class.

        /// </summary>

        public ExtendedXmlSiteMapProvider()

        {

            this.SiteMapResolve += new SiteMapResolveEventHandler(ExtendedXmlSiteMapProvider_SiteMapResolve);

        }

 

        private SiteMapNode ExtendedXmlSiteMapProvider_SiteMapResolve(object sender, SiteMapResolveEventArgs e)

        {

            SiteMapNode node = null;

            node = e.Provider.FindSiteMapNode(e.Context);

            if (node == null)

                node = e.Provider.FindSiteMapNode(e.Context.Request.Url.AbsoluteUri);

 

            if (node == null)

                node = currentNode;

            else

                currentNode = null;

 

            return node;

        }

 

        /// <summary>

        /// Sets the current node.

        /// </summary>

        /// <param name="currentNode">The current node.</param>

        public void SetCurrentNode(SiteMapNode currentNode)

        {

            this.currentNode = currentNode;

        }

 

If you did not see the link at the top you can download the ExtendedXmlSiteMapProvider here.  If anyone knows an easier way to do what this please let me know.

Monday, May 22, 2006 3:00:49 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Front Range Code Camp CAB Slides and Demo Code#
Thanks everyone for coming out for the front range code camp!  I hope everyone took away something from my talk on CAB.  You can download the sample code and slides from my CAB talk here.
Monday, May 22, 2006 12:15:18 AM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Front Range Code Camp is this weekend!#

Don’t forget the Front Range Code Camp is this weekend.  Come out and meet some of your fellow developers and learn/teach a thing or two.

See ya there.

Wednesday, May 17, 2006 1:45:08 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Patterns and Practices gets a new workspace#

Anyone that enjoys working in a collaborative work environment should take a look at Brad’s post.  This is the coolest setup I have seen yet!

Tuesday, May 16, 2006 3:52:30 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

SecureQueryString 2.0#
Just finished modifying some code to use TSHAK’s SecureQueryString.  I got to give him props, easy to use and works perfectly for my purposes.
Monday, May 08, 2006 10:38:07 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

The good and bad of virtual machines#

I’m a very big fan of the use of virtualization.  Virtualization provides a controlled environment and helps get new people to the team contributing value very quickly.  Lately I have noticed a tendency others have when each person on the team is using a copy of the same virtual machine.  This is the tendency to hard code paths! Because hey everyone has the same virtual environment.

This drives me nuts to no end.  Relative paths are very easy to use and maybe it takes an extra few seconds to figure out how to write the script using relative paths but the payoff is huge for the future when you start moving and extending the scripts to do other things.

Saturday, May 06, 2006 3:23:14 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Reporting Service: XML Query and defining columns#

No longer did I finish me last post did I remember another little tidbit that may interest people.  Some of you probably have wondered why you have to define the columns in your Xml query instead of just leaving out the “{}” from the end of your query and get all columns in the Reporting Services Designer Dataset explorer.  This does in fact work but with some very strict rules which is why I define the columns I want.  As an example

<Query xmlns:es="http://test.test.com">
<SoapAction>http://test.test.com/RetrieveOrganizations</SoapAction>
<ElementPath>es:RetrieveOrganizationsResponse{}/es:RetrieveOrganizationsResult{}/es:OrganizationInfo{es:OrganizationId, es:OrganizationName}</ElementPath>
</Query>

will retrieve the OrganizationId and OrganizationName that will show up in the Dataset explorer in the Report Designer.  These are the only two columns that exist in the entity.  The below query should do the same

<Query xmlns:es="http://test.test.com">
<SoapAction>http://test.test.com/RetrieveOrganizations</SoapAction>
<ElementPath>es:RetrieveOrganizationsResponse{}/es:RetrieveOrganizationsResult{}/es:OrganizationInfo</ElementPath>
</Query> 

but it only retrieves the OrganizationId in the Dataset explorer.  Why?  Well this has to do with the implementation of the entity that is being retrieved from the web service.  When the Dataset explorer refreshes it makes a call to the webservice to see what the return type is going to be (with null parameters of course).  If the properties, which represent your columns in RS Dataset explorer, are initialized to null or an empty string they will not show up in the Dataset explorer.  This is unfortunate with the introduction of nullable types in .NET 2.0.

Anyway the easy work around is to just define you columns in your query.

Saturday, May 06, 2006 3:15:08 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Reporting Services: Beating a dead horse with XML Queries#

In my previous posts (1, 2, 3) I gave some examples of queries to be used with xml datasources.  Looking back at those I realized that I did not give a good example using the namespace alias in the column definition in the ElementPath part of the query.  So here it is:

<Query xmlns:es="http://test.test.com">
<SoapAction>http://test.test.com/RetrieveOrganizations</SoapAction>
<ElementPath>es:RetrieveOrganizationsResponse{}/es:RetrieveOrganizationsResult{}/es:OrganizationInfo{es:OrganizationId, es:OrganizationName}</ElementPath>
</Query>

Notice in the ElementPath I ask for the es:OrganizationId and es:OrganizationName from the es:OrganizationInfo.

I hope this helps some poor soul out there from pounding their head against the wall trying to figure out this not well documented feature.

Saturday, May 06, 2006 2:52:45 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

Reporting Services: Soap Actions and Namespaces#

I got a comment on my blog by Alexei Pavlov who was having an issue with report parameters not being passed to a web service. 

Honestly I forgot all about running into this, it must be old age.  Basically a concatenation happens using the namespace and if the namespace has a trailing slash you get “//” in the uri for the soap action.  I have ran into issues before with trailing slashes and reporting services so it was one of the first things I tried and it worked.  I presume that there is a string concatenation going on instead of building a URI.  Alexei Pavlov found a good link that explains the problem and the solution on channel 9.

Thursday, May 04, 2006 1:59:57 AM (GMT Standard Time, UTC+00:00) #    Comments [0]  | 

 

All content © 2008, John Luif
On this page
This site
Calendar
<November 2008>
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
Archives
Sitemap
Blogroll OPML
Disclaimer

Powered by: newtelligence dasBlog 2.1.8102.813

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Send mail to the author(s) E-mail

Theme design by Jelle Druyts