Archive for SharePoint 2010

SharePoint Conference 2014 aftermath – Customizing Forms

As a blog primarily focused on the technical aspects of building applications in SharePoint, I won’t drone on about the far-reaching impacts of “The End of the InfoPath Era” – this was already announced in the weeks leading up this year’s SharePoint Conference, and then (sort of, but more on that later) given more clarity during the Conference itself. In short, although end-of-life support for InfoPath will extend until 2023, last year’s release will remain the final one to include any new features or functionality, while fixes & patches will be at the pace you’d expect from a Microsoft product on its way to sunset.

Sitting in the room at SPC14 with hundreds of my fellow SharePoint developers, users & executives, I got a first-hand glimpse of what Microsoft sees as its path, or really paths, forward. We knew Microsoft meant business when the session was given a primo time slot & 3 Microsoft employees to present; in the end, what we got was a scatter shot of four possible options for replacing custom InfoPath forms:

  1. Using Excel Surveys, an apparently little known feature for creating custom forms directly inside an Excel document & that write to a worksheet therein.
  2. Using a new, yet to be released “Forms Over SharePoint Lists” web-based designer for creating custom forms in SharePoint 2013 (and yes, that acronym is FOSL, pronounced ‘fossil’ by the MS reps themselves – insert irony joke here).
  3. Possibly using Word for structured document forms – this I say “possibly” because MS committed only to providing a roadmap for this option by the end of 2014; no actual product yet.
  4. Using Access Apps, which if you used them in SP2010, seem reminiscent of the Office Business Apps (OBAs) that were touted then.

With such a wide range of choices, and comparatively little guidance on when to use which & where, I couldn’t help but think the flexibility & power of the CorasWorks Actions Framework provides a much-needed alternative. In the coming months, I suspect more vendors will try to fill the “custom forms” gap with new products – but we’ve been building apps with & improving our Actions Framework, including our web-based designer (the Actions Wizard) for more than 8 years now; this is a feature set CorasWorks knows well!

And as an architect that’s designed & implemented 100+ custom applications on SharePoint, I also know just creating a custom form a solution does not make; what if you want to apply a custom form to more than one list, across multiple sites, site collections or web apps, with a single centralized definition – none of the MS approaches facilitate this, while the CorasWorks platform has for years. Or how about custom forms that are exposed depending on the current values or stage an item is in, can trigger Workflows anywhere in the SharePoint farm, or are security trimmed based on the currently logged in user? All core features of the CorasWorks Actions.

Plus, in the coming months, while others are just starting to explore the world of InfoPath alternatives, CorasWorks will be expanding our Action framework further to include integration with other data sources & providing greater flexibility & customizability in the form UI.

So while the InfoPath announcement and SPC14 have put the topic of custom forms for SharePoint at the forefront, CorasWorks has been building & improving our platform – which includes this key feature – since the SharePoint 2003 days.

Resolving Errors when saving Sites as Templates in SharePoint 2010

For all the improvements and updates introduced with the SharePoint 2010 release, there’s at least one segment of the platform that got harder to work with – saving sites as templates. Debates rage about whether and to what extent people should even use SharePoint site templates as a deployment mechanism (vs say Features) but if you found your way here, you’ve likely already made that decision and just need some tips on resolving some of the common errors we here at CorasWorks ran into when SharePoint 2010 was first released. Hope these help!

Error #1

“Error exporting the list named “YourList” at the URL: Lists/YourListURL

When getting this error, the name of the list is almost always the first list (in alphabetical order) within your site, and you’ll likely see an error screen like this:List Export Error

The error is often the result of the default content types not being present/enabled within the Site Collection you’re working in. A quick pair of PowerShell commands though and you can get them redeployed fairly quickly.

First, fully disable them:
Disable-SPFeature –Identity ctypes –url http://SiteCollection

Then, enable them anew:
Enable-SPFeature –Identity ctypes –url http://SiteCollection

Now you’re back in business; go ahead and try to save your site as a template again. If you get a new error however, read on…

Error #2

“The attachments column does not exist for list Id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, list name YourList

In this case, a generic error is displayed in the UI and the above message is found in the logs using the Correlation ID of the error.

Usually related to error #1 above, this error indicates the default Site Columns are missing and thus SharePoint is unable to build a functional Site Template. And just like above, a short pair of PowerShell commands are all you need to get said Site Columns redeployed.

Again, first disable them completely:
Disable-SPFeature –Identity fields –url http://SiteCollection

And then re-enable them:
Enable-SPFeature –Identity fields –url http://SiteCollection

References

CorasWorks support for In, Includes and NotIncludes filters in SharePoint

Starting with SharePoint 2010, three new CAML filter operators were added, but scant details and examples mean that even 3+ years later, few people know about or use them. Fortunately, the CorasWorks platform (including CAPS) fully support these new operators – and here’s some insight on how you can take advantage of them!

The <In> operator

This is probably my favorite addition of the three and the one I use most often; what it does is allow you to collapse what would normally be a string of multiple <Or> filters into one single <In> condition.

For example, you want to filter a native Tasks list to show all items that are “Not Started”, “In Progress” or “Waiting on Someone Else”; you would likely string three together three <Eq> conditions inside <Or> operators (or even string two <Neq> filters for the other possible values of “Completed” & “Deferred”).  Something like this:

<Where>
<Or>
<Or>
<Eq>
<FieldRef Name=”Status”/>
<Value Type=”Choice”>Not Started</Value>
</Eq>
<Eq>
<FieldRef Name=”Status”/>
<Value Type=”Choice”>In Progress</Value>
</Eq>
</Or>
<Eq>
<FieldRef Name=”Status”/>
<Value Type=”Choice”>Waiting on Someone Else</Value>
</Eq>
</Or>
</Where>

Now let’s see that same filter written using the <In> operator:

<Where>
<In>
<FieldRef Name=”Status”/>
<Values>
<Value Type=”Choice”>Not Started</Value>
<Value Type=”Choice”>In Progress</Value>
<Value Type=”Choice”>Waiting on Someone Else</Value>
</Values>
</In>
</Where>

How’s that for efficiency? Easier to read and easier to write – bet you never thought you’d say that about a CAML query.

The <Includes> operator

If the <In> operator is akin to a string of <Or> conditions on a single value, the <Includes> operator is a specialized option for working with multi-select Lookup values; think of it as a “contains”, but intelligent enough to differentiate if you have similar text in multiple Lookup values.

Sticking with our Task list example, imagine wanting to filter by the multi-select Lookup that is the Predecessors column to find all Tasks that have a specific predecssor – this would allow you to see all the Tasks that might be impacted by a specific one slipping. You can’t use an <Eq> condition because that would only bring back items whose only predecessor is the Task you want – again, the <Includes> gives you the advantage of working more like an intelligent contains, like such:

<Where>
<Includes>
<FieldRef Name=’Predecessors’/>
<Value Type=’Lookup’>Task 4</Value>
</Includes>
</Where>

The <NotIncludes> operator

This one is now simple because it’s just the inverse of <Includes>. Still specifically built for multi-select Lookups, it would allow you to filter for, in our same scenario, all Tasks that do not have a given Task as a predecessor – it’s the intelligent version of a “does not contain” filter, implemented as:

<Where>
<NotIncludes>
<FieldRef Name=’Predecessors’/>
<Value Type=’Lookup’>Task 4</Value>
</NotIncludes>
</Where>

References

Not that there’s much more detail there, but here are the corresponding MSDN links for these operators as well:

Securing & Hardening SharePoint Sites – Part 3

Previously, we discussed how the CorasWorks platform enables working with data anywhere in your SharePoint farm, followed by some masterpage changes you can make to secure away SharePoint’s system pages within a site. In our third and final part of this series, I’ll describe how CorasWorks can be used to essentially create a secure “proxy” for use within your SharePoint-based applications.

Typically in SharePoint, if you want a user to be able to see some data, or even enable them to perform inserts/updates/deletes, you have to give that user at least direct access to the item(s), if not the parent List or even Site the data is in. However, with the CorasWorks External Data Provider – don’t let the word “external” fool you – you can actually create secured connections between a user interface on one SharePoint site and the data on another, without the logged in user actually having any access to said data.

Sounds crazy, or worse, unsecure? Not at all! The architecture supported is not unlike integrating with a line-of-business database application; a SharePoint admin can create and enable the equivalent of a service account that will be given the necessary rights to the underlying data to support the application requirements. That account’s information is then stored in secure web.config app keys. On the CorasWorks side, you can then reference the corresponding app keys in your configuration of an External Data Provider to make HTTP Post calls to any URL said account has access to – these can be calls to native SharePoint service endpoints or, even better, our own API.

From there, you can now focus on creating the optimal UI for your users and let CorasWorks handle the proxied connections between the UI and the data. The users accessing the application will only need Read rights to the UI elements, and so even if they ever figure out where the data is coming from (which they won’t, because you’ll have secured that away too), they still won’t be able to access it outside the UI you create.

If this sounds like a design pattern you need, email steve@corasworks.net and we’ll setup an architectural review to help get you started!

Securing & Hardening SharePoint Sites – Part 2

Previously we blogged about the reasons for – and potential concerns with – opening up a SharePoint application to external users. The improved collaboration and access to real-time data is certainly compelling, but what if we’re concerned savvy users might decide to poke around the SharePoint site we give them access to? Even with the proxy design available to architects using the CorasWorks platform, there’s always those users who may try to access content or underlying back-end SharePoint pages, like the “All Site Content” or “All People” pages.

Luckily, there’s a straightforward way to make some quick adjustments to a masterpage and restrict access to even those system pages for a given site. To start, let’s look at the first few lines of HTML that normally make up the body of a masterpage; this example comes from an unmodified “v4.master” in SharePoint 2010:

<body scroll=”no” onload=”if (typeof(_spBodyOnLoadWrapper) != ‘undefined’) _spBodyOnLoadWrapper();”><form runat=”server” onsubmit=”if (typeof(_spFormOnSubmitWrapper) != ‘undefined’) {return _spFormOnSubmitWrapper();} else {return true;}”><asp:ScriptManager id=”ScriptManager” runat=”server” EnablePageMethods=”false” EnablePartialRendering=”true” EnableScriptGlobalization=”false” EnableScriptLocalization=”true” />… (The rest of the page)</form>

</body>

When customizing a masterpage, one of the things you can do is add Security Trimmed Controls, which essentially allow you to wrap a block of content within your masterpage and thus restrict the display/running of it to only those users whose permissions match the settings specified. Here’s an example of one such use:

<Sharepoint:SPSecurityTrimmedControl runat=”server” ID=”HidePage” Permissions=”ManageWeb” PermissionMode=”All” PermissionContext=”CurrentSite”>

Now imagine you wanted to secure the entirety of your underlying SharePoint system pages, like “All Site Content” or your native List Views. No problem – simply wrap the entire contents of the <form> tag that encompasses the page and you’ve got a locked site where only users with sufficient permissions can access your back-end pages:

<body scroll=”no” onload=”if (typeof(_spBodyOnLoadWrapper) != ‘undefined’) _spBodyOnLoadWrapper();”><form runat=”server” onsubmit=”if (typeof(_spFormOnSubmitWrapper) != ‘undefined’) {return _spFormOnSubmitWrapper();} else {return true;}”><Sharepoint:SPSecurityTrimmedControl runat=”server” ID=”HidePage” Permissions=”ManageWeb” PermissionMode=”All” PermissionContext=”CurrentSite”><div id=”FullPage”><asp:ScriptManager id=”ScriptManager” runat=”server” EnablePageMethods=”false” EnablePartialRendering=”true” EnableScriptGlobalization=”false” EnableScriptLocalization=”true” />

… (The rest of the page)

</div>

</Sharepoint:SPSecurityTrimmedControl>

</form>

</body>

Want to display a note to users who try to sneak their way in; another simple tweak – just add a little HTML with some appropriate verbiage, then hide said message if the user does have sufficient rights:

<body scroll=”no” onload=”if (typeof(_spBodyOnLoadWrapper) != ‘undefined’) _spBodyOnLoadWrapper();”><form runat=”server” onsubmit=”if (typeof(_spFormOnSubmitWrapper) != ‘undefined’) {return _spFormOnSubmitWrapper();} else {return true;}”><div id=”ReadersMessage” style=”width:100%;text-align:center”><h1>Nothing to see here…</h1></div><Sharepoint:SPSecurityTrimmedControl runat=”server” ID=”HidePage” Permissions=”ManageWeb” PermissionMode=”All” PermissionContext=”CurrentSite”><script type=”text/javascript”>document.getElementById(“ReadersMessage”).style.display = ‘none’;</script>

<div id=”FullPage”>

<asp:ScriptManager id=”ScriptManager” runat=”server” EnablePageMethods=”false” EnablePartialRendering=”true” EnableScriptGlobalization=”false” EnableScriptLocalization=”true” />

… (The rest of the page)

</div>

</Sharepoint:SPSecurityTrimmedControl>

</form>

</body>

To learn more about the SPSecurityTrimmedControl, check out the documentation from MSDN here: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.spsecuritytrimmedcontrol_properties.aspx

The three properties you will want to focus on are the “Permissions”, “PermissionMode” and “PermissionContext” one as seen in the examples above; for reference, the examples here would hide the contents of any page using this masterpage to all users except those with Owner (or equivalent) rights on the current site.

Three Approaches to Building SharePoint Solutions

When it comes to building solutions with SharePoint, there are three approaches.

LowCode

No Code

SharePoint comes with a rich set of features and functionality that can help deliver your solution requirements.  For a feature matrix, you can refer to this SharePoint 2013 Feature Matrix blog posting.

But what if the business requirements can’t be delivered purely with out of the box capability?

Custom Code

With SharePoint Solutions, there is a general impression that the more complex the requirements are the more likely you are going to need custom code.  Depending on your organization, you may need to tap internal developers who will crack open Visual Studio and start plugging away on your requirements.  If you don’t have the luxury of having SharePoint developers you will need to employ outside consultants.

One thing to note around custom SharePoint code.  A .NET developer does not necessarily equal a SharePoint developer.  Knowing the SharePoint object model is required in addition to understanding .NET.  When doing custom code, if you treat SharePoint like all other web site development, you are likely to encounter pain later when upgrading or modifying it later.

With the specialized skills required for custom coded solutions, it requires a huge investment in developer resources, training and ongoing maintenance.  It’s quite possible that it makes it cost prohibitive to pursue solutions where complex requirements are in view.  But is there another option?

Low Code
The CorasWorks Approach

Traditional web developers are much more accessible than those with specialized SharePoint development skills.  They are also more affordable.  Most organizations have web developers with more common skills like HTML and XML along with JavaScript and jQuery.  You could train these resources to understand the SharePoint Client Side Object Model for instance but there are other options.

The “No Code” option implies being locked into certain functionality and capability.  The “Custom Code” comes with specialized resourcing requirements.  The “Low Code” option offers flexibility to meet solution requirements while leveraging more readily available resources.

CorasWorks provides a low code option through our Platform and Application Service (known as CAPS).  Our Platform and CAPS make it possible to build complex solutions with the flexibility you would expect from a custom solution but with a much smaller code footprint.  For a look at CAPS capability, please read this recent blog article outlining those capabilities.

With CorasWorks, your traditional web developer can build a feature rich, complex solution with less code and using the skills they already possess.  Our off the shelf solutions have taken this approach and it’s available for you to build your own solutions.  Have you taken some projects off the SharePoint solution roadmap because their requirements would have forced you down a custom development approach?  Well grab some pizzas, one of your traditional web developers, a copy of CAPS and reinstate those projects.  You’ll be surprised at what you can build with this low code approach.

CorasWorks v11.3 and SharePoint 2010 Service Pack 2

Lately, the CorasWorks Support team has been receiving questions concerning SharePoint 2010’s Service Pack 2.  The Service Pack was released late in July 2013, and users would like to know if the CorasWorks Solutions and v11.3 Platform are compatible with it.

CorasWorks has been testing the SharePoint 2010 Service Pack 2 with v11.3.  Our testing hasn’t found any problems requiring changes to the solutions or the Platform components.  We have had similar responses from users who have already installed the Service Pack 2.  Feel free to install SharePoint 2010 Service Pack 2 into your CorasWorks-based SharePoint 2010 environments.

Naturally, the SharePoint 2010 environment is multifaceted, one with many possibilities of server, network, security, and other options.  Should you see any unexpected behavior after installing Service Pack 2, report the behavior to the CorasWorks Support team.

Thanks!

CorasWorks Support
Support@CorasWorks.net

What happened to “NT AUTHORITY\Authenticated Users” in SP2010 & SP2013

For those that used SharePoint prior to the 2010 release, you may recall we had the option to add an account named “NT AUTHORITY\Authenticated Users”, which had the effect of granting access for all of your AD users with one shot. However, if you go looking for the same account in SharePoint 2010 or SharePoint 2013, you may become concerned when you search the address book and receive this:

PeoplePicker

Worry not though; while Microsoft has hidden it away from the search of the address book, said account does still exist. You just need to manually type in “Authenticated Users” then click the user check icon instead of searching the address book for it. Once the check completes, you should see an image similar to below:

GrantPermissions

Now you have easy access for all your AD users again!

Prevent Edit in MS Word (or any App) in SharePoint

Recently we were faced with the requirement from a client that wanted to be able to edit a Microsoft Word document accessible via SharePoint (via a link) but ensure that once the document was closed, the user could no longer edit it. Thanks to the way Microsoft Office maintains the linking of documents between the client and SharePoint when opening a file, it is easy for a user to view the link to a document or List Item attachment when it opens and then, when saving, see the original file location on the server.

Our issue became how do we lock down the file without a lot of manual permissions but still allow a user to click a link and download a copy of a document. What we crafted was a solution that leveraged the native “_layouts/download.aspx” page to effectively break the link between the file in SharePoint and the local copy a user opens on their machine. Within our documents display, we simply dynamically generate hyperlinks using the following format:
<<YourSiteURL>>/_layouts/download.aspx?SourceURL=<<YourFileURL>>

Doing so ensures the copy of the file downloaded to the client machine has no URL or link back to the original location, and thus obscures the ability for a user to click & open a document in SharePoint and then easily save it back to SharePoint – because in this case, that’s exactly what we did not want. As an added perk, since the display was built via XSLT (remember, CAPS supports XSLT 2.0), we were also able to conditionally build the link to the documents based on the overall item status.

Grouping in XSLT 2.0

I have been helping one of my colleagues on an engagement that has a complex project Gantt chart as part of a custom Project Lifecycle Management application.  The chart involves multi-level grouping of the data from a number of SharePoint Lists so it was an excellent opportunity to take advantage of the ability to utilize XSLT 2.0 as supported by the CorasWorks Application Service (available for both SharePoint 2010 & 2013).

XSLT 2.0 has some significant advantages over XSLT 1.0, including improved support for data types, custom functions and data parsing.  One of the other major improvements – and the reason I was excited about working on the Gantt chart solution – is the ease with which data can be grouped.  Grouping and especially multi-level grouping with XSLT 1.0 can be quite laborious and prone to errors.  A popular and efficient method of grouping in XSLT 1.0 is Meunchian grouping, wherein keys are defined that will be used in the select attribute of the <xsl:for-each> instruction so the processor knows which data values to group on.  Each additional level requires that a new key be defined and that the grouping value used be a concatenation of the preceding key’s value with the current grouping value.

Various examples of grouping with XSLT 1.0 are located at Jeni Tennison’s site, and here’s the basic form for multi-level grouping:

<xsl:key name="service_row" match="SetDailySetRpt:SettleItem" use="SetDailySetRpt:ServiceCode" />

<xsl:key name="exchange" match="SetDailySetRpt:SettleItem" use="concat(SetDailySetRpt:ServiceCode, ' ', SetDailySetRpt:ExchangeName, ' ', SetDailySetRpt:ExchangeCode)" />

<xsl:variable name="service_items" select="key('service_rows', SetDailySetRpt:ServiceCode)" />

<xsl:for-each select="$service_items[generate-id() = generate-id( key('exchange', concat(SetDailySetRpt:ServiceCode, ' ', SetDailySetRpt:ExchangeName, ' ', SetDailySetRpt:ExchangeCode))[1])]">
  <xsl:value-of select="SetDailySetRpt:ExchangeName" />
  <xsl:text> - </xsl:text>
  <xsl:value-of select="SetDailySetRpt:ExchangeCode" />
</xsl:for-each>

I have used this grouping method with great success on a variety of reports and displays, but it can be frustrating to make sure you have all the keys, variables and select attributes within the <xsl:for-each> instruction properly written.

With XSLT 2.0, life is much simpler when it comes to grouping.  No longer do you need to define keys and declare variables.  Here’s an example of multi-level grouping with XSLT 2.0:

<xsl:for-each-group select="NewDataSet/Data" group-by="LEVEL_1_DATA">
  <xsl:value-of select="current-grouping-key()"/>
  <xsl:for-each-group select="current-group()" group-by=" LEVEL_2_DATA ">
    <xsl:value-of select="current-grouping-key()"/>
    <xsl:for-each-group select="current-group()" group-by="LEVEL_2_DATA ">
      <xsl:value-of select="current-grouping-key()"/>
      <xsl:for-each select="current-group()">
        <xsl:value-of select="ITEMS"/>
      </xsl:for-each>
    </xsl:for-each-group>
  </xsl:for-each-group>
</xsl:for-each-group>

The first thing you’ll notice is that we are using XSLT 2.0’s <xsl:for-each-group> instruction at each grouping level and that there is a group-by attribute that lets us quickly define what we want to group the populate of data on at that level.  As we traverse down the hierarchy, we can simply reference the current group we are in by setting the select attribute to use the current-group() XPATH expression. For more information, check out this great discussion about XSLT 2.0’s <xsl:for-each-group> instruction and its various attributes can be found here.