Required fields and linking to other lists

Had an interesting problem come up at work the other day.   I had written some custom code that reads from ListA (which has 3 required fields one of which is a lookup into ListB) and outputs them.   Every so often the web part would come back saying that one of the entries was missing a field.   I could not figure out how an entry was being created that did not have all the required fields.  I tried the SharePoint UI and the dataview and both would not let me create the entry without having the required field filled in.


Turns out that you cannot create the entry without the required fields.  However, one of the fields is a lookup into ListB and if that entry is deleted from ListB then the field in ListA that was using that entry is now blank.  I can see why MS did this (and if memory serves this is different than how it worked in 2003) but what a pain figuring it out!


Of course the other option is to check every field to make sure it is not NULL before trying to process it and ignore those entries that were not completebut it was decided that we would not that in this case.

Create a web part to show sites and sub-sites

Saw a newgroup question the other day about how to do this in SharePoint 2007.  While the solution posted works quite well here is some code that I wrote that should accomplish what the user needs.   This will either start at the root of your site collection or a specified location (which may or may not be the site you are on).  It will then add all the sites and sub-sites to a treeview control, security trimmed of course.  Note that it uses recursion to view all the sub-sites so depending on how your system is architected this may take a while.  Guess a simple enhancement would be to add a parameter to limit the depth of your treeview.  You could get even more fancy and show X levels by default and then if you expand beyond that add the nodes dynamically.  [:D] 


 


using System;
using System.Runtime.InteropServices;
using System.Web;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;


using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Publishing.Navigation;


namespace GBushey.Portal.SiteMap
{
    [Guid(“1e900b56-1f33-4772-b5b9-9df73612c40d”)]
    public class PortalSiteMap : System.Web.UI.WebControls.WebParts.WebPart
    {
        string _StartNodeName;
        bool _StartAtTopLevel = false;


        [WebBrowsable(true),
        Personalizable(PersonalizationScope.Shared),
        FriendlyName(“Start at the Root Node?”)]
        public bool StartAtTopLevel
        {
            get
            {
                return _StartAtTopLevel;
            }
            set
            {
                _StartAtTopLevel = value;
            }
        }


        [WebBrowsable(true),
        Personalizable(PersonalizationScope.Shared),
        FriendlyName(“The name of the root level site”)]
        public string StartNodeName
        {
            get
            {
                return _StartNodeName;
            }
            set
            {
                _StartNodeName = value;
            }
        }


        protected override void CreateChildControls()
        {
            this.ChromeType = PartChromeType.None;
          
            try
            {
                if (_StartAtTopLevel || _StartNodeName.Length > 0)
                {
                    PortalSiteMapDataSource siteMapDataSource = new PortalSiteMapDataSource();


                    siteMapDataSource.TrimNonCurrentTypes = Microsoft.SharePoint.Publishing.NodeTypes.Page;
                    siteMapDataSource.TrimNonCurrentTypes = Microsoft.SharePoint.Publishing.NodeTypes.List;


                    base.CreateChildControls();
                    PortalSiteMapProvider portalSiteMap = new PortalSiteMapProvider();
                    portalSiteMap.IncludePages = PortalSiteMapProvider.IncludeOption.Never;
                    portalSiteMap.IncludeHeadings = false;
                    portalSiteMap.EncodeOutput = true;


                    SiteMapNode startNode;
                    if (_StartAtTopLevel)
                    {
                        startNode = portalSiteMap.RootNode;
                    }
                    else
                    {
                        startNode = portalSiteMap.FindSiteMapNodeFromKey(_StartNodeName);
                    }
                    SiteMapNodeCollection nodes = portalSiteMap.GetChildNodes(startNode);



                    SPTreeView siteTreeView = new SPTreeView();
                    siteTreeView.ExpandDepth = 10;


                    siteTreeView.Nodes.Add(new TreeNode(startNode.Title, startNode.Url, “”, startNode.Url, “”));


                    TreeNode topNode = siteTreeView.Nodes[0];
                    ProcessWeb(topNode, nodes);


                    Controls.Add(siteTreeView);
                }
                else
                {
                    Controls.Clear();
                    Label errorMessage = new Label();
                    errorMessage.Text = “Enable the web part to start either at the root node or at a specific Url”;
                    Controls.Add(errorMessage);
                }
            }
            catch (Exception ex)
            {
                Controls.Clear();
                Label errorMessage = new Label();
                errorMessage.Text = “There was an error in the code.  Please contact your system administrator and rely the following ” +
                    “message: ” + ex.Message;
                Controls.Add(errorMessage);
            }


        }


        private void ProcessWeb(TreeNode topNode, SiteMapNodeCollection nodes)
        {
            try
            {
                foreach (SiteMapNode currentMapNode in nodes)
                {
                        TreeNode currentNode = new TreeNode(currentMapNode.Title, currentMapNode.Url, “”, currentMapNode.Url, “”);
                        if (currentMapNode.ChildNodes.Count > 0)
                        {
                            ProcessWeb(currentNode, currentMapNode.ChildNodes);
                        }
                        topNode.ChildNodes.Add(currentNode);
                }
            }
            catch (Exception e)
            {
            }


        }
    }
}

Process appears hung when deploying/retracting solutions

I have noticed from time to time that when I deploy solutions (using the Central Administrations, Operations, Solution Management) the Status field is stopped on either “Deploying” or “Retracting” for quite a long time.   While normally this is an indication of some error on one of the front-end servers (for example I have run into a memory issue quite a bit using when running 64bit) and that issue needs to be taken care of, once the issue is resolved how do you get rid of this?


If you go back to the “Operations” tab under the “Global Configuration” section is a link called “Timer job status”.  Clicking on this will bring up a new window that lists all the SharePoint jobs currently running and what server the job is running on.  Towards the bottom of the screen will be the job that concerns the deploying/retracting of the solution.   The name of the job starts with either “Windows SharePoint Services Solution Retraction for” or “Windows SharePoint Services Soltion Deployment for” followed by the name of the solution.   There will be one entry for each of the front-end servers that the solution is being deployed to or retracted from.   Usually one of the entries will say failed and the others will say succeeded so you can use this to help figure out which front-end is causing the problems.


If all the jobs have succeeded you can delete the job.  To do this go back to the “Operations” tab and click on “Timer job definitions” which is right below “Timer job status”.  Find your job (same name as before)  and click on it.  Note that there will only be one listing for the job here even though you have multiple front-ends.   Click on the “Delete” button to remove it.


If you then go back to the “Solution management” area you will notice that the solution is now set to either “Deployed” or “Retracted”.


Remember, that this is just a band-aide to get you through errors when deploying/retracting solutions.  If you need to do this then most likely there are other issues with your front-ends that you need to resolve.

Recruiters, get a clue

Update:  Had another call from a recruiter yesterday.  It was night and day difference!  He was very professional, knew what he was going to say, and even though I turned him down he asked…..let me say that again, HE ASKED….if it would be alright to contact me again in the future.   I do not think I have ever had a recruiter ask that before.  Normally they just call again in 3 months unless I tell them not to contact me again.    So I guess there are good recruiters out there as well as bad ones.  Of course he did ask the obligatory, “…if you are not interested do you know anyone who is?”.    I would really love to hear from a recruiter to see if that question ever worked. 


—————————


OK, recruiters,


 reality check.   If you are making the cold call to a person guess who is most likely going to be the first person from your company you are going to talk to?   That’s right.  YOU!  Act professionally!


I had a recruiter call me yesterday (on my work phone no less) from, shall we say, a rather large consulting organization.   Even if I was looking for another job, which I am not (if there is anyone from my current company reading this [:)].  If someone from Microsoft SharePoint development is reading this I can be reached at……  [:P] ) I would not even consider going to this company based on the recruiter alone.  This man was the most unprofessional person I have ever spoken with (and I was around during the dot-com days when I would get 10 recruiter calls a week).  Not only could he not put 2 words together without adding an “Umm” in between he seemed to actually be upset I would not consider going to his company.  When I said I was not looking for another job he actually said “Do you know who ….. is?”.   Oh wait, now I want to work for you!


Here is a wake up call for recruiters.  Not everyone wants to work for a big company.  I like the fact that I know everyone in my company….or at least I thought I did until I went to the last Holiday party! [:)]  Guess we are growing.   In any case, I know I can pick up the phone and call the president of the company if I had an issue.   Cannot do that with a lot of consulting companies I know of.  Heck, cannot do that with a lot companies period!


So to summarize:


  1. Act professionally.  If you need to, reherse what you are going to say.  Believe it or not a person’s view of your company may very well be swayed by you.
  2. If the person is not interested do not take it as a personal insult.  As I said, some people just do not want to work for large companies.
  3. Above all, stop calling my work number!  You have no idea where I am or what I can say.
  4. Oh yeah, if you want the person to call you back, leave a phone number.   My work phone gets forwarded so I have no idea what number you are calling me from.

Time to go 64bit

As a follow-up to yesterday’s post let me restate that the next version of SharePoint is set to be 64bit only.   This means that if you have the option any new SharePoint 2007 install should be done using the 64bit version otherwise you will not have an easy upgrade path (not saying that upgrading from 2003 to 2007 is easy but hopefully from 2007 to the next version will be).   If you do not run 64bit Windows you would basically have to wipe your system completely and redo the installation.


As there are no guarantees as to what Microsoft will be doing in the future in regards to the upgrades I strongly suggest that any new installations be done using the 64bit versions of the OS and SharePoint now. 

Capacity planning beta and hardware recommendations

The SharePoint team blog has posted a great entry about the beta of the SharePoint capacity planning program as well as information about hardware recommendations.   Basically you will need 64bit machines for the future versions of SharePoint.  Not really a big surprise seeing how most of the other server software world is heading to 64bit.   A few other tidbits there as well.   Worth your time to check it out.


I have been using the capacity planning program for a while and I am quite impressed with it.  Provides verification of hardware requirements that you present to customers.


http://blogs.msdn.com/sharepoint/archive/2007/12/17/hardware-recommendations-and-sccp-sharepoint-capacity-planning-tool-beta-models.aspx

MOSS SP1 now available

This update applies to the following programs:

  • Microsoft® Office SharePoint® Server 2007
  • Microsoft® Office Project Server 2007
  • Microsoft® Office Forms Server 2007
  • Microsoft® Office Groove® Server 2007, 64-Bit Edition


 

WSS 3.0 (required before you install MOSS SP1) can be found here: