Visual WebParts are great because they give
you a visual editing experience during development time. Their biggest
disadvantage, however, is that they need to make changes to the file
system and thus have to be deployed as a farm solution.
You should prefer to deliver your functionality as much as possible
using sandbox solutions instead. Therefore, I suspect that you would be
writing more and more normal WebParts rather than Visual WebParts.
A normal WebPart is a server control, whereas a Visual WebPart is based on a UserControl.
As mentioned earlier, WebParts are widgets that you
can drop on a page, and they present a unique functionality to the end
user. Sometimes these WebParts are also editable. The administrator can
customize them for everyone or an individual user can personalize them
for their own needs. Also, sometimes, these WebParts can talk to each
other.
I'm going to build a crawl, walk, run approach example for you.
You
will begin by writing a WebPart that renders an RSS feed for you. You
will also deploy this WebPart using a site page that has WebPartZones.
(I will also demonstrate an easy way to get a runtime configuration
experience by allowing the end user to specify the RSS feed URL.) Let's
call this the RSSFeed WebPart.
Next,
you will write a second WebPart, which will allow you to host a number
of RSS URLs. (In order to host a number of RSS URLs, I will demonstrate
writing a custom editor for this WebPart. Let's call this the OPML
WebPart.)
Finally,
you will connect the OPML WebPart with the RSSFeed WebPart. This will
allow the OPML WebPart to communicate the RSS URL of the selected RSS
Feed, so it can be rendered in the RSSFeed WebPart.
1. Writing the RSSFeed WebPart
Start by creating a new empty SharePoint project in
Visual Studio 2010 called "FeedReader". I intend to put the RSS WebPart
and the OPML WebPart in this project. Specifically, the RSS WebPart is
going to make a call to an external web service. While I could (and
probably should) have written a full trust proxy, to keep things to the
point, I will simply write this as a farm solution instead.
Next, right-click the features node and choose add
feature, then go ahead and rename the added Feature1 to something more
meaningful such as RSSWebParts. While you're at it, also give the
feature a decent title, description, and ImageURL. Finally, in the
feature properties, make sure that the feature is scoped to Site
Collection. You can access the feature properties by double-clicking the
feature itself and changing the scope, as shown in Figure 1.
Next, right-click the project and add the new SharePoint item, then choose to add a new WebPart called RSS WebPart, as shown in Figure 2.
Adding the RSSWebPart will also add the associated
Feature1 feature for you in the solution. Since you intend to package
the RSSWebPart you just added in the RSSWebParts feature you just
created a moment ago, delete the Feature1 feature. You can do so by
right-clicking the Feature1 node and then choosing delete.
Next, you need to package the RSSWebPart WebPart in
the RSSWebParts feature. To do this, double-click the RSSWebParts
feature to open the feature designer. You should see the RSSWebPart
WebPart in the items in the solution pane on the left side. Select it
and move it to the items in the feature pane using the buttons provided.
This can be seen in Figure 3.
Next, you need to add some logic to the RSSWebPart WebPart. Edit the RSSWebPart.cs class to include the code, as shown in Listing 1.
Example 1. Code for RSSWebPart.cs
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using FeedReader.BO;
namespace FeedReader.RSSWebPart
{
[ToolboxItemAttribute(false)]
public class RSSWebPart : WebPart
{
[WebBrowsable(true)]
[Personalizable(PersonalizationScope.Shared)]
public string RSSUrl { get; set; }
protected override void RenderContents(HtmlTextWriter writer)
{
RSSFeed feed = new RSSFeed(RSSUrl);
HyperLink newLink = new HyperLink();
foreach (RSSItem singleRssItem in feed)
{
newLink.Text = singleRssItem.Title;
newLink.NavigateUrl = singleRssItem.Href;
newLink.Target = "rssSite";
newLink.RenderControl(writer);
writer.WriteBreak();
}
base.RenderContents(writer);
}
}
}
|
As you can see in Listing 1,
I'm using custom business objects called RSSFeed and are RSSItem. The
code for RSSFeed and RSSItem are shown in Listings 2 and 3.
Example 2. Code for RSSFeed
internal class RSSFeed : List<RSSItem>
{
internal RSSFeed(string RssURL)
{
try
{
XmlDocument rssDoc = new XmlDocument();
XmlTextReader xRead = new XmlTextReader(RssURL);
rssDoc.Load(xRead);
XmlNodeList xNodes = rssDoc.SelectNodes("./rss/channel/item");
foreach (XmlNode xNode in xNodes)
{
this.Add(new RSSItem(xNode)) ;
}
}
catch (Exception)
{
this.Add(new RSSItem());
}
}
}
|
Example 3. Code for RSSItem
internal class RSSItem
{
public string Title { get; internal set; }
public string Href { get; internal set; }
internal RSSItem()
{
Title = "Feed not available at this time" ;
Href = "˜" ;
}
internal RSSItem(XmlNode xNode)
{
Title = xNode.SelectSingleNode("./title").InnerText;
Href = xNode.SelectSingleNode("./link").InnerText;
}
}
|
The list of WebParts available in a site collection
is generally controlled by the WebPart gallery. The WebPart gallery is a
document library at the top-level site in a site collection. You will
look at this document library shortly. For your WebPart to be available
in the site collection you need to deploy a file with the extension
.WebPart into the WebPart gallery. A sample RSSWebPart.WebPart file has
already been created for you in the project. Go ahead and edit the
RSSWebPart.WebPart file to look like what is shown in Listing 4.
Example 4. The RSSWebPart.WebPart File
<?xml version="1.0" encoding="utf-8"?>
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="FeedReader.RSSWebPart.RSSWebPart, $SharePoint.Project.AssemblyFullName$" />
<importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>
</metaData>
<data>
<properties>
<property name="Title" type="string">RSSWebPart</property>
<property name="Description" type="string">This WebPart displays an RSS Feed rendered in
the browser.</property>
<property name="CatalogIconImageUrl"
type="string">/_layouts/images/FeedReader/wslogo.gif</property>
<property name="TitleIconImageUrl"
type="string">/_layouts/images/FeedReader/wslogo.gif</property>
<property name="RSSUrl" type="string">http://feeds.feedburner.com/winsmarts</property>
</properties>
</data>
</webPart>
</webParts>
|
You would notice some interesting properties being
set in the RSSWebPart.WebPart file. All of these properties surface at
different places within SharePoint helping to categorize your WebPart
and also provide helpful information to the user about the usage of the
WebPart. They can also be used to preconfigure the WebPart with some
initial values as necessary. When you see this WebPart running in action
come back to Listing 4-8 and compare what you see on the screen with what you specified in the RSSWebPart.WebPart file.
Before you build and deploy this solution, let's revisit Listing 1 one more time. Specifically, observe the code shown in the following lines:
[WebBrowsable(true)]
Personalizable(PersonalizationScope.Shared)]
public string RSSUrl { get; set; }
The [WebBrowsable(true)] attribute tells ASP.NET that
this WebPart property is editable from the UI. SharePoint at runtime
will provide you with a simple text box to edit the string value. If the
property type was an enum, it would instead provide you with a
dropdown. The Personalizable attribute specifies the scope of
personalization available on the property.
However, PersonalizationScope.User means that
individual users can personalize this property to their own needs. In
other words, a change that you make using personalization is available
only to you and not to the other users on the web site. This process is
referred to as personalization of the WebPart and is generally accessed
by choosing the "personalize this page" menu item, as shown in Figure 4.
PersonalizationScope.Shared means that any changes
done to the property are shared amongst all users using the web site.
This is also referred to as customization and is generally accessed by
putting the page in edit mode using the ribbon in SharePoint. Since the
RSSUrl Property is marked as PersonalizationScope.Shared only, that
property is not available for Personalization but it is available for
customization.
Go ahead and deploy your WebPart and let's see it
working in action. This can be done by right- clicking your project and
choosing deploy. Launch your browser and visit your SharePoint site. Go
to site actions\site settings and under the site collection
administration section click site collection features. You should see
your RSSWebParts feature activated, as shown in Figure 5.
Now go back to the home page of the site collection
and put the page in edit mode. Click the left WebPartZone and choose the
insert tab from the ribbon. Click the WebPart button and under the
custom category on the left look for the RSSWebPart. This can be seen in
Figure 6.
At this time, I would like you to quickly glance over Listing 4 and compare what you see on the screen with what you specified in Listing 4. Go ahead and add the RSSWebPart to the left WebPartZone. You should see the WebPart running, as shown in Figure 7.
Again, quickly glance over Listing 4,
and you will note that by default this WebPart is pointing to the
RSSFeed of my blog. Also, as you can see, I've been blogging about
SharePoint 2010 quite a lot. Let's go ahead and repoint this WebPart to CNN.com. Choose to edit the WebPart, as shown in Figure 8.
When the editor zone pops open on the right-hand side under the miscellaneous section, point the RSSUrl property to http://rss.cnn.com/rss/cnn_topstories.rss instead. This is as shown in theFigure 9.
Next, hit OK and stop editing the page. You can stop
editing the page by clicking on the page tab in the ribbon and clicking
on the stop editing button. Your final WebPart in action can be seen in Figure 10.
Congratulations you've written and deployed the RSSWebPart successfully!