Friday 19 November 2010

SharePoint - How to get an SPUser Object based on a Person Field in a SharePoint List

I had a question today about how to determine the email address of the user who is mentioned in the "Responsible Field" of a SharePoint list. He was trying to develop an event receiver that would email a particular user if they were mentioned in that field. To this end, here is a tiny method I wrote to get an SPUser based on a Person field in a SharePoint list. The code has to first obtain a reference to the relevant SPField and then use the "GetFieldValue" method of the SPField to get the SPFieldUserValue. The SPFieldUserValue is really just an SPUser:

        /// 
        /// Gets the SP User object from a person field (e.g. the Modified By field) 
        /// so we can determine the email address or other details of that user.
        /// 
        /// e.g. the SPItem with the Person field obtained 
        /// from web.Lists[0].Items[0]         /// e.g. a person field e.g. "Modified By"
        public static SPUser GetSPUserFromPersonField(SPListItem listItem, string fieldName)
        {
            var personField = listItem.Fields[fieldName];
            return ((SPFieldUserValue)personField.GetFieldValue(listItem[fieldName].ToString())).User;
        }

DDK

Tuesday 16 November 2010

Exception when connecting WCF client to SAP WS-Reliable Messaging enabled web service - "Invalid WS-RM message. There are no WS-RM headers within SOAP message."

One of the SAP Business Process Management (SAP BPM) WSDLs consumed by a SharePoint web part was re-created by a member of our development team yesterday. My .NET client application then refused to operate with the new SAP SOAP endpoints and began to spit out the following error in the SOAP response (as captured by WireShark):

<SOAP-ENV:Envelope xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">Invalid WS-RM message. There are no WS-RM headers within SOAP message.</faultstring>
<faultactor>Server</faultactor>
<detail>
<yq1:com.sap.engine.services.wsrm.exceptions.ReliableMessagingException xmlns:yq1="http://sap-j2ee-engine/error">Invalid WS-RM message. There are no WS-RM headers within SOAP message.</yq1:com.sap.engine.services.wsrm.exceptions.ReliableMessagingException>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

WS-RM (WS-Reliable messaging) is a protocol that allows messages to be transferred reliably between nodes that implement this protocol in the presence of software component, system, or network failures.

MSDN has a brief mention of the potential problem here:
http://msdn.microsoft.com/en-us/library/ff710229.aspx
As described in the article:

"Both products also support WS-ReliableMessaging 1.0. However, the implementations are not interoperable. Do not use WS-ReliableMessaging 1.0 when exchanging messages between SAP and .NET Framework."
In fact, even though SAP and WCF both support WS-ReliableMessaging 1.0, you cannot use it - it will just give you an error like the above. You can either turn WS-RM off or use version 1.1 of WS-ReliableMessaging for your SAP to .NET WCF communications.

DDK