A.7. Using VSeWSS to Build Web Parts

The VSeWSS Web Part Wizard enables you to quickly create SharePoint Web Parts that can inherit from the SharePoint WebPart base class or the ASP.NET 2.0 WebPart base class. It also offers quick deployment of Web Parts using a SharePoint feature manifest built into the embedded SharePoint Solution deployment.

There are several major tasks that are automated by using the SharePoint WebPart template:

  1. Conventional reference establishment and base class inheritance.

  2. Auto-packaging Web Parts into SharePoint solution files for deployment ease (easily the most useful feature).

  3. Temporary key provisioning to sign assembly with a strong name (Temporary.snk), for Web Part deployment into the Global Assembly Cache (GAC) if Code Access Security (CAS) isn't a large concern. This key should be replaced by the enterprise key, which is password protected once the Web Part is pushed to production.

  4. A generic render method to output embedded (child) HTML using HtmlTextWriter, since it allows a granular level of the child control output.

There are very specific references established for some very concrete purposes by using the WebPart project template. The first and most obvious are the SharePoint specific references, since they are required to work with the SharePoint object model. For example, there will be references made to the Microsoft.SharePoint DLL because Web Parts may need site objects (SPSite), web objects (SPWeb), and user (SPUser) objects. Microsoft.SharePoint.Webcontrols is referenced because it is needed for assets like SPcontrol. By putting these together, you can start to build intuitive Web Parts that will interact more with SharePoint, doing something as simple as getting the context of the current web with TheCurWeb = SPControl.GetContextWeb(Context); or as complex as getting a folder by passing in an argument that will define the source URL (see Listing A-10).

Example A.10. Using SPWeb to get a folder by the source URL
public static SPFolder getFolderBySourceFileUrl(SPWeb webSite, string fileURL)
        {
            SPFolder folder = null;
            if (fileURL.Length > 0)
            {
                int urlNumeric = SPEncode.UrlEncodeAsUrl(webSite.Url).Length;
                int lengthNumeric = fileURL.Length;
                string urlString = fileURL.Substring(urlNumeric + 1, (lengthNumeric - urlNumeric) - 1);
                string[] textArray = urlString.Replace("%20", " ").Split(new char[] { "/' });
                for (int i = 0; i < (textArray.Length - 1); i++)
                {
                    if (i == 0)
                    {
                        try
                        {
                            folder = webSite.Folders[textArray[i]];
                        }
                        catch
                        {
                            return null;
                        }
                    }
                    else
                    {
                        try
                        {
                            folder = folder.SubFolders[textArray[i]];
                        }
                        catch
                        {
                            return null;
                        }
                    }
                }
            }
            return folder;
        }

using statements will also be created for System.Runtime.InteropServices so that tasks such as controlling instance fields for structs, by defining struct layouts attributes, can be implemented, as well as marshaling in unmanaged code. There will also be a using statement for System.Xml.Serialization, since your WebPart properties will generally make use of an XMLelement to specify an accessor for the SharePoint property XmlElement(ElementName="MyElementName"), but this becomes increasingly important when working with CAML (Collaboration Application Markup Language), a specialized XML language. For example, assume that it is necessary to construct a method that will allow a sort order to be added to a CAML query (see Listing A-11). This requires heavy use of the XML reference, since XmlNode and Xmlattribute have to be leveraged.

Example A.11. Adding a sort order to an existing CAML query
private static string AddSortOrderCAML(XmlDocument existingQuery, string orderColumnName, bool Ascending)
        {
            XmlNode orderNode = existingQuery.CreateElement("OrderBy");
            XmlNode refNode = existingQuery.CreateElement("FieldRef");
            XmlAttribute nameAttribute = existingQuery.CreateAttribute("Name");
            nameAttribute.Value = orderColumnName;
            refNode.Attributes.Append(attribute1);
            nameAttribute = existingQuery.CreateAttribute("Ascending");
            nameAttribute.Value = Ascending.ToString().ToUpper();
            refNode.Attributes.Append(nameAttribute);
            orderNode.AppendChild(refNode);
            return (orderNode.OuterXml + existingQuery.OuterXml);
        }

// Utilize the new option by passing in the appropriate parameters
AddSortOrderCAML(XMLdocument, webpart.SortField, webpart.SortDir == "ASC")

The SharePoint WebPart Template will take care of providing the basis for the Web Part, establishing base class inheritance and necessary reference establishment, and providing a cryptographic key pair with which to sign the compilation. Therefore, you just need to add some methods to the project template in order to do something relevant, initialize whatever properties are required in the constructor that is generated by the template, and add the final output method to the overridden RenderContents or RenderWebPart output method. As an example, many of the documents that are going to be put in the policy management site will maintain document workspaces, so it may be helpful to provide users with a Web Part that shows them all the subsites that they have access to on the front page.

The first step is to build out a method that will include the relevant site icon related to the site, using the SPWeb.WebTemplateId and SPWeb.Configuration properties with an if statement (see Listing A-12).

Example A.12. Get the icon of the site
private string GetSiteIcon(SPWeb myWeb)
        {
            if (myWeb.WebTemplateId == 2)
            {
                return "/_layouts/images/mtgicon.gif";
            }
            if (myWeb.Configuration == 2)
            {
                return "/_layouts/images/docicon.gif";
            }
            return "/_layouts/images/stsicon.gif";
        }

Second, the site title for the relevant site should be collected for the Web Part to display. This can be generated through a GetSiteTitle method, which returns a string by passing in the SPWeb object, then using the SPWeb.Title public property to return the title of the site (see Listing A-13).

Example A.13. Get the site title
private string GetSiteTitle(SPWeb myWeb)
        {
            string siteTitle = "<a href='" + SPEncode.HtmlEncode(myWeb.Url) + "" ";
            siteTitle = siteTitle + "title='" + SPEncode.HtmlEncode(myWeb.Title) + """;
            return (siteTitle + ">"+ "</a>");
        }        }

The main body of the Web Part uses the GetDesignTimeHtml() method from the IDesignTimeHtmlProvider interface in order to return the HTML that will be output (see Listing A-14). The benefits of using the GetDesignTimeHtml method are that it will also render the output correctly when the Web Part is opened in an editing interface, such as Microsoft Office SharePoint Designer, and it reduces the codebloat in the overridden RenderWebPart method, since it will just output this.GetDesignTimeHtml(). The returned sites will be collected by the SPWeb.GetSubwebsForCurrentUser method, which will get the subsites of which a user is a member.

Example A.14. GetDesignTimeHtml() method
public string GetDesignTimeHtml()
        {
            string designTime = "";

            SPWeb currentWebContext = SPControl.GetContextWeb(this.Context);
            SPWebCollection webCollectionBucket =
currentWebContext.GetSubwebsForCurrentUser();
            SPSite currentSiteWrap = currentWebContext.Site;
            foreach (SPWeb primaryWeb in webCollectionBucket)
            {
                designTime = designTime + this.GetSiteIcon(primaryWeb);
                designTime = designTime + this.GetSiteTitle(primaryWeb);
            }

            return (designTime);
        }

Now that you have built the Web Part, you can use some of the inherent features of the VSeWSS and deploy it across a SharePoint single server or SharePoint farm by packaging it within a SharePoint solution that defines a Feature for the SharePoint Web Part. Using this option is much more attractive for a server farm because, when coupled with a SharePoint timer job, the Web Part will be made available across all front-end web servers on a scheduled basis. As opposed to legacy methods of packaging our Web Part into a .cab file that contains the instructions for deployments such as Safe Control entries, resource file exposure, and sister assembly references, the solution file will take care of the deployment for you by generating the appropriate SharePoint Feature. Depending on the scope element for which the Feature is targeted (such as farm, web application, or site collection), it will alter where the Web Part is available for use through the SharePoint environment. The Feature scope can be controlled from the scope attribute in the version-incrementable Feature file.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.40.177