Friday, July 2, 2010

Displaying Flash Content in SPGridView

Hi all, while playing around with SPGridView, the power creating a new class by inheriting the SPBoundField to render any Html element gave me the thought of displaying Adobe flash content on Sharepoint SPGridView. The .swf files are stored in an Sharepoint document library, the SPGridView added to an webpart or a custom aspx renders the information from that document library. The document library is used as the flash content store. Even though I am not that familiar with Flash rendering and tags, I managed to get that the <object> tag is the used to show flash content. The object tag has some specified properties and parameters which in turn renders the flash object in the browser. Basically the SPBoundField can be inherited and by overriding ChildControlDataBinding and the custom html element can be rendered. One of the parameters of ChildControlDataBinding provides the dataItem which has the current SPListItem of the row. So the SPListItem properties can be accessed and from that the swf file’s serverRelativeUrl is fetched.

The SPFlashField class is given below,

public class SPFlashField : SPBoundField
{
    protected override void ChildControlDataBinding(System.Web.UI.Control childControl, object dataItem, System.ComponentModel.MemberDescriptor dataFieldPropertyDescriptor)
    {
        PlaceHolder placeHolder = (PlaceHolder)childControl;
        SPDataSourceViewResultItem spDataSourceViewResultItem = dataItem as SPDataSourceViewResultItem;
        Microsoft.SharePoint.SPListItem spListItem = spDataSourceViewResultItem.ResultItem as Microsoft.SharePoint.SPListItem;
        string fileUrl = spListItem.File.ServerRelativeUrl;
        LiteralControl literalControl = new LiteralControl();
        literalControl.Text = "&nbsp;";
        //Only if the file is a flash file
        if (fileUrl.ToLower().Contains(".swf"))
        {
            literalControl.Text = this.GetFlashObjectHtml(fileUrl, spListItem.Name, "250", "538");
        }
        placeHolder.Controls.Add(literalControl);    
    }

    protected override System.Web.UI.Control GetChildControlInstance()
    {
       return new PlaceHolder();
    }

    private string GetFlashObjectHtml(string swfFileUrl, string swfName, string height, string width)
    {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.Append("&lt;object height='" + height + "' width='" + width + "' name='" + swfName + "' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0' classid='clsid:" + new Guid().ToString() + "&gt;");
        stringBuilder.Append("&lt;param value='" + swfFileUrl + "' name='movie'&gt;");
        stringBuilder.Append("&lt;param value='high' name='quality'&gt;");
        stringBuilder.Append("&lt;param value='transparent' name='wmode'&gt;");
        stringBuilder.Append("&lt;param value='always' name='allowscriptaccess'&gt;");
        stringBuilder.Append("&lt;embed height='" + height + "' width='" + width + "' allowscriptaccess='always' type='application/x-shockwave-flash' flashvars='strm=stream3' bgcolor='#ffffff' quality='high' src='" + swfFileUrl + "' name='" + swfName + "' wmode='transparent' id='" + swfName + "'&gt;");
        stringBuilder.Append("&lt;/object&gt;");
        return stringBuilder.ToString();
    }
}

Note: Replace &gt; with > and &lt; with <, my live editor didn’t allowed me to copy paste that code snippet ;-)

The final output is like shown below,

ScreenClip000001

The function GetFlashObjectHtml can be also used to render flash in a webpart, or even in a custom SPField.

Thursday, July 1, 2010

AssetUploader aspx page in SharePoint

Just wanted to share one of the usage of AssetUploader.aspx in SharePoint. The scenario is pretty simple, we have a picture library, and the list items are displayed in a SPGridView with thumbnail as one of the column.

<Columns>
    <asp:TemplateField HeaderText="Type" ItemStyle-Width="30px">
        <ItemTemplate>
            <%# Eval("ContentType").ToString() == "Folder" ? "<img src='/_layouts/images/folder.gif' alt='' />" : "<img src='/_layouts/images/" + Microsoft.SharePoint.Utilities.SPUtility.MapToIcon(Microsoft.SharePoint.SPContext.Current.Web, Eval("DocIcon").ToString(), "")+ "' alt='' />" %>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Thumbnail" ItemStyle-Width="100px">
        <ItemTemplate>
            <%# Eval("ContentType").ToString() == "Folder" ? "<span>&nbsp;</span>" : "<img src='/_layouts/AssetUploader.aspx?Size=Small&ImageUrl=" + HttpUtility.HtmlEncode(Eval("FileRef").ToString()) + "' alt='' style='cursor: pointer;'  />"%>
        </ItemTemplate>
    </asp:TemplateField>
    <sp:SPBoundField DataField="LinkFilenameNoMenu" HeaderText="Name" />
</Columns>

The above will render the grid like below,

ScreenClip000000

Here the file type image is rendered based on the Field property DocIcon and SPUtility.MapToIcon function.

The thumbnail is generated using AssetUpload.aspx

And the name column just bound to the LinkFileNameNoMenu

 

 

 

 Usage of AssetUploader.aspx in detail

This can be used anywhere with <img> tag to display thumbnail of size normal or small.

<img src=”/_layouts/AssetUploader.aspx?Size=Small&ImageUrl=/IMAGES/fileName.fileextension&Size=Small” alt=”” />

  • IMAGES –> Is the Images library name
  • fileName –> the name of the image (myPhoto in myPhoto.jpg)
  • fileextension –> the file extension of the image (jpg in myPhoto.jpg)
  • Size –> If not provided then medium size thumbnail will be generated, pass Small for smaller thumbnail.

So the effort to generate crisper and smaller thumbnail is made easier with the AssetUploader.aspx

Issue

Recently I ran across an issue in Sharepoint with AssetUploader.aspx (The page can be used to generate thumbnail images for images which are located in a Sharepoint library, the usage I have mentioned at the bottom of the post). The issue which we faced was that the AssetUploader.aspx failed to generate thumbnail when the request was secured that is when the request was made across https://. So I tried to investigate using refactoring the dll using .Net reflector, but unfortunately the code was obfuscated. But as a savior I found Mr.Bob Moore’s Blog while googling on the issue. The post is located at http://blogs.pointbridge.com/Blogs/moore_bob/Pages/Post.aspx?_ID=14 the title of post is Pain in the AssetUploader.aspx . Thanks a lot Bob :)