SliverLight: Application will not update! No matter how many times I clear my cache.

I’ve been developing a SharePoint SilverLight Application and deployed an update to the customers UAT environment. I could see the update but the BA on the team could not. “CLEAR THE CACHE!” I said. It was no good. 

– When I logged into SP as the BA I could see the latest version of the application (strange).

– When I signed into Internet Explorer as the BA (shift + right click on IE + Sign in As Different User) I could reproduce the issue. 

Obviously IE is not being a nice browser, it looks to be caching different versions of the application for different users. This is expected behaviour for any browser except we are clearing the cache, i.e. get rid of all my SilverLight clients.

The quick way to fix this is to change the URL of the SilverLight XAP file in the SP WebPart confguration pane. Simply add a parameter to the end of the URL and this will force IE to get a new version of the application. 

E.g. ~sitecollection/TestProject/Application.xap?version=1

Infopath: Migrating infopath forms to a new URL

Infopath is not the best technology but it is used a lot and there are times when form templates or probably more often entire sites containing 100’s of forms.

Most forms should be referencing the DCL in the site but I’m sure this is rarely the only place we need to change.

Many absolute URLs are embedded within the xml of the forms, these URLs are not easy to change manually.

POWERSHELL TO THE RESCUE!

I didn’t even need to make a script.

http://sharepintblog.com/2011/06/07/updating-infopath-form-templates-and-data-connections-with-powershell/

It just works! Note you will need to download an additional dll but those instructions are in the script. Happy migrations ahead.

 

PowerPivot: Multi-source reporting tool for Excel and SharePoint

I recently had a requirement for creating multi-source reports in a SharePoint environment. The sources were from web services, SharePoint lists and MSSQL databases.

I researched different options and PowerPivot quickly surfaced as the best option for the job. With PowerPivot you can quickly capture, manipulate, display and publish data in Excel and SharePoint.

PowerPivot has two parts, a client component for creating reports and a server component for viewing reports. Both free if you already have licences for excel and sharepoint.

Functionality

Excel

  • Free Add-in
  • Import data from multiple sources
  • Create relationships between data
  • Manipulate data
  • Create tables and Charts
  • Filter data with slicers
  • Familiar UX for excel users

Sharepoint

  • Multiple users can collaborate on reports
  • View Tables and Charts within webpage
  • Interact with Tables and Charts using slicers
  • Automatically refreshes source data

Requirements

Client (https://office.microsoft.com/en-001/excel/download-powerpivot-HA101959985.aspx)

  • Excel 2010 or later
  • 4.0 .NET Framework Client Profile
  • PowerPivot Add-in (free download)

Server (http://technet.microsoft.com/en-us/library/ee210708.aspx)

  • SQL Server Enterprise Edition
  • SharePoint Server Enterprise Edition

Claims: Extranet user authentication made easy

I wanted to set up a site for external users. The site needed a public area with anonymous access and then secured areas for users authenticated via Form Based Authentication (FBA). As I have never done this before I was  happy to see the wealth of posts out there detailing the various approaches.

I did some reading and decided on the following approach:

  • Claims based web application
  • Top level site collection with anonymous access enabled (instructions, again one of many examples)
  • Sub-sites with anonymous access enabled

Here are some instructions to do this. One of many examples; Easy enough.

What I struggled with was the authentication method. By default the authentication goes to a new page, a page that would need its own styling (AFAIK). There are some examples out there of webparts that do the job but they all seemed a bit overly complicated to me. Here is my approach.

1. Create a new Visual Webpart in Visual Studio

2. Stick this in the WebPart class

        [WebBrowsable(true),
         Category(“Common”),
         WebDisplayName(“Redirect Page”),
         WebDescription(“The page to redirect user to once logged in”),
         Personalizable(PersonalizationScope.Shared)]
        public string RedirectPage{ get; set; }
        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @”~/_CONTROLTEMPLATES/<FeatureName>/ExternalLogin/ExternalLoginUserControl.ascx”;
        protected override void CreateChildControls()
        {
            var control = Page.LoadControl(_ascxPath) as ExternalLoginUserControl;
            if (control != null)
            {
                control.RedirectPage = RedirectPage;
                Controls.Add(control);
            }
        }
3. Fire this into the user control ascx
<table>
<tr>
<td>User Name</td>
<td><asp:TextBox ID=”UserName” runat=”server”></asp:TextBox></td>
</tr>
<tr>
<td>Password</td>
<td><asp:TextBox ID=”Password” runat=”server” TextMode=”Password”></asp:TextBox></td>
</tr>
</table>
<asp:Button ID=”Login” runat=”server” Text=”Login” OnClick=”PerformLogin” />
<asp:Label runat=”server” ID=”ErrorMessage” style=”color:Red;”></asp:Label>
4. Shove this up the gullet of the ascx.cs file
public partial class ExternalLoginUserControl : UserControl
    {
        public string RedirectPage { get; set; }
        private static string ErrorText = “Incorrect Username or Password.”;
        protected void Page_Load(object sender, EventArgs e)
        {
            if ((SPContext.Current.Web.CurrentUser != null) &&
                (SPClaimProviderManager.IsEncodedClaim(SPContext.Current.Web.CurrentUser.LoginName)))
            {
                RedirectUser();
            }
        }
        protected void PerformLogin(object sender, EventArgs e)
        {
            try
            {
                if (SPClaimsUtility.AuthenticateFormsUser(new Uri(SPContext.Current.Web.Url), UserName.Text, Password.Text))
                {
                    RedirectUser();
                }
                else
                {
                    ReturnError();
                }
            }
            catch
            {
                ReturnError();
            }
        }
        private void RedirectUser()
        {
            Response.Redirect(RedirectPage);
        }
        private void ReturnError()
        {
            ErrorMessage.Text = ErrorText;
        }
    }
5. Deploy
6.  Add Webpart to page in the top level site.
There we go; extranet site with user login form without having to go to a seperate site.
P.S Sorry for the lack of comments in the code but it sort of speaks for itself.

Custom Alerts: What are the options?

I was asked to investigate different approaches to creating custom email alerts for a customer. Here is what I found.

Update Templates in server folder

Good

  • Built into SharePoint

Bad

  • Text based configuration
  • High technical level required
  • New template needs to be created for each custom alert.
  • Requires IIS and SPTimer to be restarted for each change to be applied.

Estimate 1 day (Development, testing, deployment, UAT testing) per custom alert.

For more information see here: http://sharepointempower.com/2013/03/sharepoint-2010-customizing-alert-notifications-and-alert-templates/

 Custom Workflow

Good

  • Built into SharePoint
  • Have good control over the alerts
  • Lower technical level required than first option

Bad

  • SharePoint Designer skills required.
  • New workflow needs to be created for each custom alert.

Estimate: 1 day (Development, testing, deployment, UAT testing) per custom alert.

For more information see here: http://office.microsoft.com/en-gb/sharepoint-designer-help/send-e-mail-in-a-workflow-HA010239042.aspx

 HarePoint Custom Alerts for SharePoint

Good

  • Ready-made application
  • Least technical solution.
  • Can customise alerts through web-browser
  • Can be maintained by admin user
  • Very flexible: Can have different alerts for adding, modifying and deleting on a per list basis. Users can add custom links, can show before and after values and provide instructions without Kainos involvement.
  • Comes with 30 day free trial
  • Easy installation
  • Can be rolled out across entire farm

Bad

  • £600 per WFE (one off payment with optional £180 per year for support and software updates)

Estimate: 10 minutes deployment, 10-30 minutes configuration per custom alert depending on complexity.

More info can be found here http://www.harepoint.com/Products/HarePointCustomAlerts/Default.aspx

Please Note: I have no affiliation with HarePoint, it just looks like a good product.

Lightning Conductor: XSL to output all selected columns.

I was looking at Lightning Conductor today. I was asked to make an XSL that outputs the columns selected in the webpart’s configuration UI and also provides some custom links.

This little bit of XSL outputs a basic table of the configured Lightning Conductor output. From this you can add as much custom XSL as your require.

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes” ?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform&#8221; xmlns=”http://www.w3.org/1999/xhtml&#8221; >
  <xsl:output indent=”no” method=”html” />
  <xsl:template match=”/”>
    <xsl:choose>
      <xsl:when test=”count(Root/Root/Rows/Row)=0″>
        Your query returned 0 results.
      </xsl:when>
      <xsl:otherwise>
        <table width=”100%” border=”0″ cellspacing=”0″ cellpadding=”3″>
          <!–This is table header–>
          <tr style=”background-color:#E6E6FA”>
            <xsl:for-each select=”Root/Root[1]/Header/Field[@Hidden=’False’]” >
              <td align=”center”>
                <xsl:value-of select=”@Title”/>
              </td>
            </xsl:for-each>
          </tr>
          <xsl:for-each select=”Root/Root/Rows/Row” >
            <xsl:variable name=”row” select=”.”/>
            <tr>
              <xsl:attribute name=”style”>
                <xsl:choose>
                  <xsl:when test=”position() mod 2 = 1″>
                    background-color:white
                  </xsl:when>
                  <xsl:otherwise>
                    background-color:#F0F8FF
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:attribute>
              <xsl:for-each select=”/Root/Root[1]/Header/Field[@Hidden=’False’]” >
                <xsl:variable name=”field” select=”.”/>
                <td align=”center”>
                  <xsl:value-of select=”$row/Column[@fInternalName = $field/@InternalName]/@Value”/>
                </td>
              </xsl:for-each>
            </tr>
          </xsl:for-each>
        </table>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

FAST Search: Add new scope to Advanced page

Had some difficultly finding out how to add a new scope to the advanced search page. Naturally I thought it was the webpart settings but no…

1. Go to Site Collection > Site Settings > Search Scope

2. Select Display Groups

3. Select Advanced Search

4. Check the scope you want to add.

The scope should now appear in the advanced search.

I found this out from http://www.youtube.com/watch?v=lZVPpfD9tDI (15 minute video, skip to 10 minutes).