Monday, October 17, 2011

XSLT Rendering–SharePoint 2010 Web Parts

 

One of the main areas of investment when developing Web Parts is the user interface and the output of (X)HTML code. A Web Part needs to merge transparently into an existing page (Web Part Page or Wiki Page), adhering to the rich and user-friendly layout of the hosting site, which can be a public CMS solution. Nevertheless, the output of the Web Parts can be defined in its CreateChildControls method or, for Visual Web Parts, in the ASCX code of the corresponding visual control. However, you cannot always predict where the Web Part will be hosted; thus, you cannot provide a layout that will be appropriate for
every kind of output.

Of course, you can try to satisfy different layout requirements by just working with Cascading Style Sheets (CSS), but in general, there’s no one-size-fits-all solution. This is an issue that Microsoft had to face when developing SharePoint itself.

Consider how Web Parts such as the SearchCoreResults or the XsltListViewWebPart render their output, to name but a couple of
examples. These native Web Parts accept an XSLT transformation as one of their main parameters and apply that transformation to an XML document that represents the real content of their output.


Often, in real SharePoint solutions that target not only intranet/extranet sites but also public Internet scenarios, you will need to develop custom Web Parts that follow these same basic principles.


This technique is truly powerful because it lets you define a completely custom layout for Web Parts while still sharing common business logic and behavior, but it doesn’t impose any specific constraints about the (X)HTML code to output, so it’s often your best choice in realworld SharePoint Internet solutions.

Sunday, October 16, 2011

Passed Exam 70-667: TS: Microsoft SharePoint 2010, Configuring

 

Last week, I finally gave the 70-667 exam and passed with 750 marks. The exam was not as easy one would expect. The toughest part were multiple questions where you need to arrange the steps of configuration. I was knowing what all involve in configuration but arranging them in proper steps were bit hard.

So, here is my 1 cent advise on anyone who wants to sit this exam-

  • Go through Wiley Publishing - MCTS Microsoft® SharePoint® 2010 Configuration Study Guide. Follow each step on a test SharePoint Virtual machine
  • Use MeasureUp or other exams and make sure to go through the explanation

If you follow these thoroughly, I am pretty confident that you will be able to pass this exam..ALL the best.

Friday, September 30, 2011

Explanation - Microsoft.SharePoint.SPException: The security validation for this page is invalid.

 

SharePoint applies a security check whenever you change data through the Server Object Model during HTTP requests. In fact, by default, SharePoint web forms use a form digest control to enforce security. The form digest is a hidden field POSTed by SharePoint webforms and checked by the security infrastructure on the server. When you make changes to objects by using the Server Object Model during an HTTP GET request, this input field will be missing, so by default SharePoint will throw an exception that looks like this excerpt:


Microsoft.SharePoint.SPException: The security validation for this page is invalid.


Similarly, if you send an HTTP POST request with a missing or invalid form digest value, you will receive the same error. This behavior applies only during HTTP requests. Therefore, when you reference the Server Object Model in a class library or a batch tool that runs outside of the ASP.NET pipeline, the security check will not occur. In fact, the check process looks for the
HttpContext.Current variable; if it is null the digest validation will not occur.


With that in mind, if you are developing a webpage that will respond to HTTP GET requests, or a custom web form page that doesn’t inherit from the WebPartPage type and doesn’t use the Form Digest control, you will need to instruct SharePoint to skip the digest validation;otherwise, your code will not work.


To instruct SharePoint to skip the validation, set the Boolean AllowUnsafeUpdates property of the current SPSite or SPWeb to true.

Conversely, when you develop a custom ASPX page, and you want to exploit the security environment provided by SharePoint, you have a couple of choices: you can inherit from WebPartPage, or manually include a FormDigest control in your page.

In the first case you simply need to inherit from the Microsoft.SharePoint.WebPartPages.WebPartPage base class, which internally renders a FormDigest control. Then, in your code, you call the utility method SPUtility.ValidateFormDigest() to check the digest when you POST the page back to the server.

In the latter case you need to include the Microsoft.SharePoint.WebControls.FormDigest control in your page(s), and you still need to invoke the SPUtility.ValidateFormDigest() method to check the digest.

Saturday, August 06, 2011

Handling exception in SharePoint Client Object Model

 

If you use normal try … catch … finally blocks to handle exceptions in Client Object model, you will need to invoke the server via ExecuteQuery three times(one for each situation). This could lead to performance degradation as well as to a huge stress on the server side. Luckily the Client Object Model provides a class named ExceptionHandlingScope that is specifically defined to support such situations and avoid executing multiple queries against the server.

Refer sample from http://msdn.microsoft.com/en-us/library/ee534976.aspx



ClientContext clientContext = new ClientContext("http://MyServer/sites/MySiteCollection");            

ExceptionHandlingScope scope = new ExceptionHandlingScope(clientContext);

using (scope.StartScope())
{
using (scope.StartTry())
{
List oList = clientContext.Web.Lists.GetByTitle("My List");
oList.Description = "In Try Block";
oList.Update();
}

using (scope.StartCatch())
{
// Assume that if there's an exception, it can only be
// because there is no list with the specified title, so
// create the list.
ListCreationInformation listCreateInfo = new ListCreationInformation();
listCreateInfo.Title = "My List";
listCreateInfo.Description = "In Catch Block";
listCreateInfo.TemplateType = (int)ListTemplateType.Announcements;
List oList = clientContext.Web.Lists.Add(listCreateInfo);
}

using (scope.StartFinally())
{
List oList = clientContext.Web.Lists.GetByTitle("My List");
oList.EnableFolderCreation = true;
oList.Update();
}
}

clientContext.ExecuteQuery();




Explanation:



Under the cover, the ExceptionHandlingScope instance collects activities (internally called ClientAction) to execute on the server side for all the three situations (try, catch, finally). The server will begin executing the code inside the StartTry block, and then in case of failure, it will execute the code in the StartCatch. Whether or not exceptions occurred in the StartTry

block, it will finally execute the code in the StartFinally block. However, the request sent to the server is just one, as well as the response.

Wednesday, June 29, 2011

Read SharePoint 2010 List item using Web Service

 

This sample uses the GetList operation of the Lists.asmx service to retrieve the configuration of the target list to query. It then loads the items of the list by using the GetListItems operation,providing a default query over the default view of the list.

String targetListName = "News";
String baseUrl = "http://local/_vti_bin/";
Lists wsLists = new Lists();
wsLists.Url = baseUrl + "Lists.asmx";
wsLists.Credentials = System.Net.CredentialCache.DefaultCredentials;
XElement listMetadata = XElement.Load(new XmlNodeReader(wsLists.GetList(targetListName)));
Guid targetListId = new Guid(listMetadata.Attribute("ID").Value);
XmlNode listItemsXmlNode = wsLists.GetListItems( targetListId.ToString(), // ID of the target list
String.Empty, // ID of the view or String.Empty for default view
null, // CAML query or null
null, // ViewFields or null
"200", // RowLimit as a string
null, // Query options
null // ID of the web site or null for root website
);

XElement listItemsXml = XElement.Load(new XmlNodeReader(listItemsXmlNode));
var xmlItems = from x in listItemsXml.Descendants("{#RowsetSchema}row")
select x;
foreach (XElement xmlItem in xmlItems) {
Console.WriteLine("{0} - {1}",
xmlItem.Attribute("ows_ID").Value,
xmlItem.Attribute("ows_Title").Value);
}

 

Both of the operations we invoked (Lists.GetList and SiteData.GetListItems) return a result in the form of XML; in fact, we use classes of LINQ to XML to read and parse them. While working with SharePoint SOAP services, you will need to be accustomed to managing different kinds of results, because it is common for XML results to be presented in various ways (XmlNode, String, arrays of custom types, and so on).

Tuesday, June 21, 2011

Main OOTB Services Published by SharePoint 2010

 

Alerts.asmx

Allows listing and deleting alerts subscriptions for users.


Authentication.asmx

Provides an operation for logging on to a SharePoint site that uses FBA. The Login operation returns a cookie that should be used in all subsequent calls to other services.


Lists.asmx

Provides operations to work with lists, content-types, list items, and files. For example, this service offers operations to check-in and check-out a file in a document library, or to query list data using CAML queries.


SiteData.asmx

Allows reading sites, webs, lists, and items. SiteData.asmx targets external search engines willing to crawl contents of a SharePoint site.


Sites.asmx

Allows creating, deleting, reading, exporting, and importing of SharePoint websites.


Webs.asmx

Provides operations to manage content-types, site columns, and features of a SharePoint website


Search.asmx

A service that allows querying the search engine of SharePoint Server.

Tuesday, May 31, 2011

Sample–Using ECMAScript Client Object Model

 

Below is a sample application page which uses ECMAScript client object model to retrieve a List instance and show its Title property.

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>


<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ECMAScriptDemoPage.aspx.cs" Inherits="ECMAScriptDemo.Layouts.ECMAScriptDemoPage" DynamicMasterPageFile="~masterurl/default.master" %>

<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<SharePoint:ScriptLink ID="SPScriptLink" runat="server" LoadAfterUI="true" Localizable="false" Name="SP.js" />

<script language="javascript" type="text/javascript">
var clientContext;
var web;
var oContactsList;
function onQuerySucceeded(sender, args) {
alert('Title of the List: ' + this.oContactsList.get_title());
}

function onQueryFailed(sender, args) {
alert('Request failed ' + args.get_message() + '\n' + args.get_stackTrace());
}

function retrieveContacts() {


this.clientContext = new SP.ClientContext.get_current();
this.web = this.clientContext.get_web();
this.oContactsList = this.web.get_lists().getByTitle("News");
this.clientContext.load(this.oContactsList);
this.clientContext.executeQueryAsync(
Function.createDelegate(this, this.onQuerySucceeded),
Function.createDelegate(this, this.onQueryFailed));


}

</script>
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<input type="button" onclick="retrieveContacts()"
value="Click me to get the list!" />
</asp:Content>

<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
ECMAScript Object Model Demo Page
</asp:Content>

<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
ECMAScript Object Model Demo Page
</asp:Content>

Saturday, May 07, 2011

Retrieving SharePoint List data in blocks

 

To reduce the impact on the sever, you could use SPQuery object’s RowLimit property to get data from SharePoint list in blocks.

The below code shows how one could get data in block of 10s-

SPList list = web.Lists["News"];
SPQuery query = new SPQuery();
// Define the query
query.Query = "<Where><Contains><FieldRef Name=\"Title\" />
<Value Type=\"Text\">San</Value></Contains></Where>";


// Define the maximum number of results for each page (like a SELECT TOP)
query.RowLimit = 5;


do {
SPListItemCollection items = list.GetItems(query);
foreach (SPListItem item in items) {
}
// Set current position to make SPQuery able to set the start item of the next page
query.ListItemCollectionPosition = items.ListItemCollectionPosition;
} while (query.ListItemCollectionPosition != null);

The ListItemCollectionPosition property is of type SPListItemCollectionPosition. It offers a PagingInfo property of type String, which contains the following data:
Paged=TRUE&p_ID=10


The _ID is the unique identifier of the last item retrieved so that SharePoint can know the starting position of the next page.

Friday, April 29, 2011

Unexpected Behavior of LINQ to SharePoint

 

When using LINQ to SharePoint to query items in list folder and the folder path is invalid, the query seems to return item from all the folders recursively Sad smile

When using LINQ to SharePoint inside PageMethods, the code need to be run under elevated permissions Sad smile

Thursday, March 24, 2011

LINQ to SharePoint code under elevated permission

 

Use the following code to run your code under elevated permission…

string url = SPContext.Current.Site.Url;
HttpContext backupCtxt = HttpContext.Current;
try
{
    if (SPContext.Current != null) HttpContext.Current = null;
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        using (SPSite sc = new SPSite(url))
        {
            using (SPWeb web = sc.OpenWeb())
            {
                HttpRequest httpRequest = new HttpRequest("", web.Url, "");
                HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new System.IO.StringWriter()));
                using (MyDataContext dc = new MyDataContext(web.Url))
                {

                          // YOUR CODE
 
                }
            }
        }
    });
}
catch
{
    throw;
}
finally
{
    if (SPContext.Current == null)
        HttpContext.Current = backupCtxt;
}

The one thing to note is that as SPContext is recreated, you will not be able to refer this in YOUR CODE. Also, any function which is called from YOUR CODE should also not use SPContext object.