in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

Sharepoint Space

It is all about Sharepoint

October 2007 - Posts

  • Lesson learned when create list instance in Sharepoint solution

    It took me plenty of time to figure out how to create a sharepoint list/document library instance and delpoy to the Sharepoint in a solution. I experienced some weird error message and it is really frustrating untill everything works at the last!

    1. Project structure and features
    Make sure completely understand how feature and solution works in Sharepoint. Understand how to create feature head file and feature detail file. Not necessary to memorize all the element but you must know where and how to find it at msdn. It is also very important to build your file structure properly first, otherwise it will easy comfuse youself later when the project grows. A good practice is create a Sharepoint list using VseWSS and study the structure. Key files to study are: Manifest.xml, setup.bat, feature.xml, instance.xml. You need also has the knowledge to create ddf file for your own projects. You could also implement MSBuild for your project in the future...

    2. Make sure follow the rules
    Exception from HRESULT: 0x81070201
    I got this error message once and really took me long time to fix the problem. Finally, I found the folder name has to be exactly the same you defined in your element.xml. Sounds weird? Ask MS but to make it work, you have to rename the folder name and your ddf file as well.

    3. Only Content controls are allowed directly in a content page that contains Content controls.
    This error message is also misleading. If you got this message, simply remove the commented line in the AllItems.aspx and the rest .aspx pages. (Who says the commented line does not impact your project??? )

    4. Two features for 1 list
    When create list or document library, Sharepoint actually wants you to create 2 features for it.
    First one is just instance of the list or document library. You might need:
    feature.xml and instance.xml
    the second actually is the schema and default aspx pages.
    For list, this feature by default should contain: AllItems.aspx, DispForm.aspx, EditForm.aspx, NewForm.asxp, schema.xml, elementManifest.xml
    For docLib, this feature by default should contains: AllItems.aspx, combine.aspx, dispform.aspx, editdlg.htm, editform.aspx, filedlg.htm, repair.aspx, schema.xml, upload.aspx, webfldr.aspx
    The second feature acutally defines the default behavior of the list or docLib.

    5. Event receiver
    Event receiver defines the event and action during or after certain activity. For example, after the feature activated or after the item added. It is quite useful when you build your installation package and control your list/docLib. This can be defined in your feature.xml. For example:
     <Feature
    Title
    ="XXXYYYZZZ"
    Id="282A5A9B-465F-4b4d-BB79-B5F6DD2B5A40"
    Description
    ="Your description"
    Version
    ="1.0.0.0"
    Scope
    ="Web"
    Hidden="FALSE"
    DefaultResourceFile
    ="core"
    ReceiverAssembly
    ="MyTest.Sharepoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f1cf6b1266b9b906" ReceiverClass="MyTest.Sharepoint.MyTestFeatureEventReceiver"
    xmlns
    ="http://schemas.microsoft.com/sharepoint/">

    -   <ElementManifests>
           <ElementManifest Location="instance.xml" />
     </ElementManifests>
    </Feature>
     
  • SPSite, SPWeb and SPWebCollection

    Sharepoint come with many class. Some class name is confusing.

    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.
    Note: SPSite is NOT a Collection, in another words, you can not use foreach to loop SPSite. To do this, you have to use SPWebCollection.

    SPWebCollection:
    Represents a collection of SPWeb objects.

    SPWeb:
    Represents a SharePoint Web site.

    SPFolder:
    Represents a folder on a SharePoint Web site. 

    The following snipet is copy from a class:

            #region properties
            /// <summary>
            /// site collection url address
            /// </summary>
            public string _RootSiteUrl
            {
                get { return RootSiteUrl; }
                set { RootSiteUrl = value; }
            }
            /// <summary>
            /// Site collection, get SPSite object repsent a "collection"
            /// </summary>
            public SPSite _Sites
            {
                get { return new SPSite(this._RootSiteUrl); }
                set { Sites = value; }
            }
            /// <summary>
            /// Web collection, SPWebCollection, this is the real Collection
            /// </summary>
            public SPWebCollection _Webs
            {
                get { return this._Sites.AllWebs; }
            }

            public string _PPMAspxPageSiteUrl
            {
                get { return this.PPMTargetSiteUrl; }
                set { PPMTargetSiteUrl = value; }
            }

            public SPWeb this[string SiteName] // indexer, represent a SPWeb
            {
                get
                {
                    int i = 0;
                    foreach (SPWeb web in this._Webs)
                    {
                        if (web.Url == SiteName)
                            return this._Webs[ i ];
                        i++;
                    }
                    return null;
                }
            }

            #endregion

    The indexer is quite useful, to get a SPWeb object, simply use mySharePointClass["your site or subsite url"] to access!

  • Convert html to Sharepoint aspx page

    In my previous post http://www.sharepointblogs.com/mingssn/archive/2007/10/06/word-documents-to-sharepoint.aspx explained the idea of edit Sharepoint aspx content directly instead of using the out of box converter. This is the complete class to import word html into Sharepoint. Somehow, SPWeb, SPSite, SPWebcollection, SPSiteCollection is kind of confusing. Make sure read document from MSDN

    Also, this class removed the <style>  section from the html file...

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Publishing;

    namespace PPM
    {
        class PPMWeb
        {
            private string RootSiteUrl;
            private string PPMTargetSiteUrl;
            private SPSite Sites;

            #region properties
            public string _RootSiteUrl
            {
                get { return RootSiteUrl; }
                set { RootSiteUrl = value; }
            }
            public SPSite _Sites
            {
                get { return new SPSite(this._RootSiteUrl); }
                set { Sites = value; }
            }
            public SPWebCollection _Webs
            {
                get { return this._Sites.AllWebs; }
            }

            public string _PPMAspxPageSiteUrl
            {
                get { return this.PPMTargetSiteUrl; }
                set { PPMTargetSiteUrl = value; }
            }

            public SPWeb this[string SiteName]
            {
                get
                {
                    int i = 0;
                    foreach (SPWeb web in this._Webs)
                    {
                        if (web.Url == SiteName)
                            return this._Webs[ i ] ;
                        i++;
                    }
                    return null;
                }
            }

            #endregion

            public PPMWeb(string RootSiteUrl, string PPMAspxSiteUrl)
            {
                this._RootSiteUrl = RootSiteUrl;
                this._PPMAspxPageSiteUrl = PPMAspxSiteUrl;
            }

            public void ConvertHtmlToAspx(string HtmlFileFolder, string HtmlFileName, string TargetWeb, PageLayout PPMPageLayout, string PPMContentField)
            {
                foreach (SPWeb web in this._Webs)
                {
                    if (web.Url == TargetWeb )
                    {
                        PublishingPage AspxPage = GetPublishingPagebyName(HtmlFileName.Replace(".htm", ".aspx"), web);
                        if (AspxPage != null) //if page exists, update content field
                        {
                            UpdateAspxPageContent(web, HtmlFileFolder, HtmlFileName, PPMContentField, false);
                        }
                        else //if page not exists, create page first
                        {
                            PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
                            // Create the new page in the PublishingWeb.
                            PublishingPageCollection pages = publishingWeb.GetPublishingPages();
                            pages.Add(HtmlFileName.Replace(".htm", ".aspx"), PPMPageLayout);
                            // Update content
                            UpdateAspxPageContent(web, HtmlFileFolder, HtmlFileName, PPMContentField, true);
                        }
                    }
                }
            }

            public void UpdateAspxPageContent(SPWeb Web, string HtmlFileFolder, string HtmlFileName, string PPMContentField, bool AlreadyCheckedOut)
            {
                PublishingPage AspxPage = GetPublishingPagebyName(HtmlFileName.Replace(".htm", ".aspx"), Web);
                if (AspxPage != null) //if page exists, update content field
                {
                    try
                    {
                        if (!AlreadyCheckedOut)
                            AspxPage.CheckOut();
                        AspxPage.ListItem[PPMContentField] = GetHtmlContentWithouStyle(HtmlFileFolder, HtmlFileName);
                        AspxPage.Update();
                    }
                    catch { }
                    finally
                    {
                        AspxPage.CheckIn("Your comment here...");
                    }
                }
            }

            public PublishingPage GetPublishingPagebyName(string AspxFileName, SPWeb TargetWeb)
            {
                PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(TargetWeb);
                PublishingPageCollection pages = publishingWeb.GetPublishingPages();
                foreach (PublishingPage page in pages)
                {
                    if (page.Name == AspxFileName)
                    {
                        return page;
                    }
                }
                return null;
            }

            public string GetHtmlContentWithouStyle(string HtmlFileFolder, string HtmlFileName)
            {
                StreamReader rdr = new StreamReader(HtmlFileFolder + HtmlFileName, System.Text.Encoding.Default);
                // Search through the stream until we reach the end
                bool StyleHeadFound = false;
                bool StyleEndFound = false;
                StringBuilder HtmlContent = new StringBuilder();
                while (!rdr.EndOfStream)
                {
                    string line = rdr.ReadLine();
                    if (StyleHeadFound && StyleEndFound)
                        HtmlContent.Append(line);
                    else
                    {

                        if (!StyleHeadFound)
                        {
                            if (line == "<style>")
                            {
                                StyleHeadFound = true;
                                continue;
                            }
                            HtmlContent.Append(line);
                        }
                        else
                        {
                            if (!StyleEndFound)
                            {
                                if (line == "</style>")
                                {
                                    StyleEndFound = true;
                                    continue;
                                }
                            }
                        }
                    }
                }
                return HtmlContent.ToString();
            }

            public PageLayout GetPPMPageLayout(string PPMPageLayoutTitle)
            {
                PublishingSite publishingSite = new PublishingSite(this._Sites);
                foreach (PageLayout pageLayout in publishingSite.PageLayouts)
                    if (pageLayout.Title == PPMPageLayoutTitle)
                        return pageLayout;
                return null;
            }

        }
    }

  • Word documents to Sharepoint

    We currently have a challenge of converting over thousand Word 2003 document into Sharepoint publishing page. Here is our approach:
    Step 1: Run Microsoft document convert tool to convert word document into docx
    You can download it free from Microsoft at: http://www.microsoft.com/downloads/details.aspx?familyid=13580cd7-a8bc-40ef-8281-dd2c325a5a81&displaylang=en
    Step 2: Call out of box document convert to convert docx into aspx
    With thousands of files to convert, we have to write a code to do the job. Use Microsoft.Sharepoint.Publishing.PublishingPageCollection class to add new publishing page.

    public PublishingPage Add (
    string newPageName,
    SPFile fileToConvert,
    Guid transformerId,
    PageConversionPriority priority )

    This approach works however we now have 2 issues
    1. About 10% of the documents does not convert. The error message shows internal error which does not help us identify the problem. After spending lots of time on the word document, we think this error is relate to the word document format. Such as bullet, section break...at this time, we can not certain exactly the problem
    2. Some of the Word format lost or style has been changed after convert.

    To work this around, I have another idea to bypass the converter. For example, to convert 100.doc to 100.aspx we follow the steps:
    1. create an empty 100.aspx publishing page first. Of course, we know the content type and the field where to save the html content.
    2. convert 100.doc to 100.htm using the default office behavior. You could do this by writing a piece of code or just open the 100.doc and save as a html file.
    3. programtically paste html text into the 100.aspx publishing page content field.
    Note: the html saved by Word will have a style css within the html page. Some class might have a conflict with you Sharepoint master page. Make sure delete those class. However, keep css style in the html and paste into the content field is not the best practice. I'd rather save those style into the css file which the master page is using. If you do this, when paste html text to the content field, make sure delete all style section from the html content.

    It is faster and all the word format will be kept even the bullet and lines in the word document. However, I really not sure if this is a good idea or not but at least it gives you an alternative way of converting word document into Sharepoint.

    I will post entire solution when the code is complete.

  • How to apply css style sheet in Sharepoint

    Apply css style sheet to Sharepoint master page has 2 ways:
    1. In the header section, you can add any custom cascading styles sheets by using a simple link tag.
    2. Use <SharePoint:CssRegistration> tag. This approach offers a few advantages because you have an option to use SPUrl, which returns the URL of the current site. css style sheet of this approach is stored in the Sharepoint content database instead of file system.

    Example:
    <head runat="server">
    <asp:ContentPlaceHolder runat="server" id="head">
    <title>
    <asp:ContentPlaceHolder id="PlaceHolderPageTitle" runat="server" />
    </title>
    </asp:ContentPlaceHolder>
    <Sharepoint:CssLink runat="server"/>
    <!-- Product Group Custom Styles -->
    <%--SharePoint:CssRegistration name="<% $SPUrl:~SiteCollection/Style Library/PG/PG.css%>" runat="server"/--%>
    <link type="text/css" rel="stylesheet" href="/_layouts/1033/styles/PG/PG.css" />
    <!-- End Product Group Custom Styles -->
    <asp:ContentPlaceHolder id="PlaceHolderAdditionalPageHead" runat="server" />
    </head>


    http://msdn2.microsoft.com/en-us/library/bb727372.aspx


Need SharePoint Training? Attend a SharePoint Bootcamp!

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