Contents tagged with SharePoint
In SharePoint, there are several web parts that allow us to have different contents depending on some conditions:
LoginView (ASP.NET): allows the definition of templates per authenticated or anonymous user;
SPSecurityTrimmedControl: displays contents based on the security permissions of the current user;
EditModePanel: for displaying contents in a web part page depending on its edit mode;
DataViewWebPart: allows the passing of parameters and the usage of XSL for rendering logic.
I imagine you are now rolling your eyes: DataViewWebPart? how come? Well, because it doesn’t need to point to a specific list or view (unlike XsltListViewWebPart), it is very useful for markup-based customizations that will only depend on parameters.
Let’s see an example:
You can use this technique for:
Including scripts and stylesheets;
Including server-side controls.
It’s just a matter of rolling out some XSL to the rescue!
You may be already familiar with the available parameters, but you can find the full list here: http://msdn.microsoft.com/en-us/library/office/ff630170(v=office.15).aspx.
Another SharePoint Designer-only solution that may come in handy! ;-)
Sometimes, when you are using a SPDataSource control to bind to some list control, you might need, inside of it, to fetch information from the item you are iterating over.
Imagine, for example, that you are displaying a list of sites. As usual with SharePoint, there are lots of options for doing this, but consider the SPDataSource approach, which doesn’t require any coding:
But now you want to display all lists of each subsite… What would you do then?
OK, we need to get, for each site listed, its id, and store it in some server-side control, such as HiddenField. Next, we add a nested SPDataSource, this time with DataSourceMode=ListOfLists, and add a WebID parameter:
If you are curious, the MSDN page SPDataSource.SelectParameters lists all predefined parameters that the SPDataSource will recognize automatically, and this page in Solutionizing .NET lists all fields returned by SPDataSource, in all of its modes. BTW, a great resource!
A common request is the ability to have one drop down list (the child) being filled after another one (the parent) has; this is usually called cascading drop down lists.
First, let’s create two lists: Parent and Child. Connect the Child to the Parent through a lookup field that points to the Parent’s ID field and call this lookup Parent. Add some records to it.
On SharePoint Designer create a new web part page. Find some space and add two DropDownList controls:
Next, add two SPDataSource controls:
Pay attention to a couple of things:
- I am using the standard ID and Title columns, but you can use whatever you want;
If you prefer to have the parent DropDownList initially unselected, use the following markup instead:
AppendDataBoundItems makes sure that any items added from a data source control are appended to any existing ones.
Of course, you can have any number of nested DropDownList controls, just follow the same logic.
SharePoint Designer 2013 workflows brought along new and quite welcome features. I will list my favorite ones.
First, the ability to define stages (blocks of instructions) and to jump (yes, goto-style!) between them. This permits a better organization of our code and because of conditional jumps, even includes the ability to reuse code and to loop between stages.
Next one is stage-level loops. We have two flavors: one where the loop count is predefined from an Integer variable and the other where a condition is used to determine its end.
Then we have a new type of variables, Dictionary, and three associated actions: build a dictionary with values, get an item from a dictionary and count the number of items in it. Each Dictionary item can be of a different type, and it is even possible to have items of type Dictionary. A Dictionary can be indexed by its key or by position, which is very useful to use inside loops.
It is now possible to start list and site workflows, but only SharePoint 2010 are supported. Workflows can be started synchronously, in which case, the originating workflow will wait for the result, or asynchronously, aka, fire and forget. Depending on the workflow selected, it may be necessary to specify values for its parameters.
Also new is the ability to assign tasks and start approval processes.
A perhaps not so used one is the capability to start a document translation process. The name is misleading, since it can also be used to translate list fields. The result translation is stored in another list.
Finally, we have the ability to call an HTTP web service. This will mostly used to call REST-style web services, but nothing prevents us from calling SOAP, since we can build a SOAP request using the string utility actions that the Designer offers. We can specify both request contents and headers, and retrieve the result, headers and HTTP status code. The problem is, SharePoint Designer workflows can only process results coming as JSON, not XML, but there are a number of translation web services that can be used to turn XML into JSON.
All in all, very useful additions!
SharePoint 2013 Designer workflows now has two new interesting options: the ability to call HTTP web services and the option to loop over some code a number of times. This, together with the new REST API, which supports querying lists and returning data in JSON, allows iterating through list items in a workflow, something that was not possible before.
In order to demonstrate this, let’s create a new Site Workflow in SharePoint Designer, that will iterate through the Tasks list:
Call it Process Tasks, for example, and make sure you select SharePoint 2013 as the platform type.
In the workflow designer, let’s start by creating a new stage, call it Retrieve Tasks:
In it, we add a new Set Workflow Variable action which creates a new String variable called url with the value “http://sp2013/_api/web/lists/getbytitle('Tasks')/items”. This uses the new REST API, and you can pass in additional options, such as for ordering by the DueDate field in descending order:
http://sp2013/_api/web/lists/getbytitle('Tasks')/items?$filter=DueDate gt DateTime’2014-07-31T00:00:00’
Next, we add a Dictionary variable (Build a Dictionary action), call it requestHeaders, and initialize it as this:
Both “Accept” and “Content-Type” entries are of the String type and they both contain the value “application/json;odata=verbose”, SharePoint REST API understands this and sets the response content type appropriately as JSON. If we don’t pass these values, the output would come as XML.
Following, add an Call an HTTP Web Service action and set its properties. The request will be the url variable:
Response content will go to a new variable called responseContent:
Response headers will go to a new variable called responseHeaders:
And the same goes for the response code (variable responseCode):
Then we set the request headers to be the requestHeaders variable we created just now, by clicking on the properties for the Call an HTTP Web Service action:
Now, create a new stage, call it Process Tasks, and, at the end of the initial stage, add a Go to Process Tasks action.
On the Process Tasks stage, add a Get an Item from a Dictionary action, set the item as d/results, the source variable reponseContent and the output to a new variable of type Dictionary called list. Then count items from this list variable using a Count Items in Dictionary action and store the result in a new Integer variable called count. This variable will tell us how many times we have to loop. Finally, create a new Integer variable called index and set it to 0 (Set Workflow Variable), this will be the loop index.
Next, add a loop (Loop n Times), call it Loop Task Items, and set the loop variable to count. Inside the loop, get value d/results([%Variable: index%]) using a Get an Item from a Dictionary action from responseContent and store it in a new Dictionary variable called item. Get some fields (Get an Item from a Dictionary) from the item variable, such as Title and DueDate (mind you, these will be task item fields) and store them in appropriate variables and do whatever you want with them, like logging its contents (Log). Time to increment the loop counter: add a Do Calculation action and in it increment the index variable into a new Integer variable called indexPlusOne. Then set the index variable to be the indexPlusOne (Set Workflow Variable). Finally, exit the loop and set the workflow status (Set Workflow Status action) to Finished. At the end of the stage, select Go to End of Workflow.
That’s it. Your workflow should look like this:
The new functionality makes SharePoint Designer workflows much more powerful than before. I will continue to talk about it in the following posts.
This post is in portuguese only, sorry!
There are numerous pages that show how to do this with PowerShell, but I found none on how to do it with plain old C#, so here it goes!
To abbreviate, I wanted to have SharePoint suggest the site collection user’s names after the first letters are filled in a search site’s search box. Here’s how I did it:
You may do this, for example, on a feature. Of course, feel free to change users for something else, all suggestions are treated as pure text.
Following my last post, I decided to publish the whole set of expression builders that I use with SharePoint. For all who don’t know about expression builders, they allow us to employ a declarative approach, so that we don’t have to write code for “gluing” things together, like getting a value from the query string, the page’s underlying SPListItem or the current SPContext and assigning it to a control’s property.
These expression builders are for some quite common scenarios, I use them quite often, and I hope you find them useful as well.
This expression builder allows us to specify an expression to be processed on the SPContext.Current property object. For example:
It is identical to having the following code:
Returns a property stored on the farm level:
Returns the value of a selected page’s list item field:
Does the same as:
Checks if the current user belongs to an audience:
Checks if the current user belongs to a group:
The equivalent C# code is:
Returns the value of a user profile property for the current user:
Where the same code in C# would be:
Returns a value passed on the query string:
Is equivalent to (no SharePoint code this time):
Returns the value of a property stored at the site level:
You can get the same result as:
OK, let’s move to the code. First, a common abstract base class, mainly for inheriting the conversion method:
Next, the code for each expression builder:
You probably know how to register them, but here it goes again: add this following snippet to your Web.config file, inside the configuration/system.web/compilation/expressionBuilders section:
I’ll leave it up to you to figure out the best way to deploy this to your server!
OK, back to two of my favorite topics, expression builders and SharePoint. This time I wanted to be able to retrieve a field value from the current page declaratively on the markup so that I can assign it to some control’s property, without the need for writing code. Of course, the most straight way to do it is through an expression builder.
Here’s the code:
It must be placed on the Global Assembly Cache or you will get a security-related exception. The other alternative is to change the trust level of your web application to full trust.
Here’s how to register it on Web.config:
And finally, here’s how to use it on an ASPX or ASCX file inside a publishing page:
I had a tough time trying to have SharePoint working perfectly on a Windows 7 development machine that was occasionally disconnected from the Active Directory (when I am home I must connect through a VPN). I mostly had problems with service applications such as User Profile, Managed Metadata, Business Connectivity Services and the like, and all I knew were cryptical messages such as “access denied” or “the service or application pool is not started”. I was sure that both the services and application pools were running under a domain account that had proper permissions on the SQL Server instance, and basically it was a fresh installation. Lots of people are having the same problem, apparently. After banging my head against the wall for several days, I remembered about farm (what I had) versus stand-alone (which I had never tried) installations. Bingo!
Here’s what I did: I dropped all SharePoint databases and logins and reinstalled SP from scratch, only this time not in farm mode, but as stand-alone. After the SharePoint Configuration Wizard started, I cancelled it and started the Management Shell. I created the configuration database manually by using the New-SPConfigurationDatabase cmdlet where I specified a local account – something that the Configuration Wizard wouldn’t allow me to do. Then I restarted the Configuration Wizard and everything began working perfectly! Yes, I got some pre-configured service applications and also some content which I didn’t need, but I realized it was possible to drop and recreate everything the way I wanted to. All services and application pools are now running under local accounts, which is fine for my development needs. Really, Microsoft…
I hope this will bring light to someone facing the same problems!