another technical blog...technically

Wednesday, July 30, 2014

Howto solve Workflow suspended with HTTP 401 and survive to a demo

Today... demo day...
Objectives:
  •     Show the customer what he/she is paying for
  •     Satisfy customer
  •     Sell change requests
  •     Earn project bonus
So, basically, let's take another demo roundtrip and let's test all the process.
Wow everything works fine, why don't we start the workflow?
Wow... Why execution failed?

RequestorId: dbaf8233-b7f4-cc8e-0000-000000000000. Details: An unhandled exception occurred during the execution of the workflow instance. Exception details: System.ApplicationException: HTTP 401 {"error":{"code":"-2147024891, System.UnauthorizedAccessException","message":{"lang":"en-US","value":"Access denied. You do not have permission to perform this action or access this resource."}}} {"Transfer-Encoding":["chunked"],"X-SharePointHealthScore":["2"],"SPRequestGuid":["dbaf8233-b7f4-cc8e-84d2-34863a603d9b"],"request-id":["dbaf8233-b7f4-cc8e-84d2-34863a603d9b"],"X-FRAME-OPTIONS":["SAMEORIGIN"],"MicrosoftSharePointTeamServices":["15.0.0.4551"],"X-Content-Type-Options":["nosniff"],"X-MS-InvokeApp":["1; RequireReadOnly"],"Cache-Control":["max-age=0, private"],"Date":["Fri, 25 Jul 2014 14:01:50 GMT"],"Server":["Microsoft-IIS\/8.0"],"WWW-Authenticate":["NTLM"],"X-AspNet-Version":["4.0.30319"],"X-Powered-By":["ASP.NET"]} at Microsoft.Activities.Hosting.Runtime.Subroutine.SubroutineChild.Execute(CodeActivityContext context) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)

Wow... Why my bonus it's flying away?
Don't worry about it, the solution it's simple, even if the situation is frustrating.
The problem can be solved using central admin, look for Refresh trusted security token services metadata feed and run it now. Then make an iisreset.
If you are a lazy one use this small PowerShell
Get-SPTimerJob "RefreshMetadataFeed" | Start-SPTimerJob
And now, let's go on with demo, and with the bonus :) .

Monday, July 21, 2014

Some small (personal) updates

Hi guys, just few words.
I really want to thank you for visiting this blog, i've received lots of views and it's very important for me.
Dear visitors, i'd really like to interact more with you, so feel free to comment, ask, whatever... don't be shy :-) .
I wanna to tell you i've prepared lot of drafts during this week, and i'm going to talk about:
  • SharePoint 2013: Device channel panel and web parts
  • SharePoint 2013: Device channel panel BUG (Yes i've found it and MS is currently working to solve that!)
  • SharePoint 2013: Device channel panel BUG mitigation (Yes i've found it!)
  • SharePoint 2013: Other velocity considerations about quering objects
  • SharePoint 2010: Workflow OnTaskCreated action issue!
  • Restricting page layout and content type on SharePoint pages list
  • Security groups informations extraction via Powershell
  • Azure farm creation... with a script
"Ok, that's fine, you told us you have these draft, why don't you publish them"
Dear friends, work projects are becoming really challenging, and, meantime, i'm getting SharePoint 2013 certified... friends say i'm SharePoint addicted :-p and my head is focused on vacancies :-p ....so be patient.
BTW, first exam passed: 70-480: Microsoft said i'm expert in CSS3, Javascript, HTML 5 and so on :), and right now i'm studying MVC... really intersting technology.
If you're interested in one of these posts, please let me know, so i will focus on writing following your interests.
Please use comments below ;-) .
Share:

Wednesday, July 9, 2014

SharePoint 2013 Workflows task permission workaround

Hi there, I'm Troy McClure, maybe you remind me for the wonderful tutorial Visual studio SharePoint 2013 workflow walktrough
/mode joke off
Everyone noticed users can view/edit tasks but this is not a customer wish 99/100 times.
Someone asked me how to change task permissions so only assigned user can watch/edit/whatever task item. Unfortunally you cannot do this using Visual Studio in the OOB way and you need to create a custom Visual Studio activity, definitely not a developer-friendly task. I sense you are smiling because you think i'm gonna deliver you a custom activity you can just plug'n'play right now.
Sorry but today i'm just gonna show you a porkaround (no it's not a misprint).
I'm talking about event receivers.
Someone is saying: i already tried to do a event receiver, but it's not possible to make it run on a workflow task list. The key it's simply to change the event receiver list template n. 171.
Now use this simple piece of code you can find in example 03.
I also created a little helper method which helps you to restrict permissions without any useless roundtrip.
public static void SetPermissions(SPListItem item, List readers, List editors)
{
    SPSecurity.RunWithElevatedPrivileges(() => {
        using (SPSite site = new SPSite(item.Web.Site.ID))
        {
            using (SPWeb web = site.OpenWeb(item.Web.ID))
            {
                item = web.GetListItem(item.Url);

                item.BreakRoleInheritance(false, true);

                if (readers != null)
                { 
                    foreach (SPUser u in readers)
                    {
                        item.RoleAssignments.Add(CreateRoleAssignment(item, u, SPRoleType.Reader));
                    }
                }

                if (editors != null)
                { 
                    foreach (SPUser u in editors)
                    {
                        item.RoleAssignments.Add(CreateRoleAssignment(item, u, SPRoleType.Editor));
                    }
                }
            }
        }
    });
}

private static SPRoleAssignment CreateRoleAssignment(SPListItem item, SPUser user, SPRoleType roleType)
{
    SPRoleAssignment roleAssignment = new SPRoleAssignment(user);
    SPWeb web = item.Web;
    roleAssignment.RoleDefinitionBindings.Add(web.RoleDefinitions.GetByType(roleType));
    return roleAssignment;
}
As you can see, now young Skywalker must use the force to discover other users tasks.


Anyway, you can download the source here, and yes this is the first post of the brand new post category tips'n'tricks.Enjoy.

Tuesday, July 1, 2014

Is FAST query a data retrieval silver bullet?

Yesterday, a customer asked me pros and cons of Search in SharePoint 2013 and how it can help with FASTer queries.
I already used it on another project and i was able to make some cross site collections and cross web applications queries using just one statement, so i told him about the benefits this can imply.
Then, the customer asked me also: "And what about cross lists queries? It's better to use CAML or FAST?"
"Ehm... uhm.. sorry i have another call on hold, i'll call you back later" was the answer.
/jokes mode off
Everybody knows there are many ways to query contents across multiple SharePoint lists and, that's clear, writing code is a "depends on" work, but i started asking myself if FAST query could rule them all and be the best query method also for a simple task like cross list query (which is the CAML query dark reign).
I compared pure LINQ queries, SPSiteDataQuery, CrossListQueryInfo and KeywordQuery on the same battlefield (cross lists query), so expects some strong assumptions (borrowed from the project business case i'm following right now):
  • 1 Content Type containing 10 columns;
  • 3 List instances containing the same number of items (which are randomly generated) and the same content type;
  • Query will select all content type fields;
  • Usage of SharePoint like a DB (wrong usage, but some customers seems to love this scenario anyway);
  • Whenever it's possible, use just one query to extract data using date range;
I compared queries execution times populating lists with 2.000, 5.000, 10.000, 20.000, 50.000, 100.000, 500.000, 1.000.000 random items and i queryed just 1 list, then all 3 lists.

If you want to test on your own, as usual, download the last source code and deploy example 2.
Please note you have to follow steps below to enable your farm to support query on many items per lists:
1.  Allow object model override in web application's resource throttling options (Central administration > Manage web applications > <Your web application> > General settings > Resource throttling)
This will avoid CAML query to explode

2.  Using powershell, raise search service application max row limit.
$searchApp = Get-SPEnterpriseSearchServiceApplication
$searchApp.MaxRowLimit = 10000
$searchApp.Update()
iisreset
This will avoid KeywordQuery to extract less results than expected.

After that you can use my web part to populate list instances, launch crawler (you have to launch crawlers everytime you add new items if you haven't enabled continous crawling).
Please launch full crawl from the web part UI  the first time you add items on lists since it's necessary to install also managed property on search service application.

This is your example 02 dashboard, really fine uh? For sure, i made it.
Yes, i know you are thinking a script or a console application would be the best option to make massive import process, but i preferred to use a webpart in order to create a dummy-proof test dashboard for this example.
And now, last but not least, the numbers:

Query on single list
List items Retrieved items LINQ SPSite DataQuery CrossList QueryInfo Keyword Query
2.000 60 44ms 31ms 1ms 236ms
5.000 140 77ms 68ms 2ms 415ms
10.000 270 144ms 117ms 6ms 749ms
20.000 550 283ms 247ms 18ms 1436ms
50.000 1.370 708ms 322ms 32ms 5220ms
100.000 2.740 1387ms 747ms 70ms 10579ms
500.000 N/A N/A N/A N/A N/A
1.000.000 N/A N/A N/A N/A N/A

 

Query on 3 lists 
Items per list Retrieved items LINQ SPSite DataQuery CrossList QueryInfo Keyword Query
2.000 180 115ms 84ms 3ms 375ms
5.000 420 225ms 206ms 8ms 1123ms
10.000 810 438ms 375ms 16ms 1736ms
20.000 1.650 824ms 776ms 47ms 4084ms
50.000 4.110 1953ms 941ms 103ms 15042ms
100.000 8.220 3980ms 2635ms 198ms 29487ms
500.000 N/A N/A N/A N/A N/A
1.000.000 N/A N/A N/A N/A N/A



Results
I haven't done any tests for 500.000 and 1.000.000 items per list, this is due to the KeywordQuery boundary of 10.000 max results rows and the execution time that must be under 60 seconds per query.
The data i'm showing you are the average queries execution times, i excluded the first query because it represents the warm up (and slowest) execution time.
Well, despite my hopes, KeywordQuery doesn't seem to be the silver bullet i was waiting for. This doesn't mean it isn't a good technology, on the contrary i think it comes with a lot of advantages, but, simply, in some old-fashioned scenarios, could be better to use the old-fashioned CrossListQueryInfo way.
Download the source code

Me, myself and I

My Photo
I'm just another IT guy sharing his knowledge with all of you out there.
Wanna know more?