in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

SPSherm.MyBlog

Sharing points about SharePoint...

August 2007 - Posts

  • My First Computer

    Came across this while cruising around:

    http://content.techrepublic.com.com/2346-10877_11-895-9.html
    http://www.oldcomputers.net/vic20.html

    5K (3.5K usable)… wow. We also had the tape drive. Wicked. Ask me how we searched for programs on a tape... Smile

    And for the record, our *second* computer was an (original, not a clone) Apple IIe with dual disk(ette) drives. My buddy had an Apple IIc, and my future neighbour had an Apple Lisa.

    (Ironic how I am posting about one of my old computers, the Apple IIe, which was codenamed "Diana", on this, the 10th year of Diana's death.)

  • SPFormContext

    Argh, Sezai beat me to this post about SPFormContext and SPControlMode by a few hours! I have to admit my sentiment is the same as his - I'm super stoked to have found this class.

    Oftentimes, we need some code to execute, but only in the "published" state (old MCMS terminology). We might want a component to run certain logic, but it's really only relevant if the page is in a live/published state. In other words, the logic does not matter when we are viewing the page as authors, editors, or administrators - we either don't care, or we just don't want the logic to execute. (Could be vice-versa; execute some code only if we're NOT in published state.)

    For example, my UE developer asked me to hide all mark-up surrounding a publishing site field. After all, if there isn't any content to display, then why bother rendering the DIV tags, or possibly some heading (H) tags? By performing a check for content, we can avoid a situation where a "News" header appears, but there's nothing it. So, I created a control that wraps around all the mark-up that comprises a UI element/section. If there is no content, the control, and its children, will not render. However, we always want it to render in editing mode; otherwise, we can't add content back in!

    This scenario was fairly simple to solve: write a control that inherits from Microsoft.SharePoint.WebControls.BaseFieldControl, and only run the code to check for content if we are in published mode:

    if (this.ControlMode == SPControlMode.Display)
    {
        // do something.
    }

    This is all fine and well, since BaseFieldControl can be traced back to Microsoft.SharePoint.WebControls.FormComponent, which is the last point in the hierarchy that has the ControlMode property. If you go further up the tree, Microsoft.SharePoint.WebControls.SPControl does not have the ControlMode property... I have no idea why not.

    Why is this a problem? Well, my UE developer wanted to check multiple fields. I could not inherit from BaseFieldControl any longer, since it is meant to represent a single field, not multiple fields. So I decided to inherit from SPControl instead. (In the end, I probably could have inherited from System.Web.UI.WebControls.WebControl, but it seemed to make sense to stick within the SharePoint namespace.)

    After much searching, including spending a lot of time in Reflector, specifically searching for Microsoft.SharePoint.Publishing.WebControls.PageDisplayMode and Microsoft.SharePoint.Publishing.WebControls.SPControlMode (both enums), I finally came across this *internal* and *sealed* class in the Microsoft.Office.Server.Utilities namespace: PageUtility. But we can't use it! However, inside PageUtility is a method called IsPageCurrentlyInSomeEditMode() (nice, huh?) and more importantly, a property called FormContextMode, which returns an SPControlMode object... interesting.

    Looking closer, I saw a line (similar to) SPContext.Current.FormContext.FormMode (!!). As Sezai pointed out, FormContext is an SPFormContext object, which contains two (potentially) very useful properties: FormMode and FieldControlCollection:

    • FormMode gives us a way to check against the enum SPControlMode to determine what "state" we're in.
    • FieldControlCollection returns an ArrayList of field controls (skipping all the other server controls on the page).

    Now, I can do a check like this:

    if (SPContext.Current.FormContext.FormMode == SPControlMode.Display)
    {
        // do something.
    }

    Also, with FieldControlCollection, I can iterate over the list of defined fields for the current page, looking for some specified fields. Nice!

    SPFormContext is definitely useful, and I'm surprised there hasn't been any postings about it until Sezai came along Wink (try searching for SPFormContext...).

  • Improving Performance: BlobCache

    When a SharePoint is application is created, a web.config file is created in the application folder you specified. One of the entries inside the SharePoint element is BlobCache. By default, it looks like this:

    <BlobCache location="C:\blobCache" path="\.(gif|jpg|png|css|js)$" maxSize="10" enabled="false" />

    In order to improve the performance of your site, the BlobCache should be enabled.

    <BlobCache location="C:\blobCache" path="\.(gif|jpg|png|css|js)$" maxSize="10" enabled="true" />

    The maxSize attribute is in GigaBytes, so make sure you have enough room at the location.

    Pop quiz: why is it off by default?!

    See this article for more information about other caching techniques: http://blogs.msdn.com/ecm/archive/2006/11/08/how-to-make-your-moss-2007-web-site-faster-with-caching.aspx

  • Planning for Performance

    This isn't in my area of expertise, but a co-worker of mine (thanks Carmen!) alerted me to this, so I figured I should put it here for safe keeping. It's an article that describes the capacity limits for MOSS 2007.

    Plan for software boundaries (Office SharePoint Server)

  • SPSite vs. SPWeb

    We had a discussion amongst the developers in our group recently: what is an SPSite, what is an SPWeb, and what is the difference? Which once should I work with in my code? Looking at MSDN for the SPSite class, we see this description:

    [SPSite] Represents a collection of sites on a virtual server, including a top-level site and all its subsites. Each SPSite object, or site collection, is represented within an SPSiteCollection object that consists of the collection of all site collections on the virtual server.

    Mmmmm... ooo-kay... what does that mean?

    The SPWeb class simply says:

    Represents a SharePoint Web site.

    Wow. Enlightening. Looking back to my first experiences working with the SharePoint object model in WSS2/SPS2003, I must say this was one of the more confusing points for me. And it's easy to see why it can be such a confusing/frustrating experience for developers working with the API for the first time. Now that I've worked with WSS3/MOSS code more closely, specifically with Publishing Sites where there are many child "sites", I've come to understand the world of SPSite and SPWeb objects.

    The problem lies with the difference in terms used between the SharePoint user-interface and the object model. When we are speaking to end-users, they are familiar with the term "creating SharePoint team sites". However, everytime you create a "site" from the UI, an SPWeb object was created.

    It doesn't help that the MSDN documentation uses the following type of naming conventions in their code samples:

    SPSite mySiteCollection = new SPSite("http://servername/");
    SPWeb mySite = mySiteCollection.AllWebs["Site_Name"];
    SPWeb myRootSite = mySiteCollection.RootWeb;

    For me, it would have been much clearer if they wrote something like this instead:

    SPSite mySite = new SPSite("http://servername/");
    SPWeb myWeb = mySite.AllWebs["Site_Name"];
    SPWeb myRootWeb = mySite.RootWeb;

    While the description for SPSite may be valid, a typical SharePoint application web site only has one top-level site collection. Therefore, in this url http://servername/site1/site1a/, there are actually three SPWeb objects, and only one SPSite object.

    SPSite site1 = new SPSite("http://servername/site1/"); 
    SPSite site1a = new SPSite("http://servername/site1/site1a/");
    bool sitesAreEqual = site1.Equals(site1a);  // sitesAreEqual should evaluate to true.

    SPWeb web1 = site1.OpenWeb();
    SPWeb web1a = site1a.OpenWeb();
    SPWeb rootWeb = site1.RootWeb; // or site1a.RootWeb; would return same instance.

    See the SPSite.OpenWeb() method for more examples: http://msdn2.microsoft.com/en-us/library/ms474633.aspx.

    SPSite itself is not a "collection" in the sense that comes from CollectionBase, for example. In fact, both SPSite and SPWeb inherit directly from System.Object. Therefore, to use a name such as mySiteCollection is confusing/misleading.

    The key thing to keep in mind is that as developers, we need to use the technically accurate terms when speaking with each other (even if MSDN doesn't), and reserve the marketing/UI terms when speaking with people who would never see the object model. (Note: there are examples of these kinds of terminology differences all over the place in SharePoint 2007.)

    I hope this clears things up a bit...if you find something that is not correct/accurate, please let me know!

  • MSDN Link: SharePoint Best Practices - Disposing WSS Objects

    Might as well dive right in and make the inaugural posting useful... 

    Anyone who's done some development work with SharePoint probably already knows about this article, but I wanted to place it here for reference:

    Best Practices: Using Disposable Windows SharePoint Services Objects

    Review the article very carefully... there are things we do often such as getting to an SPSite's RootWeb, like this:

    SPSite site = SPControl.GetContextSite(HttpContext.Current);
    SPWeb rootWeb = site.RootWeb;

    In this case, it's pretty obvious (based on the article) that we need to call rootWeb.Dispose();.

    However, if you were to access a property like this:

    string rootWebTitle = site.RootWeb.Title;

    the article states that you should call site.RootWeb.Dispose(), something that is not obvious, in my opinion. So to keep/ensure your SharePoint site/application runs as smoothly as possible, clean up after yourself! 


Need SharePoint Training? Attend a SharePoint Bootcamp!

Posts (c) their respective authors. Everything else (c) 2007 SharePoint Experts