Saturday, 31 July 2010

Best Practice Sharepoint 2010 coding tips

1.> SharePoint Dispose Checker Tool - Run the SP Dispose Checker Tool on all custom code you write.
SPSite & SPWeb object has a big load and we need to ensure dispose is always called. 2 easiest ways to ensure Site and web objects are always disposed are shown below:
SPSite site;
try
{
site = new SPSite("http://demo1"); // Create the SPSite object
...
}
finally
{
if (site != null) // Check if the SPSite object exists
{
site.Dispose(); // Clean up the SPSite object as it has not be disposed of
}
}

Alternatively I prefer to use using statements
using (SPSite site = new SPSite(http://demo1/))
{

.... // SPSite.Dispose method will be called always
}
Run the SPDisposeCheck tool on all code before deploying outside of you development environment, this can be automated into VS 2010.
2.> Have at least 3 environments i.e. don't send code from the developers machine straight into production. Sandboxed solutions alleviates this risk to some degree but use a UAT, pre-prod, QA environment. Your deployment environment must mimic production as closely as possible i.e. ensure there is a separate SQL DB, all versions of software are identical, load balancing is setup. Have documented change control. Try perform changes through scripts not manual changes if possible. Web.config changes need to be replicated to all servers on the farm so doing the change manually is not the best option. Change the web.config via code to ensure it is done through the configuration database so they are changed on all web.config's in the farm.
3.> Error handling, catch errors as specifically as possible, die gracefully and appropriately, log the errors, check the production error logs periodically.
4.> Deploy code using wsp solutions. Ensure code is not in debug mode when compiled, it runs slower and potentially can crash/holdup your production environment. Implement CAS, deploy to bins if possible and apply CAS security policies to custom coding. Perform peer code reviews, it ensures coding standards are being followed, developers learn from each other, bugs are often picked up pre-testing and it increases team members knowledge that reduces maintenance costs.
5.> Develop using source control no matter how smal the dev project is. Preferably TFS 2010 but VSS 2005 is even fine, failing this use CVS, IMB/rationals ClearCase for source control. Also have bug tracking with TFS the integration is excellent between the bugs and the source control. I.e. use TFS if possible.
6.> SharePoint projects are often very good candidates to SCRUM or other agile methodologies. Use them if it's appropriate. Traditional formal SDLC / waterfall approaches tend to work well on the larger SharePoint projects.
7.> Use the developer dashboard.
8.> Unit testing - don't test SharePoints API, test your custom code. In MOSS Type Mock isolator was a great product for SharePoint I presume this is still the way to go. Andrew Woodward is a good blogger on SP unit testing.

SharePoint 2010 Claims based security & Security notes

Non-Active Directory users in MOSS could support Forms Based Authentication (FBA) so can use SQL to authenticate users, or other providers.
Claims based model decouples authentication from SharePoint.  You can declaratively setup multiple providers. Using Claims Based Authentication (CBA) you can now mix multiple users from different sources in a single zone/site.
In MOSS needed a separate web.config for each set of users.
Using claims based providers can logic/meta-data to provide different users rights depending on rights.
SAML - security access markup language, used instead of Windows identity security tokens. SAM is better in that the token is extendable to give additional authority/claims. I.e. can give additional info on the security token.
CBA allows use to authenticate internal Windows users and external FBA users in the same web app.
Note: Once a claim is validated, the user is added to the SPWeb properties: Users, AllUsers & SiteCollectionUsers before they are authorised.  So as long as they have been authenticated they are added to the properties shown above.

More Info:
Claims explained on Channel 9

SharePoint 2010 simple reporting options

Overview: SSRS has it's place but I want to gather reports from a composite application where data is stored in SharePoint lists.
Solutions:
OOTB web parts - UI may be tricky to get right but useful for quick reporting that can be performed by power users for general business users. Use filter, List View (XLVWP), CQWP, data View, chart web parts.
Custom Web parts - either write or buy web parts for querying lists. Custom CAML queries provide a solution to display data. Con is that it's pretty development heavy, inflexible and requires code deployment. SPMetal has issues with joins, publish columns and hidden columns such as "Created by". Also see Ninetix reporting.
Dataviews - Displaying list data using SPD - need SPD access. Joining 2 lists.

Giles Hamson has a good chart explaining reporting options.

Thursday, 29 July 2010

Custom error and call stack info is not showing on my SP dev machine

Problem: I have turned my web.config file customErrors mode to "Off" however the error is telling me to turn it off or RemoteOnly. Therefore my screen is not showing me the problem. You can debug but the feedback is not provided on the erring SP page.
Hypothesis: Changing the web.config in the IIS SharePoint 2010 web site does not take effect. Ensure the web.config is correct and ensure other related web.configs used by the site are updated.
Resolution: Update the following 3 web.configs:

  • 14\CONFIG
  • 14\TEMPALTE\LAYOUTS
  • Current IIS web.config
web.configs should read:
customErrors mode="Off" />
SafeMode MaxControls="200" CallStack="true" ... AllowPage LevelTrace="true">
compilation batch="false" debug="true" >
More Info:

http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/2673ae4e-0b26-42ba-a158-1ceb63985721
http://blogs.msdn.com/b/amitsh/archive/2007/11/01/why-i-am-not-able-turn-off-customerrors.aspx

Monday, 26 July 2010

Problems with SPMetal in SharePoint 2010

Overview: I have been doing a fair amount of LINQ to SharePoint lately and I have found a couple of issues I don't like namely:
  1. SP metal can run against external content type (BCS) - external content types don't get created by SPMetal;
  2. Hidden fields are not available to the SPMetal created proxy i.e. createdby, modified. Parameters.xml can be changed to display these hidden fields;
  3. Only SharePoint Foundation field types are generated.  Column types are not picked up by SPMetal include the "Managed Metadata columns", "Publishing Html" or "Publishing Image". Additionally any custom created columns are not included by SPMetal;
  4. Anonymous LINQ needs a work around.  Update 27/11/2010, August Cumulative Update (CU) for SharePoint 2010 apparently fixes the anaonymous LINQ to SharePoint issue. Ensure you get the latest CU due to the re-release issues.
  5. Update: 08 Oct 2010 - List attachments are not picked up by SPMetal.  You will need to use the Server side object model or extend SPMetal using a partial class.
  6. Update: 14 Oct 2010 - Multiselect columns are not update-able with multiple values using LINQ to SharePoint.  You can update with 1 value only.
  7. Update 18 Oct 2010 - SPMetal does not like spaces in the url to the site that it generates off. Error the web at 'http://demo.dev/sites/my site' could not be found.
  8. Update 27 Nov 2010 - Using Linq to SharePoint across site collections.  Scope is to the current site collection.

LINQ to SharePoint Posts on this blog
Extending SPMetal for field columns no available to SPMetal by AC (Update) or AC
CAML query for retrieving Publishing HTML and Publishing image columns
Configuring SPMetal default generated code

To see the CAML generated by SPMetal:
StringBuilder sb = new StringBuilder();

System.IO.TextWriter tw = new System.IO.StringWriter(sb);
updatedataContext.Log = tw;
// CAML Query here i.e. var x from customers select customers;
string camlOut = sb.ToString();  // CAML generated.

Update: 09/10/2010 Extend SPMetal to retrieve list attachments

Friday, 23 July 2010

SharePoint 2010 Ribbon for Developers

Overview: SP2010 implements the ribbon UI. Ribbon in the same as word 2007 ribbons in that it provides contextual actions that the user can use. This post looks at styling and controlling/extending the ribbons functionality.
Notes:
  • Ribbon is styled using corev4.css, this changes depending on if you apply a theme. css styling starts with "ms-cui" in the css.
  • SPD can add custom actions.
  • Ribbon is controlled by SP file 14\Template\global\xml\CMDUI.xml, this is merged with our custom xml file at run-time to result in an extended ribbon displayed to users.
  • Deploy the custom ribbon xml using a feature.
  • Buttons can be easily added or existing buttons replaced or hidden using XML declaratively to include custom ribbon actions.
  • Ribbon can also be modified programmatically (SPUserCustomAction)

Thursday, 22 July 2010

Deploying to GAC vs bin folder in SP 2010

Problem: Do we deploy our to the GAC or the bin directory.

Answer: It depends on what the dll is, who needs to use it and is the SharePoint farm dedicated. You need to understand Code Access Security (CAS). Key point is dlls in the GAC (Global Assembly Cache) have full privileges. dll's in the bin have restricted privileges. You can change the level of permissions for dll's in the bin using CAS policies. SharePoint has 2 policys you can use by default: WSS_Minimal or WSS_Medium (same options as in MOSS). You can also use ASP.NET's policies, there are about 5 of these policies in .NET and the highest level is the "Full Trust" CAS policy. You can also create your own policy. Change the CAS relating to you dll's in the bin via your applications web.config.

Only code that runs in the IIS workprocess can be placed in the bin.  Deploying to the bin minimises permissios but certain tasks such as timer jobs, workflows, service applications and event receivers only work in the GAC.  Deploying to the GAC allows for multiple versions of the dll to exist in the GAC provided versioning is used.  Bin deployment can't have multiple versions.

Note on Sandboxed solutions - runs is the "Microsoft SharePoint Sandboxed Code Service", sandboxed solutions have restricted rights to what it can do. It can permorm basic SP Server side OM's unde the SPSite (Site collection) object under the current SPSite which makes sense. Sandboxed code is deployed to the solutions gallery under the current SPSite. You can also use sandboxed solutions with code proxyies to achieve higher rights operations.  So as you can see sandboxed solutions do not go into the GAC or the bin and CAS is not an issue.  Real option is between GAC + using a Sandbox solution.

Sandbox solutions are good in restricted high usage environments as they allow SharePoint Administrators to validate (manually and via solution validators) the code being uploaded.  Developers are limited in what they can do to the environment.  The counter stop inefficient code once the threshold has been passed.  Administrators can monitor sandboxed solutions to easily identify poorly performing code.

My general rule is: Deploy my custom code to the GAC except if it's not trusted i.e. 3rd party code or there is a business reason/policy not to. It makes dev easier but is not ideal in that best practice decitates that you should apply the minimal levels of security permissions to your code.
Additional Info: Microsoft SharePoint Team Blog on application development.
Great blog on sandboxed solutions

Tuesday, 20 July 2010

SharePoint 2010 membership provider/Claims based authentication

What is Claims based authentication?
Allows SharePoint to communicate with external membership providers over open communication standards to authenticate a user. The membership provide determines if the user is valid. A token either saying the user is valid or invalid is returned. More info
Authorisation is handled by SharePoint or the logic can be applied by external membership providers.
Forms Based Authentication (FBA) works with your membership provider to give users access off a provide such as LDAP providers like Active Directory (AD).
You can also setup Windows Authentication in the "Identity Provider" where you use either NTLM or Kerbros as well as other ASP.NET providers.
The SecurityTokenService (STS) Application ensures claims tokens are being passed correctly between the provider and SharePoint (Our SPSite). STS allows for multiple providers plugged in our site. STS is setup in the web.config. More info.
Tip: Sign in Url - when setting up FBA, you can use a custom page to add business logic, for instance I assign rights/permissions when a user comes from a trusted 3rd party. More info.
Tip: FBA doesn't have to use claims based authentication as in MOSS. If you have AD but need to provide Internet access then Claims based adds no value. More info.
NTLM vs Kerbros: NTLM stands for NT Lan Manager. Microsoft's challenge response authentication protocol. Kerbros is an open standard authentication protocol, it is more secure in that it is encrypted and token are used to validate parties in the communication process. Kerbros requires ADFS.  Kerbros is therefore more secure however you do need to have a network that supports Kerbrose for it to work. Kerbros is more chatty and introduces more points of failure. NTML is more efficient. Depending on usage such as Internet it will determine the protocol.  I tend to lean towards Kerbros in larger SharePoint implementations if the network supports.  Internet scenarios don't expose ADFS to the Internet so Kerbros is not an option.

More Info:
Setting up SQL claims based FBA

Updated: 2014-02-27
Setting up ADFS2.0
Configure an Authentication Provider for a Web App to use ADFS

http://www.sharepointpals.com/post/Creating-an-ADFS20-TrustedIdentityTokenIssuer-using-PowerShell-in-SharePoint-2013
http://www.sharepointpals.com/post/How-to-Add-more-than-One-SharePoint-2013-WebApplication-to-a-SPTrustedIdentityTokenIssuer-on-ADFS-using-PowerShell

Thursday, 15 July 2010

Deploying resources using features

Overview: Feature deployment has changed in SP2010 from MOSS. In MOSS we added files to the 12 hive and deployed them via a feature. In SP2010 the feature is package slightly differently and is marginally easier to create using VS2010 because of the tools. I have VS2010 and the CKSDev tools installed.

Steps to add an xslt file to your style library using a feature in SP2010:
1.> In VS2010 create a new Element;
2.> Under the element add and xslt, change the "Deployment Type" property;
3.> Move the elements to "Items in the Feature" default is "Items in the Solution";
4.> Modify the elements.xml file;

5.> Ensure the itemStyleCustom.xsl exists in the Xsl Style library.

Wednesday, 14 July 2010

SP2010 CQWP customisation

Overview: Content Query Web Part (CQWP) in SP2010 is similar to in MOSS. This post walks thru using the CQWP to display a custom list and custom columns while outputting custom html via a custom xslt.
CQWP (need the publishing feature enabled, this creates the styles library and add the CQWP) by default uses the xslt /Style Library/XSL Style Sheets/ItemStyle.xsl.

Steps:
  1. Don't write over ItemStyle.xsl as this si supplied by SP2010 OOTB. Rather create a new xslt and put it into the styles library. Build up the xslt, I based my file on the itemstyle.xsl file, see rules for getting the output you are looking for using How to: Customize XSL for the Content By Query Web Part
  2. Custom xslt formatting, I always add the following code in case I want to see what the available fields are:
  3. Deploy the custom style sheet via a feature.
  4. Create a new Custom list called "Pets" and add columns for Title, Age & Status (choice):
  5. Edit your custom xslt to display for "Pets" as shown below:
  6. Add a new CQWP to your page. Configure it to display items from your new list (Pets).
  7. Change the "Presentation" section, "Item Style" to Show "Pets". Apply the Changes:
  8. CQWP displays as:
  9. Edit the CQWP "Age" property to "Age"
  10. Edit the CQWP "Age" property to "Status"

    Tuesday, 13 July 2010

    Audience Targeting in SP2010

    Overview from MS
    Technet User Profile Service Overview
    Audience targeting needs compilation so not useful when adding users on 1st login however, menu items can be targeted using SharePoint security groups.
    Audience targeting is part of SharePoint Standard edition.  SharePoint 2010 editions comparison.
    Update 5 Dec 2010 - The "Publishing feature" needs to be enabled on the site collection and site.  User Profile Service needs to be running.

    Setup Audience targeting on Global menu's.

    Overview: To use audience targeting you need to have at least SharePoint Server standard edition as you need the "Site Collection Publishing Feature" enabled. 

    In this walk thru I am adding a user to a SharePoint Group and allowing the group to see a menu option.  Also ensure audience targeting is enabled.
    Add the user to the Share Point group in my case I added the user "ReadOnlyUser" to SharePoint Security group "Extend Visitors".
    Edit the menu option to be only visible to the SharePoint group "Extend Visitors".
    Menu of normal user without the extra menu option.
    User that can see additional menu options

    Monday, 12 July 2010

    Sharepoint 2010 Dialogs Framework

    Problem: Use the dialog framework to edit information on a SharePoint composite page.
    Hypothesis: Dialog framework can open existing pages and pass back values to the calling page. The pass back value can be more than just a simple parameter such as a string. You can return fairly complex flat objects. The example below, displays multiple addresses, allows the user to edit any of them via a modal dialog. and returns the updated address along with the id of the element address to change. To use the dialog framework modals you need SP context so use any of the client OM's or the server OM (i.e. you can't use html unless to load the SP context)
    In the parent page inside javascript add the following 2 functions
    function OpenDialogAdr(myurl) {
    var options = SP.UI.$create_DialogOptions();
    options.url = myurl;
    options.width = 200;
    options.height = 100;
    options.dialogReturnValueCallback = CloseCallback;
    var dialogSP = SP.UI.ModalDialog.showModalDialog(options);
    }
    var messageId;
    function CloseCallback(dialogResult, returnValue) {
    if (dialogResult === SP.UI.DialogResult.OK) {
    var adr = returnValue.adr;
    var id = returnValue.id
    $("#adr-sales-" + id).html(adr);
    }
    }


    Add a link with the appropriate js:
    Add the child page, that will return the new address and the id of the item to change.

    function onUpdate() {
    var adrs = document.getElementById('txtAdr').value;
    var ids = document.getElementById('txtId').value;
    var mydata = {
    adr: adrs,
    id: ids
    };
    SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, mydata);
    }
    function onCancel() {
    SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult
    }

    Resolution:
    The dialog framework is good for displaying additional information. It is similar in nature to using jQuery & the lightbox plug in.

    Resources:
    Working with SP2010 modal dialogs

    SharePoint 2010 UI/browser help urls

    Site settings url: http://...../_layouts/settings.aspx
    Determine CAML to create site columns  http://url/_vti_bin/owssvr.dll?Cmd=ExportList&List=listguid
    Remove web parts from a page http://url/_layouts/spcontnt.aspx?&url=page/_layouts/spcontnt.aspx?&url=page

    VS2010 deployment error Site Url property missing

    Overview: Each new developer on a project grabs the solutions/project files from TFS or VSS as in my case. When they try deploy the solution, they receive an error "Error occurred in the deployment step 'Recycle IIS Application pool': Cannot connect to the SharePoint Site: http://... Make sure that this is a valid URL and the SharePoint site is running on the local computer, ... Update the Site URL property on the project."
    Resolution: As the error suggest go to the project being deployed and ensure that you local development url is entered in the "Site URL" property. Obviously this setting should not be stored in source control as it will often differ per environment/developer.
    Visual Studio 2010 Project properties

    Friday, 2 July 2010

    Dynamic LINQ to SharePoint 2010

    Problem: I have 2 connected Web Parts, the provider provide multiple values for lookup columns. I started with LINQ to SharePoint (SPMetal) but could not build up the query dynamically.
    Hypothesis: My initial reaction was to use a dynamic CAML query as done in MOSS using U2U to work out my query. The issue is that the CAML is not safe (as we don't get validation until run-time) but at least I can dynamically build up my query.

    Using Dynamic link with LINQ to SharePoint to can achieve the required result. The code is safe as least for run-time (my logic is still dodgy). Only issue is with the performance and the results if the list if large. Using a very broad LINQ-to-Sharepoint query that is converted into a CAML query anyway I get a large result set. I then filter using dynamic LINQ. Pretty heavy filtering and inefficient querying. Throttling concern: If I returned more than 5,000 items (default list throttling limit for SP2010 lists) I now loose results that should be queried (SharePoint would trim my SPMetal query and then Dynamic LINQ would work on the max of 5,000 items). Sure you can turn throttling off as a farm admin but not a great idea. You could programatically override the throttling (SPQueryThrottleOption.Override) using the server OM but this doesn't help for your SPMetal query.
    In this case, my best option is to use a dynamic CAML query and get the exact set of data I am looking for.

    Tip: Only get the fields you are using in CAML queries.
    More Info:
    Building CAML queries
    Dynamic LINQ - Scott Guthrie

    LINQ to SharePoint Posts

    Thursday, 1 July 2010

    Installing Sharepoint 2010 options & Basic SP2010 manual installation tips

    You have 4 options for installing SharePoint farms:
    1. Manually sun the setup and follow the installation wizard (this is discussed below);
    2. Deploy SharePoint 2010 via a slipstream install, this was my prefered method for MOSS.  I ran the install from a batch file that got it's configuration from an xml file;
    3. PSConfig installation (sic); or
    4. Use PowerShell to Install SharePoint. and technet scripted deployment
     Summary: For environments such as live the PowerShell/Slipstreamed options are best as they allow for recreation and input is always identical.  Manual install is fine for development servers however their is no advantage except for a lower learning curve for the IT admin.
    Post below is a Manual Installation:
    SP2010 install video
    Install the pre-requisites
    • Prerequisits will install roles and software you need internet access on the server to fetch the prerequisits software (this can be put on the server to stop the machine going to the Internet).
    • Preferably have seperate instance of SQL 2008 R2 but for dev/demo machines. If 1 machine rather setup SQL devleoper or a instance (I dislike using SQL express).
    Setup / SP 2010 install tips
    • Install "Server farm" option not standalone
    • "Complete" installs all component prefered option
    • Connect to a new farm
    • Database server name us name rather than IP (incase it changes)
    • DB account (must already exist in AD)
    • Passphrase used to connect new servers to this server farm (remeber/keep it)
    • Kerbros - if your network supports it but use NTLM if you aren't sure.
    • Wizard - follow screens, services can be heavy so add them when you need them, however for demo I select all services and create a new site collection - a good options is to use the Team Site Template.
    • Need 3 accounts for min Best practices: 1) Managed Service account (domain user account) that SQL Server runs in, 2) Managed Service Account (domain user account) all services will be installed on this account (MS suggests using a seperate managed account for each service) on small farm s/dev I use 1 account,  and 3) Farm install account (domain account) this needs to be a local admin on each SP2010 server and have creator & dbsecurity accouts on SQL.
    • 5 Accounts is a better option excluding the SQL services account namely:
    1. SP-Install - domain account with admin local rights on each WFE also need SQL dbcreator and securityadmin roles (used to login and install binaries, use this account for add new servers to the farm),
    2. SP-Farm - domain account no permissions, will be the account to run timer job and other key roles,
    3. SP-Web-App-Pool - Content Web app account - Domain account only,
    4. SP-Services - Install all services to use the same domain account, this can be seperate for each services but for easy of setup and mainentance use 1 account.  Exception is the User Profiles service, setup seperately using Spence Harbors post as the user domain account needs unique security, and
    5. SP-Crawl - Used to crawl SP content.
    Additional Info on accounts:
    1. SQL Server needs to run as a windows service, you need an account, I would use a managed account in AD with no permissions called SP2010-SQLService.
    2. Farm Installation account, you need to create a domain user account in AD, give the account local admin access to each SP2010 machine.  Call it SP2010-Admin.
    3. SP2010 Service account/s, you need to create a managed service account with zero permissions in AD.  You can use 1 account or create a seperate account for each service (MS Best Practice).  I call my 1 account SP2010-Services. 
    Use slipstreaming for SharePoint it's faster and consistant.
    Use:
    1. Windows 2008 R2 x64
    2. SQL 2008 x64
    3. On HyperV/VMWare except the db which should be a seperate physical machine/SAN
    Update 08 November 2010:  Notes on deploying a 3 server farm consisting of 2 WFE's that are NLB using Windows NLB.  Installation done using AutoSPInstaller. 
    Installation Notes for a 3 server NLB SharePoint 2010 farm

    Update 10 November 2010: SharePoint install account - Todd Klindt.
    Update 11 May 2011: SharePoint 2010 database management article