Ashok Raja's Blog
Dynamic data from NASA Image of the day RSS feed for Tiles View WebPart in SharePoint 2013
by Ashok Raja T 21. January 2013 07:30

This article on dynamic data feed for promoted links, retrieves the content from NASA’s Image of the Day RSS feed to display it in the Tiles View Web Part of SharePoint 2013

clip_image002

Although the main objective of the post is feeding dynamic data to Tiles View WebPart, the below mentioned key concepts are also covered in this blog post.

Some of the Key Concepts Covered

1. Passing Dynamic Data to a Tiles View Web Part instead of mapping it to a locally available promoted links library

2. On the fly Thumbnail Image creation in SharePoint

3. Extension methods to convert Image to byte array and vice-versa

4. Parsing RSS feeds with SyndicationFeed class available under System.ServiceModel.Syndication name space.

5. Creating a TilesViewWebPart in SharePoint Object Model

6. Safely referring an application page via code.

Note : If you would like to create Tiles View WebPart (Promoted Links WebPart ) without code, check out my last blog post here

Create a Project

Well, lets start with creating a new SharePoint 2013 Empty project (Farm Solution) in Visual Studio 2012 and add a Web Part to it. I have named it as “NasaPictureOfTheDay”.

NASA Image of the Day RSS Feed

Then add a new class to the project and name it as “ImageOfTheDay” and add the below available code to the class. This piece of code uses SyndicationFeed class to read RSS feed. This class is a part of System.ServiceModel.Syndication namespace which requires reference to the assembly System.ServiceModel.dll located at C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\

 public class ImageOfTheDay
 {
     /// <summary>
     /// NASA Image of the Day RSS Feed URL
     /// </summary>
     private const string RssUrl = "http://www.nasa.gov/rss/lg_image_of_the_day.rss";
 
     //private const string RssUrl = "http://www.nasa.gov/rss/image_of_the_day.rss";
 
     /// <summary>
     /// Retrive RSS from NASA's Image of the Day RSS Feed
     /// </summary>
     /// <returns></returns>
     public ImageInfo GetImageInfo()
     {
         Uri feedUri = new Uri(RssUrl);
         XmlReader reader = XmlReader.Create(feedUri.AbsoluteUri);
         SyndicationFeed feed = SyndicationFeed.Load(reader);
         SyndicationItem Item = feed.Items.First();
         ImageInfo Info = new ImageInfo();
         Info.Title = Item.Title.Text;
         Info.Description = Item.Summary.Text.Substring(0, Math.Min(200, Item.Summary.Text.Length));
         Info.ImageUrl = Item.Links.SingleOrDefault(h => h.RelationshipType.ToLower() == "enclosure").Uri.ToString();
         Info.Link = Item.Id;
         return Info;
     }
 }

The WebPart

Now open the WebPart that has been added to the project and change the class to inherit from TilesViewWebPart. Override the GetTiles method and call the RSS feed and convert it into TileData and return it as an Array. The below is the source code for WebPart

 [ToolboxItemAttribute(false)]
 public class NasaPictureOfTheDay : TilesViewWebPart
 {
     protected override TileData[] GetTiles()
     {
         ImageOfTheDay ImgOfDay = new ImageOfTheDay();
         ImageInfo Imginfo = ImgOfDay.GetImageInfo();
         TileData[] FeedItem = new TileData[1];
 
         FeedItem[0] = new TileData
         {
             ID = 1,
             Title = Imginfo.Title,
             Description = Imginfo.Description,
             BackgroundImageLocation = SPUrlUtility.CombineUrl(SPUrlUtility.CombineUrl(SPContext.Current.Web.ServerRelativeUrl, SPUtility.GetLayoutsFolder(SPContext.Current.Web)), "/SFS.Intranet.TileDataFeed/ThumpImage.aspx?Img=" + Imginfo.ImageUrl),
             LinkLocation = Imginfo.Link,
             LaunchBehavior = TileLaunchBehavior.NewTab,
             TileOrder = 1
 
         };
         return FeedItem;
     }
 
     protected override string ViewTitle
     {
         get { return "NASA Picture Of The Day"; }
     }
 }

Note : If you override the OnLoad Event, then BaseViewId has to be set, otherwise the Tiles won't be rendered in the WebPart

Thumbnail creation in SharePoint

For the BackgroundImagelocation property in FeedItem , I am calling the ThumpImage.aspx page to re-size the Image as thumbnail . Initially I directly passed the Image Url directly, but it displayed only the left corner of the original image with size 150x150 pixel . So I created an Application page to re-size the Image. This Application page accepts the Image URL as query string and it retrieve the image as bytes and converts it to a thumbnail. The below is the code snippet which converts the original Image to Thumbnail

 public partial class ThumpImage : LayoutsPageBase
 {
     protected void Page_Load(object sender, EventArgs e)
     {
         RenderImage(Request.QueryString["Img"]);
     }
 
     private void RenderImage(string ImgUrl)
     {
         WebClient wClient = new WebClient();
         byte[] ImgContent = wClient.DownloadData(ImgUrl);
         System.Drawing.Image thumbImg = ImgContent.ToImage().GetThumbnailImage(150, 150, () => false, IntPtr.Zero);
         Response.Clear();
         Response.ContentType = "image/png";
         Response.BinaryWrite(thumbImg.ToByteArray());
         Response.End();
     }
 }

Image < = > Array Conversion

The above code for creation of thumbnail in SharePoint 2013 via an Application Page loads the Image as byte array from the original image location (URL) . Then it converts the byte array to image and creates the thumbnail and then it converts back the thumbnail to byte array to write it to the response stream. The below are the two extension methods which performs this conversion.

 
 public static class ImageEx
 {
     public static System.Drawing.Image ToImage(this byte[] ary)
     {
         MemoryStream memStream = new MemoryStream(ary);
         System.Drawing.Image tempImage = System.Drawing.Image.FromStream(memStream);
         return tempImage;
     }
 
     public static byte[] ToByteArray(this System.Drawing.Image img)
     {
         MemoryStream memStream = new MemoryStream();
         img.Save(memStream, System.Drawing.Imaging.ImageFormat.Png);
         return memStream.ToArray();
     }
 }

 Deployment

Build and deploy the project . Create a new Page or edit an existing page and add this web part to that page. If are trying with the downloaded source code available for this blog post, search for this Web Part under the category “SFS” with the name “NASA Picture Of The Day”

The below is the final out put (I have shown both default view and view on Mouse Over in a single Image )

clip_image004

blog comments powered by Disqus