SharePoint Developer Support Team Blog

The Official blog of the SharePoint Developer Support Team

July, 2012

  • Code Sample: On-Demand fetching of SharePoint list items using JQuery

    This post is a contribution from Charls Tom Jacob, an engineer with the SharePoint Developer Support team.

    In this blog, I will describe how to develop a custom web part that dynamically fetches items from a SharePoint list.  By “dynamic”, I mean fetch items on-demand and display them, thereby providing a better user experience.  It uses a combination of web services, JQuery and SharePoint object model.

    For demonstration purpose, I will be using a SharePoint blog site.  Comments for a blog post is stored in a list named “Comments”; Objective is to fetch the comments on-demand (say when the user clicks on a link “view next five comments”) without reloading the entire page.

    Following are the components I have developed in order to achieve this:

    1. A Visual Web Part to display items.

    The web part contains the JQuery logic to invoke the web service to get the required items and to render them on the page.  It also provides a hyperlink to allow users to load the next set of data.  A hidden field is used to track how many items have been loaded so far.  This information is passed on to the web service to get the next set.

    2. A web service to fetch items.

    Web service reads the list items and returns them in the JSON format.  SPListItemCollectionPosition is used to fetch the required set of data on a specific request.

    Ok, now let’s see how to implement this:

    1. Create a new Visual Web Part project in Visual Studio 2010 and add the following code to VisualWebPart1UserControl.ascx file:

    <asp:HiddenField Value="1" id="pageTrack" runat="server"></asp:HiddenField>
    <ul id="resultarea"></ul>
     
    <script type="text/javascript">
     
    $(document).ready(LoadData());
     
    function LoadData() {
            GetCommentItems();
    }
     
    function GetCommentItems() {
        var pageTrack = $("input[id$='pageTrack']").val();
        $.ajax({
            url: "/_layouts/CommentFetchSvc.asmx/ReadComments",
            type: "POST",
            data: "{'pagenum':'" + pageTrack + "'}",
            contentType: 'application/json;',
            dataType: 'json',
            success: function (msg) {
                AppendItems(msg);
                var newPageTrack = $("input[id$='pageTrack']").val();
                $("input[id$='pageTrack']").val(parseInt(newPageTrack) + 1);
            },
            error: function (xhr, msg) {
                alert(msg + '\n' + xhr.responseText);
            }
        });
     
        function AppendItems(data) {
            $.each(data.d, function (i, item) {
                var title = item.Title;
                var body = item.Body;
                html = '<li><b>' + title + '</b></li>';
                html += body;
                html += '<hr/>';
                $('#resultarea').append($(html));
            });
        }
    }
    </script>
     
    <p>
        <asp:HyperLink NavigateUrl='javascript:void(0);' id="lnkMore" onClick="GetCommentItems();" runat="server">View next five comments..</asp:HyperLink>
    </p>

    2. Build and deploy the Visual Web Part project.

    3. Add a class library project named SPBlogCommandLib to the solution.  Add reference to: System.Web.dll and System.Web.Services.dll.

    4. Add a class file named CommentFetchSvc.cs and add the following code:

    public class BlogItem
    {
        public string Title { get; set; }
        public string Body { get; set; }
    }
     
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public List<BlogItem> ReadComments(string pagenum)
    {
        List<BlogItem> blogList = new List<BlogItem>();
        using (SPSite oSpSite = new SPSite("http://localhost/blogsite"))
        {
            using (SPWeb oSpWeb = oSpSite.OpenWeb())
            {
                SPList oList = oSpWeb.Lists["Comments"];
                SPQuery oQuery = new SPQuery();
                int pageNum = int.Parse(pagenum);
                
                // Number of rows to fetch
                oQuery.RowLimit = 5;
     
                // Start reading from 1
                int intIndex = 1;
                do
                {
                    SPListItemCollection collListItems = oList.GetItems(oQuery);
     
                    // Check if this are the records to be returned
                    if (intIndex == pageNum)
                    {
                        // Read items for the specific range
                        foreach (SPListItem oListItem in collListItems)
                        {
                            BlogItem item = new BlogItem();
                            item.Title = oListItem["Title"].ToString();
                            item.Body = oListItem["Body"].ToString();
                            blogList.Add(item);
                        }
                        break;
                    }
                    oQuery.ListItemCollectionPosition = collListItems.ListItemCollectionPosition;
                    intIndex++;
                }
                while (oQuery.ListItemCollectionPosition != null);
            }
        }
        return blogList;
    }

    5. Strong name the class library project and deploy it to the GAC.

    6. Create a .asmx file using Visual Studio or Notepad (I named it CommentFetchSvc.asmx) and add the following markup:

    <%@ WebService Language="C#"  Class="CommentFetchSvc, SPBlogCommentLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=064487d45c107d0a" %>

    Make sure to modify the class attribute of the ASMX with the appropriate assembly name and public key token.

    7. Enable JQuery on your site by following this blog:

    http://blogs.msdn.com/b/yojoshi/archive/2010/06/17/using-jquery-with-sharepoint-2010.aspx

    8. Place the ASMX file into your 14\TEMPLATE\LAYOUTS folder on your SharePoint server.

    9. Add the deployed web part to a page and test the functionality.

    Sample screen:

    image

     

    Here's the sample code for download: On-demand Webpart SampleCode

    Hope you find this useful! Please share your comments and feedback.

  • Building Silverlight solution with RIA service enabled fails on SharePoint 2010 SP1 Environments

    This post is a contribution from Raghavendra Nanjaiah, an engineer with the SharePoint Developer Support team.

    On a SharePoint 2010 SP1 environment when you try to build Silverlight 4 or 5 solution with the following settings:

    1. Create a new “Silverlight Application” project.
    2. Host the Silverlight application in a new web site (default selected).
    3. Silverlight version = Silverlight 4.
    4. Check ON “Enable WCF RIA Services”.
    5. Open SilverlightApplication.Web project.
    6. Right-click References and add Microsoft.SharePoint.dll.
    7. Ensure “Configuration Manager” for the solution is set to “Any CPU”.
    8. Build the entire solution.

    It fails with the following error:

    image

    For better readability here’s the complete error:

    The "CreateRiaClientFilesTask" task failed unexpectedly.
    System.Web.HttpException (0x80004005): Could not load file or assembly 'Microsoft.Sharepoint.Sandbox' or one of its dependencies. An attempt was made to load a program with an incorrect format. ---> System.Configuration.ConfigurationErrorsException: Could not load file or assembly 'Microsoft.Sharepoint.Sandbox' or one of its dependencies. An attempt was made to load a program with an incorrect format. ---> System.BadImageFormatException: Could not load file or assembly 'Microsoft.Sharepoint.Sandbox' or one of its dependencies. An attempt was made to load a program with an incorrect format.
       at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
       at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
       at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks)
       at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
       at System.Reflection.Assembly.Load(String assemblyString)
       at System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)

     

    Here’s the workaround we used to fix this issue.

    1. Copy Microsoft.SharePoint.Sandbox.dll from GAC to local drive.

    image 

    Path: “%windir%\assembly\GAC_64\Microsoft.Sharepoint.Sandbox\14.0.0.0__71e9bce111e9429c”

    2. Add reference of the copied Microsoft.SharePoint.Sandbox.dll from GAC to SilverlightApplication1.web.

    image

    3. Set “Local Copy” property of the Microsoft.SharePoint.Sandbox.dll to “false”.

    image

    4. Build the solution.

    Hope this was helpful!

  • HOW TO: Open Content Query Web Part links in a new IE window

    This post is a contribution from Charls Tom Jacob, an engineer with the SharePoint Developer Support team.

    Content Query Web Part is a nice way to query and display data from multiple lists.  By default, when you click on a link displayed in the Content Query Web Part, it opens up in the same IE browser window.  This can be annoying at times if users want to stay on the main page and view the items in a different IE browser window.

    In this post, I’ll describe how to extend the out of the box Content Query Web Part and the styles such that links open in new IE window.

    Step1: Extend out of the box XSL

    1. Download the out of the box ItemStyle.xsl from Style Library (go to Site Actions –> View all site content –> Style Library –> XSL Style Sheets).
    2. Rename the file to ItemStyleExtended.xsl.
    3. Open the file in NOTEPAD, locate the <DIV> element that acts as a container for links displayed in the web part:
    4. <div class=”link-item”>

    5. Modify the following anchor tag to open the links in a new window:
    6. <a href="{$SafeLinkUrl}" title="{@LinkToolTip}">

      As

      <a href="{$SafeLinkUrl}" title="{@LinkToolTip}" target="_blank">

    7. Comment out the XSL that performs an additional check for links to documents or other file types, as below:
    8. <!--<xsl:if test="$ItemsHaveStreams = 'True'">
             <xsl:attribute name="onclick">
                <xsl:value-of select="@OnClickForWebRendering"/>
             </xsl:attribute>
           </xsl:if>
           <xsl:if test="$ItemsHaveStreams != 'True' and @OpenInNewWindow = 'True'">
              <xsl:attribute name="onclick">
                 <xsl:value-of disable-output-escaping="yes" select="$OnClickTargetAttribute"/>
              </xsl:attribute>
           </xsl:if>-->

    9. Upload the new file to Style Library.

    Step2:  Extending the Content Query Web Part

    1. Open the Web Part page that contains the Content Query Web Part.
    2. Export the web part, save it as “Extented_Content_Query.webpart”.
    3. Open the web part file in NOTEPAD, modify the following:
    4. a. Set the title property to "Extended Content Query"
          <property name="Title" type="string">Extended Content Query</property>
      b. Set the XSLItemLink to the uploaded XSL style sheet file:
          <property name="ItemXslLink" type="string">/Style%20Library/XSL%20Style%20Sheets/ItemStyleExtended.xsl</property>

    5. Upload the extended Content Query Web Part to web part gallery.
    6. Add the extended Content Query Web Part to the web part page.
    7. Point the web part source to a document library in the site.
    8. Click on a link to verify that it opens in a new IE window.

    Hope this helps!

  • How to use WebAnalytics API – FrontEndDataRetriever.QueryData

    This post is a contribution from Jaishree Thiyagarajan, an engineer with the SharePoint Developer Support team.

    To use WebAnalytics API, first we need to add reference to Microsoft.Office.Server.WebAnalytics.dll and Microsoft.Office.Server.WebAnalytics.UI.dll.  These DLLs can be located in GAC (C:\Windows\Assembly\GAC_MSIL\).

    The WebAnalytics DB (Report DB) has many Table-Valued-functions, which we can leverage programmatically through FrontEndDataRetriever.QueryData.

    Check out the example given below.  I’ve used “fn_WA_GetNumberOfClickthroughs”, this function will retrieve the number of hits per URL.

    List of available functions can be found in this article.

    Sample below.

    try
    {
        using (SPSite site = new SPSite("http://siteURL/"))
        {
            AggregationContext aggregationContext = AggregationContext.GetContext(site);
            if (aggregationContext != null)
            {
                List<ViewParameterValue> viewParamsList = new List<ViewParameterValue>();
                viewParamsList.Add(new ViewParameterValue("StartDateId", DateTimeToDateId(DateTime.UtcNow.AddMonths(-6))));
                viewParamsList.Add(new ViewParameterValue("EndDateId", DateTimeToDateId(DateTime.UtcNow)));
                viewParamsList.Add(new ViewParameterValue("GroupByPageId", true));
                DataPacket dataPacket = FrontEndDataRetriever.QueryData(aggregationContext, null, "fn_WA_GetNumberOfClickthroughs", viewParamsList, null, GetSortOrder("Frequency", OrderType.Descending), 1, 25000, false);
                if (dataPacket.DataTable != null)
                {
                    //Datatable manipulation
                }
                else
                {
                    //No datatable available
                }
                Console.ReadLine();
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }