Wesley Bakker

Interesting things I encounter doing my job...

Sponsors

News

Wesley Bakker
motion10
Rivium Quadrant 151
2909 LC Capelle aan den IJssel
Region of Rotterdam
The Netherlands
Phone: +31 10 2351035

(feel free to chat with me)
 

Add to Technorati Favorites

Solving WmiApRpl and BITS errors with SharePoint 2013 on Windows Server 2012

I have been searching for a way to get rid of some performance counter errors (WmiApRpl and BITS) on my SharePoint 2013 installation for a while but couldn't find the answer. Today I decided to have a look with Process Monitor and finally found a solution.

The w3wp process tries to access to registry keys but does not have the permissions.

After granting the WSS_WPG group full control(you probable can get away with a little less) to the following registry keys, the errors went away.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BITS\Performance
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WmiApRpl\Performance

And that's it!

Cheers,

Wesley

SPItemEventReceiver Bug

Normally when you inherit a class, and override any of the methods, you call the base method, just to be sure you do not interfere with the inner workings of the class. There is a bug however in the SPItemEventReceiver class that always changes the Status to Continue, even if I decided it should stop and cancel. TMHI this is simply a bug. Especially since the SPEventReceiverStatus.Continue enum value is 0 and thus the default value.

SPItemEventReceiver

 

Conclusion

If you decide to Cancel the action do not call the base implementation.

SPItemEventReceiver2

 

Cheers,

Wes

WebDAV slow with “Automatically detect settings”

Just a short note to self. A lot of Microsoft applications use WebDAV.  If you encounter some very slow WebDAV performance, just disable the “Automatically detect settings” in IE.

Tools –> Internet options –> Connections –> LAN Settings

SNAGHTML19bf2a

Speeds up performance 10 times in my case.

Regards,

Wesley

Microsoft Certified Master SharePoint 2010

Yesterday I've received the news that I've successfully completed all four exams that come with the MCM program. This actually makes me an MCM as of now which is still somewhat unreal to me. I've had to spent three weeks away from home strugling through the massive amount of information. The lectures were awesome, and I really learned to know a lot of good SharePoint specialists.

I would like to thank all the other attendees, the teachers and Brett Geoffroy for getting me through these three weeks. If you ever get the chance to attend the MCM program, go for it. It is an awesome experience you will not likely ever forget, but... just be sure to:

  • read the prereads
  • keep focussed on the next(not the previous!) exam
  • read the prereads
  • arrive two days before the start, as you cannot use a jetlag when you are in class/studying from 8am till 11pm every single day for three weeks on end
  • read the prereads
  • rest well and do some physical exercises in the few moments you have, to digest the massive amount of information you receive every day
  • read the prereads
  • enjoy the whole experience!
  • did I mention to read the prereads?

Cheers,

Wesley

Posted: May 26 2011, 04:29 PM by webbes | with 5 comment(s)
Filed under: ,
Dynamics CRM 2011 and SharePoint 2010

Here’s just a life saving tip for all you SharePoint developers, thinking about integrating with Dynamics CRM 2011 through BCS.

The new CRM SDK is built with .NET Framework 4.0! SharePoint 2010 runs in 3.5! So you cannot use the new CRM 2011 SDK if you would like to create an External Content Type.

I do have some good new for you though. Stick to the CRM 4.0 SDK. As CRM 2011 is backward compatible, your code will run just fine when you use the “old” SDK to connect to the “new” CRM.

Get Datepart in SharePoint Designer Workflow

Yesterday someone asked me how to get the datepart (f.e. the year of a date) inside a SharePoint designer workflow. I thought it would be some default action in the "Utility Actions" group, but I thought wrong. There is no such pretty common action. This post however shows a simple technique to get datepart Year, Month and Day.

How to 

First you have to start by asigning a new workflow string variable to a date value, and make sure to select the ISO Formatted option for the return field as parameter. This will set the string variable to something like 2010-12-28 according to the ISO format(yyyy-mm-dd).

We can now use the Utility Actions for string variables to extract our Year, Month and Day.

Screenshot

Cheers,

Wes

Framed Office Web Apps SharePoint 2010

In a project I'm working on we wanted to use Office Web Apps in SP2010 to preview selected documents in the browser. To do so we've created a very simple web part that renders an I-Frame with the URL set to one of the Office Web Apps urls depending on the document extension. Unfortunately the X-Frame header, that is added by the Office Web Apps service, prevents Internet Explorer to render the documents in an I-Frame! To solve this we've create a very simple HttpModule that checks for the header and changes the value from "DENY" to "SAMEORIGIN". This post simply shows the code for such a module that enables previewing of documents with Office Web Apps inside an I-Frame

The code

/// <summary>
/// The XFrameOptionsModule loosens the x-frame policy from DENY to SAMEORIGIN
/// </summary>
public class XFrameOptionsModule : IHttpModule
{
    private const string XFrameOptionsHeaderName = "X-FRAME-OPTIONS";

    /// <summary>
    /// Initializes a new instance of the <see cref="XFrameOptionsModule"/> class.
    /// </summary>
    public XFrameOptionsModule()
    {
    }

    /// <summary>
    /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
    /// </summary>
    public void Dispose()
    {
    }

    /// <summary>
    /// Initializes a module and prepares it to handle requests.
    /// </summary>
    /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
    public void Init(HttpApplication context)
    {
        context.PreSendRequestHeaders += ChangeXFrameOptionsHeaderToSameOrigin;
    }

    /// <summary>
    /// Changes the X-Frame-Options "DENY" header to "SAMEORIGIN".
    /// </summary>
    /// <param name="sender">The HttpApplication that triggers the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void ChangeXFrameOptionsHeaderToSameOrigin(object sender, EventArgs e)
    {
        HttpApplication application = (HttpApplication)sender;            
        HttpResponse response = application.Response;
            
        string headerValue = response.Headers[XFrameOptionsHeaderName];
        if (headerValue != null && headerValue.Equals("DENY", StringComparison.OrdinalIgnoreCase))
        {
            response.Headers[XFrameOptionsHeaderName] = "SAMEORIGIN";
        }
    }
}

All you have to do now is to add this module to the web.config using a SPWebConfigModification inside a feature receiver.

Cheers,

Wes

Missing server reference in SharePoint 2010

Unfortunately the "missing server references" health rule in Central Admin Health Monitoring does not display the URL were these uninstalled web parts reside. So to get these pages you'll have to execute some SQL against the mentioned content database. Because this is something that tents to come back regularly on development machines I've created a little SQL script to speed up the process of finding the url's you'll need to delete the web parts.

-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.


USE 

DECLARE @className nvarchar = ''
DECLARE @assemblyName nvarchar = ''


SELECT DISTINCT pages.DirName + '/' + pages.LeafName + '?contents=1' as Page
FROM
	dbo.AllWebParts wp
	JOIN dbo.AllDocs pages on pages.SiteId = wp.tp_SiteId
						AND pages.Id = wp.tp_PageUrlID
WHERE
	wp.tp_Assembly like '%' + @assemblyName + '%' AND
	wp.tp_Class	 like '%' + @className + '%'

 

Cheers,

Wes

Amazing world we live in...

Did you ever noticed that there are a lot of articles(265,000 results) out there that talk about linearized / 'Fast Web View' pdf files? These articles talk about the purpose of it, or about software that is capable of creating these kind of PDF files.  As a SharePoint developer, I was really interested in testing this with SharePoint and Bit Rate Throttling so I started looking for a sample file. Some large(around 5mb) linearized pdf sample file.

According to the amount of articles you might think that this should be no problem at all. Well, gues again! Not a single one of the authors of these articles ever bothered to attach an example of a linearized file! None! 0 out of 265.000! (<=I did not check all of them. I gave up after 1.5 hours of searching)

Sigh... what an amazing world we live in. Stupid *&$^#!

Cheers,

Wes

WorkflowAction and the Secure Store

CallWebServiceWorkFlowActionI have been working on this custom workflow action which allows you to post data to another servicer. This can be used to send messages to a web service for example. One thing I really wanted to have in there is security. And with security I mean the Secure Store. It is however very difficult to use the Secure Store from inside a workflow action.

Impersonation

Although SharePoint actions are so called “impersonated” to the initiator of the user, the process really runs under its own account. Depending on how busy your server is, and the type of workflow is executed by the SPUserCodeHost, OWSTimer or W3WP process. And your code actually runs under the account of that process. The so called “impersonation” is for SharePoint actions only. This is accomplished by handing out the SPContext of the initiating step to the workflow.

Secure Store

Secure Store stores the credentials for users or groups and only while running under the user, or group account, can you get these credentials out of the secure store and that’s great of course, but that’s also where the trouble starts. We have no way of impersonating the actual initiator of the workflow and thus no way to get the credentials per user. One option would be to get a ticket in the Initialize method and use that ticket during the Execute method to retrieve the user credentials and yes this does work, most of the time. Because most of the time, the Initialize method will run inside the W3WP process which has a HttpContext which in turn has a WindowsIdentity we can use to impersonate. Unfortunately, if the server gets busy, the Initialize method might just as well run inside the OWSTimer process. Another problem with the ticketing system is that tickets are valid for a specified amount of time only. You should think in minutes instead of hours, but workflows well… they sometimes take a few days or weeks before they finally arrive at your workflow action.

private static ICredentials GetSecureStoreCredentials(string applicationId, SPServiceContext context) {
    string username = String.Empty;
    string password = String.Empty;

    ISecureStoreProvider provider = SecureStoreProviderFactory.Create();
    if (provider == null) {
        throw new InvalidOperationException("Unable to get an ISecureStoreProvider");
    }

    ISecureStoreServiceContext providerContext = provider as ISecureStoreServiceContext;
    providerContext.Context = context;

    using (var credentials = provider.GetCredentials(applicationId)) {
        foreach (var credential in credentials) {
            switch (credential.CredentialType) {
                case SecureStoreCredentialType.UserName:
                case SecureStoreCredentialType.WindowsUserName:
                    username = credential.Credential.ToClrString();
                    break;

                case SecureStoreCredentialType.Password:
                case SecureStoreCredentialType.WindowsPassword:
                    password = credential.Credential.ToClrString();
                    break;
            }
        }
    }

    return new NetworkCredential(username, password);
}

Sample code for retrieving network credentials from secure store

Careful

One thing I would really like to stress out is that you really should not store the credentials in workflow variables during Initiate. Workflows can get stored anywhere (depending on the implementation of the WorkflowPersistenceService) and probably not secure. The other problem is that these credentials might not be valid anymore by the time your custom action executes.

What’s the solution?

There simply is no solution. The only thing you can do is create a so called Application Account (=Group account used by all users) in Secure Store and add the service accounts of the SPUserCodeHost, OWSTimer and W3WP processes in there. Problem is that every workflow action with the same Secure Store ApplicationId has to use the same credentials.

Cheers,

Wes

More Posts Next page »