SharePoint 2007 Wiki Link Limitation
So in the course of our daily events here on my project, one of the business analysts came over and asked me to look at a wiki page that they were setting up. It seemed as if the page had stopped rendering the link for the new page creations part way through the page. I immediately went and opened up my developer tools and looked at the styles and sure enough the styles were different.
The problem is a little bigger than it first seems because any of the broken links result in 404′s when you try to navigate to them
So I Googled a bit on the internet and found an obscure post on some scraped message board that said there was a 100 link limit. So I opened up excel and generated 120 wiki links and pasted them into a test page. Sure enough the first 100 were highlighted properly and the rest were broken in a similar fashion to what we had already seen.
I then tested filling in one of the links so it was no longer missing. Once the associated page was created and saved, you could see that now that link was appropriately highlighted, as it had content, and now link 101 was highlighted as a missing item. Confirming my suspicion that there is an internal SharePoint 2007 wiki limit of 100 links.
I imagine this was imposed in order to ensure wiki page responsiveness and the solution is simply not to have more than 100 links without content on a single wiki page. The 404 situation is unfortunate, but unavoidable.
In: Programming · Tagged with: SharePoint 2007, Wiki
jqSOAPClient and Firefox truncating XML Response
So I was trying to figure out why my little Stock Ticker control was never getting any results. It was implemented inside of a SharePoint 2007 site using jQuery and jqSOAPClient. I had to use the SOAP stuff to integrate with the standard web services provided by SharePoint.
So I created this service and everything was working great, until one day Firefox just decides to totally break and not show the Stock Ticker information. Since I was not having this problem in any other browser I was a little skeptical that I had some major bug in the code, but rather there was some browser peculiarity that was causing the issue.
Long story short, there was, and I found an identification of the cause here: http://www.coderholic.com/firefox-4k-xml-node-limit/.
So now what to do? Well fix it of course…
So the trick was to use the fix that was detailed on the Coderholic blog and insert it in the right place, in the jqXMLUtils file around line 55 there is a case statement, case 3, where I inserted the code from the Coderholic blog.
... case 3: //Text Value var resultText; if(typeof(cnode.parentNode.textContent) != "undefined") { resultText = cnode.parentNode.textContent; } else { resultText = cnode.nodeValue; } obj.Text = $.trim(resultText); break; ... |
Looking through the code, there is probably something else that should be done with the CData elements as well identified in case 4, but for my purposes this is sufficient.
Source: jqXMLUtils.js
In: Programming · Tagged with: JavaScript, SharePoint 2007, SOAP
SharePoint 2007 WSPBuilder Development Cycle
I have been asked a couple times now to onboard new people the SharePoint 2007 project that I am working on. While these developers are confident in their ability to address problems and to troubleshoot, they are stymied by the debugging and troubleshooting process in SharePoint. Hence this article.
First of all, get WSPBuilder (http://wspbuilder.codeplex.com/, it will make your life much easier and the Visual Studio integration works well and automates many procedures you would being doing manually.
12 Hive Asset Development
So there are a couple streams that you might follow when you are working in SharePoint, if you are dealing with something that lives in the 12 hive, .ascx controls, .aspx pages, and other file based resources, you are going to want to leverage the ‘Copy to 12 hive’ option listed on the WSPBuilder context menu. Pressing this does exactly what you think, copies the file from your project into the 12 hive. Reloading the page on which the control sits will then cause a re-render of the control/asset and then you can see your changes.
You can use this function at a project level to copy all resources or at an individual file level as well. A very good and handy shortcut. It should also be noted that this option is not available until you have Built and deployed a WSP as well so you are going to want to do that the first time, to create the appropriate registrations, and then use this functionality to iterate as you develop your code.
Developing Code Solutions (DLLs in the GAC)
Here you are going to want to leverage first the build process and then you are going to want to copy them into the GAC. You can also find this option on the WSPBuilder context menu in visual studio. Again you are going to need to deploy a WSP for the first time and then after that you can use this shortcut. Jumping back to your page and reloading will allow you to see your changes.
You will notice that pages take longer to load this way and it is because the Application Pool needs to be reset when DLL changes are made to the GAC. Be patient, it is the fastest route that you can take in SharePoint development unfortunately.
Debugging
On the WSPBuilder context menu there is an option way down at the bottom that says, ‘Attach to worker processes’. This is your debugging shortcut. It will automatically put Visual Studio into debug mode and attach the debugger to all your running w3wp.exe processes which will effectively allow you to debug your code. One thing to watch out for is that you compiled code in that GAC will need to be the same DLL that is in your local debug directory. If it is not hitting your breakpoints, or your breakpoints are hollow, check to see that everything is lined up.
The general process for debugging is:
- Build
- Copy to GAC
- Reload Page
- Wait…
- Attach Debugger
- Wait…
- Reload Page
- Debug your code!
If you are just deploying to the 12 hive you can skip 1 and 2 and just Copy to 12 hive.
Hope that helps some people out there.
In: Programming · Tagged with: Onboarding, SharePoint 2007, WSPBuilder, WSS 3.0
Awesome Example – Adding List and Site Name to an CQWP for SharePoint 2007
I have had to refer back to this site a couple times to make some different lists, so I thought I should link to it and provide a little better search ranking to it, should someone be looking for this in the future.
http://sharepoint-tweaking.blogspot.com/2008/04/displaying-listname-and-sitename-when.html
In: Programming · Tagged with: SharePoint, SharePoint 2007
SharePoint Tool Basket 2007 Page Ratings UX
The SharePoint Tool Basket presents us with a couple of great tools to use on our pages, in particular we have been making use of the Document Rating Webpart which was included. The functionality was all there to add the ratings to the page, but it’s user experience was perhaps a little too streamlined and resulted in users being a little confused as to what was happening.
The default behavior was to immediately take your page rating when you clicked on the star in order to have it submit that to the back end service. The rating stars would then show the average rating again and flash a message saying that your vote had been taken into consideration. Often times our less computer savvy users found this confusing and would end up clicking over and over wondering why their vote took but as soon as they moved their mouse off it seemed to snap back to some other value, making them think that there vote did not stick.
To counteract this I went in and introduced some JavaScript to modify the behavior so that the users had to click a ‘Rate this article’ link which would then clear all the stars and allow the user to cleanly interact with the rating stars. When a user clicked on the star of their choice, that would be taken into account, the message would be displayed and the average rating would then be shown again.
In pictures, standard view:
User entry mode:
And to do this I added this JavaScript:
<script type="text/javascript" language="javascript"> function showRatingsHelp() { $('.one-star,.two-stars,.three-stars,.four-stars,.five-stars').show(); $('div.rating-help-text-container').slideDown('fast'); $('li#HighLight_CurrentRatingPage').hide(); $('.rating-help-label').hide(); } function hideRatingsHelp() { $('div.rating-help-text-container').slideUp('fast'); $('li#HighLight_CurrentRatingPage').show(); $('.rating-help-label').hide(); $('.one-star,.two-stars,.three-stars,.four-stars,.five-stars').hide(); } $('ul.star-rating li a').live('click', function() { hideRatingsHelp(); }); $(document).ready(function() { $('.one-star,.two-stars,.three-stars,.four-stars,.five-stars').hide(); }); </script> |
I also had to add the actual help text and the ‘Rate this page’ text:
<div class="rating-help-label" style="float:left;margin-left:10px;margin-top:12px;">
<a href="javascript:showRatingsHelp()">Rate this page</a>
</div>
<div class="rating-help-text-container" style="display:none;clear:both;">
Click on the number of stars you wish to rate this page.<br/>
If you have already rated this page your last rating will be updated.
</div> |
But that was pretty much it. I can’t take all the credit, it was Scott Anderson over from UX Guys (http://www.uxguys.com/about/scott.html) who had the process improvement, I just had to implement it.
In: Programming · Tagged with: JavaScript, SharePoint 2007, User Experience, Web Programming
log4net in SharePoint not writing log files
I noticed that SharePoint was not allowing log4net to write files into the log directory and I was not sure why.
The answer seemed to be that the user that spins up the application pool, in the model that I was using for configuring my logging instance, was not a site collection admin and did not have access to write into the logging directory. I simply wrapped the configuration in an elevated context and that fixed the issue.
Extended Content Query Pager not Paging Properly
I had an interesting bug today. I was looking at the news article list that we had developed using the Imtech Extended Content Query from codeplex and the associated pager that comes along with it.
Funny thing was that whenever I clicked on a different page it wouldn’t take me there. I thought maybe my eyes were deceiving me because when I tried again it worked!
So after some testing and some meetings we were able to replicate the issue, the symptoms being that if you left the page open for some period, usually around 2 minutes, the page would reset and this wouldn’t be an issue. Furthermore, the problems were only experienced by visitors to the site, not authors or anyone further up the permissions chain.
We cracked open the code and didn’t really see anything that would cause any problems. But then a thought came, perhaps it was the site output cache not respecting changes in the query string and subsequently caching the pages. Bingo!
So in order to fix this we had to,
- Log in as a site collection administrator
- Go to the site collection settings
- Choose the Site Collection Output Cache Profiles
- Choose the appropriate caching profile for the site you are working on (you can find that in the Site Collection Output Cache settings)
- Then edit the profile and add ‘*’ to the vary by query string option
- Save the settings
Changing this setting will force the output cache to keep a different version of the page for every unique query string.
For a more in depth discussion on Page Output Caching see the Microsoft article which can be found here: http://msdn.microsoft.com/en-us/library/ms972362.aspx
SharePoint 2007: Delete Site yields ‘The System cannot fined the path specified’ error message
Thanks to networksteve.com for this article about how to resolve this issue:
C:>stsadm -o deletesite -url http://localhost The system cannot find the path specified. (Exception from HRESULT: 0x80070003) |
Resolution was to:
- stsadm -o databaserepair -url http://locathost -databasename localhost_content
- Go into central admin -> Application Management -> Content Databases and drop the content database
- Add the content database back in
It was buried a couple posts down the page, so I wanted to make sure this solution could easily be found.
Original post is at: http://www.networksteve.com/enterprise/topic.php?TopicId=6911
Azure Table Storage Article
I was poking around on the internets looking at people’s oppinions of Table Storage and I found this article by Michael Hamrah:
http://www.michaelhamrah.com/blog/2009/05/i-hate-persistence-but-love-azure-table-storage-with-data-services/
The highlight of the article for me was this statement:
I hate dealing with persistence because it’s totally mundane and repetitive code. Worse, nobody outside of IT really understands the details of persistence. Which means it has no business value.
I found the statement quite interesting simply because I know that I have on more than one occassion had to sit with business users and project managers alike that are very interested in the minutia of the interface and how the buttons are arranged but absolutely no interest in the fact that I templated out the ultra complex dynamic HQL query that can take any of 25 parameters and pull from an object graph that contains entities from 15 different tables with nested log entries by date. Maybe that was me just venting a little bit, but damnit it was cool.
I guess more to the point is that most people that are on the executive side of the equation, those people outside IT, really don’t care about the mechanism, they just care about the end result. It is important then that we, as IT professionals can provide that value to the business.
I think this is probably the reason for the success of products like SharePoint. People understand lists of data, documents, people, etc. That’s cool with me, as long as there is business value.
Me? I like pretty code.
SharePoint Links List Toolbar Removal
Found this blog article that really helped out in removing the toolbar off of a ListViewWebPart for a links list. I thought it was worth posting here, so I could find it again…
http://www.nearinfinity.com/blogs/joe_ferner/changing_the_toolbar_on_a_shar.html
One caveat that I would add to this is that you need to make sure that the web part is on the page before you execute this command. It will fail because there is no storage key defined for the component until it is added to the web page.
I took the liberty of updating the code with a check for the storage id and threw a more meaningful exception. The updated code is below.
using System; using System.Reflection; using Microsoft.SharePoint; using Microsoft.SharePoint.WebPartPages; namespace Intranet.Portal.Custom.Extensions { public static class ListViewWebPartExtensions { public static void SetToolbarType(this ListViewWebPart lvwp, SPLimitedWebPartManager limitedWebPartManager, ListViewWebPartToolbarType type) { #pragma warning disable 618 string storageKey = lvwp.StorageKey.ToString("B").ToUpper(); string listId = lvwp.ListName; string viewId = lvwp.ViewGuid; uint toolbarType = (uint)type; if (String.IsNullOrEmpty(storageKey) || storageKey == Guid.Empty.ToString()) throw new Exception("The webpart must be added to the page before this method (SetToolbarType) can be called"); // get the SPWebPartManager from SPLimitedWebPartManager PropertyInfo webPartManagerProp = typeof(SPLimitedWebPartManager).GetProperty( "WebPartManager", BindingFlags.NonPublic | BindingFlags.Instance); SPWebPartManager webPartManager = (SPWebPartManager)webPartManagerProp.GetValue(limitedWebPartManager, null); // get the SPWebPartConnection from SPWebPartManager PropertyInfo spWebPartsProp = typeof(SPWebPartManager).GetProperty( "SPWebParts", BindingFlags.NonPublic | BindingFlags.Instance); SPWebPartCollection webParts = (SPWebPartCollection)spWebPartsProp.GetValue(webPartManager, null); // Call the ApplyViewToListWebPart method on the SPWebPartConnection // internal void ApplyViewToListWebPart( // string storageKey, // string "listID" , // string "viewID" , // uint toolbarType, // out uint flags) MethodInfo applyViewToListWebPart = typeof(SPWebPartCollection).GetMethod( "ApplyViewToListWebPart", BindingFlags.NonPublic | BindingFlags.Instance, null, new[]{ typeof(string), typeof(string), typeof(string), typeof(uint), typeof(uint).MakeByRefType() }, null); object[] parameters = new object[5]; parameters[0] = storageKey; parameters[1] = listId; parameters[2] = viewId; parameters[3] = toolbarType; applyViewToListWebPart.Invoke(webParts, parameters); #pragma warning restore 618 } } public enum ListViewWebPartToolbarType { Full = 0, Summary = 1, NoToolbar = 2 } } |
In: Uncategorized


