Tuesday 29 June 2010

Logging custom error for SharePoint 2010 custom code

Problem: SP2010 has good logging in the ULS logs. Unlike MOSS you can write to the ULS logs in SharePoint 2010, allowing for a single consistant place to log your errors. The event viewer logs errors to a lesser extent than ULS where administrators tend to look first. However, on all projects the topic of how and where to log custom coding errors comes up. What level should the event be caught at and where should they be placed. I have seen multiple was of doing this and it really comes down to what the previous projects used and how do you want to monitor errors.
Tips:
  1. Don't write code to function using error catching i.e. I have seen developers catch a specific error and from this position they know the code is to follow specific logic -it's very inefficient. Write code to deal with all situations.
  2. Catch errors as specifically as possible, then decide if the error should be bubbled up or can it be dealt with via the logs. But catch the appropriate errors so they are logged.
  3. You can write to Unified Logging Service(ULS) logs but these are often not checked or hard to find issues you have thrown up in your code, so consider using a logging block such as Microsoft's Enterprise Logging blocks or Log4net. Ted Pattison suggests writing to ULS and he know his stuff so if you don't have another specified logging policy write to the ULS. And if you do have another logging method consider writing to the ULS anyway.
  4. There are a lot of logging applications for .NET, and most companies tend to have logging code ready for implementation on your SP 2010 project.
  5. I have seen a MS gold partner use tracing on all projects. So when an error occurs they turn on tracing and try replicate the issue in production environments. Far better to catch errors so you can get your issues resolved quickly and don't need to change config setting or leave tracing enabled on the live production boxes.
  6. A web part error can cause an entire page to throw an application error. However don't throw try catch blocks around all code, rather try catch the errors at more appropriate junctions such as at the service layer. Once again it really depends on the WP.
Summary: Avoid using errors for logic (pretty obvious). Log the errors to a distinct area (database, file system(xml files are pretty useful)) to identifying where and what the issue is. Catch specific errors -try not to catch general exceptions and if you do need to catch general exceptions make sure you have looked for more specific exceptions such nullrefobjectexceptions.

More Info:
MSDN SharePoint Logger - http://msdn.microsoft.com/en-us/library/ff798361.aspx
Writing to the ULS
Update: 5 Dec 2010 - Writing to ULS using SP2010 by Waldek Mastykarz
Update: 18 Jab 2011 - MSDN article on logging and debugging

The SharePoint Logger
using Microsoft.Practices.ServiceLocation;ILogger logger = SharePointServiceLocator.GetCurrent().GetInstance();
using Microsoft.Practices.SharePoint.Common.ServiceLocation;
using Microsoft.Practices.SharePoint.Common.Logging;
IServiceLocator serviceLocator = SharePointServiceLocator.GetCurrent();
ILogger logger = serviceLocator.GetInstance();
logger.TraceToDeveloper("Unexpected condition");

Update 14 Dec 2010 - ULS Viewer - Tool to view ULS log and filter data
Update 23 Dec 2010 - Tracing using CorrelationId

SharePoint 2010 using VS 2010 and Visual Source Safe 2005

Overview: Client is implementing SP 2010, they don't have TFS and the source control is Visual Source Safe (VSS) 2005.
Steps to integrate VS2010 into VSS 2005:
  • Install the VSS client on your development server/environment;
  • Open the VSS explorer and add the project (Subsequent developers need to locate the file and download a copy) and set the working directory if pulling the project;

  • Open VS2010, select Tools > Options > Source Control > Plug-in Selection > Change the source control to "Microsoft Visual SourceSafe";


  • I prefer to hold my solution file locally and pull my projects however a lot of architects prefer to keep the solution in Source Control. Open the solution in VS2010 and you should be ready to run.
  • Tip: If you projects won't deploy click on the project and look at the "Site Url", this gets cleared down. Enter you local development server url i.e. http://demo1.app.dev/

Thursday 24 June 2010

Inefficient Queries - SPMetal join issue

Problem: LINQ to SharePoint 2010 (SPMetal) is not querying 2 SharePoint lists, when using SPMetal on a visual web part. I am trying to JOIN 2 lists inside a web part. The Application error message is "The query uses unsupported elements, such as references to more than one list, or the projection of a complete entity by using EntityRef/EntitySet.".



Hypothesis: At the SharePoint conference in Vegas Oct 2009 I remember in 1 of the sessions that inefficient LINQ queries are blocked. This was a little vague but a good start noting the stack trace message "InvalidOperationException: The query uses unsupported elements, such as references to more than one list, or the projection of a complete entity by using EntityRef/EntitySet.]
Microsoft.SharePoint.Linq.Rules.QueryEfficiencyProcessor.Process(Expression e)"
.
Exception Details: System.InvalidOperationException: The query uses unsupported elements, such as references to more than one list, or the projection of a complete entity by using EntityRef/EntitySet.
Using LINQ I can query each of the lists.  Each list has a field of the same type that I am trying to join on. I was totally confused but realised it must be an issue with the efficiency/validity of the query. A simpler query worked so it looks like the CAML is not being correctly formed. I extracted the CAML using the DataContext Log method.
My choices are:
  1. To get and fix the CAML query and then run a CAML query manually in my code;
  2. Use LINQ to objects; or
  3. Perform 2 queries and link the data manually.
Resolution:
Reading a post on MSDN on 2 stage queries gave me a quick fix. By adding the ToList() method, the query works.
var empQuery = from bug in Bugs.ToList()
join emp in Employees on bug.AssignedTo equals emp.Title
select new
{ emp.Title,
Project = bug.Project
};

Explanation: ToList() method forces immediate query evaluation and returns the generic that contains the query result.  As described in the MSDN article above LINQ can't convert the LINQ to SharePoint into a CAML query so by using the ToList() method, the query is broken into 2 stages.  This will apply to queries that use JOINS, UNIONS, and various other LINQ operators as described in the MSDN Unsupported LINQ queries article.

Tip: Turn off Object Change Tracking if you are only reading data.

LINQ to SharePoint Posts on this Blog
Links:
Linq to SharePoint 2010 examples
Tip: CAML query for optimised speed settings, only bring back columns you will use querySearch.ViewFieldsOnly = true;
querySearch.IncludeMandatoryColumns = false;
Display the CAML that LINQ to SharePoint is running

Wednesday 23 June 2010

Connected Web Parts in SP2010

Good starting point for creating consumers & Provider web parts

Delete Web Parts from a page using the browser

Problem: A web part fails, is hidden and you can remove it using the edit mode on a SharePoint page.
Resolution: A custom crafted url will display a list of web parts and allow you to cleanup the page as required. Enter the domain plus http://url/_layouts/spcontnt.aspx?&url=page>

If the page with the problem had the url http://demo1.dev/myarea/printer.aspx
You would enter the url http://demo1.dev/_layouts/spcontnt.aspx?&url=myarea/printer.aspx
Alternatively Approach: Append ?content=1 to the url and you will be directed as above.
Example:
Page: http://www.demo.dev/sites/sponline/Pages/ViewProperty.aspx
Make it: http://www.demo.dev/sites/sponline/Pages/ViewProperty.aspx?contents=1
You get re-directed to: http://www.demo.dev/sites/sponline/_layouts/spcontnt.aspx?&url=%2fsites%2fsponline%2fPages%2fViewProperty.aspx

Tuesday 22 June 2010

XLV Web Part with filtering and customised UI (xslt)

Overview: Create a filterable view to display orders. 2 SharePoint lists: Product & Order and connected via a lookup column. Each product has an owner that we call the printer. We will use an Xslt List View (XLV) Web Part (WP) to display the multiple orders information. The UI will be customised using xslt and lastly a filter is needed to select the Printer/Owners. This will allow the Owner to see all their outstanding orders.
Steps:
1.> Create a new Site Page using the SharePoint 2010 site.

2.> Insert a SharePoint List Filter Web Part.

3.> Insert a XLV WP, this is created by SharePoint for any list/library that is create in SP2010. You will see the appropriate WP under the “List and Libraries” category when adding a WP to a page.


4.> Configure the SPListFilter to display the Owners/Printers.

5.> Setup the 2 WP to be connected WPs.


6.> Web page for ready for testing.

7.> Perform filtering using the Owner filter.

8.> Results Displayed

Thursday 17 June 2010

XLVWP - Filtering the xslt List View Web Part Series

Overview: Xslt List View (XLV) Web Part is widely used in SP 2010. This series of posts shows how to use this Web Part. Various connected web parts can be used to filter the XLVWP such as a List Filter Web Part.

Filtering: The filtering web parts provides a good way to filter data in the XLVWP. Using Connected Web Parts it is easy to filter the data you wish to retrieve. Below is the setup of 2 List View Web parts that are used to filter depending on the selected data.


Presentation: SPD 2010 provides a good tool for customising the presentation of the XLV WP. Additionally you can uncouple the default shared XSLT and provide your own customised xslt.

Also see:XSLT List View Web Part (XLV):