Showing posts with label Sharepoint. Show all posts
Showing posts with label Sharepoint. Show all posts

Monday, June 11, 2012

Accessing the SharePoint user profile service from BizTalk


I have a client scenario where weird 3rd party system 1, sends me an update of some information, from time to time, about a user, this information needs to be instantly replicated into SharePoint.

I could use BCS but it’s not instant…  It’s coming to me via BizTalk, so I have it in near real time, so 

I can update SharePoint can’t I??… well yes it seems you can…

There is the web service that SharePoint quite nicely exposes:

It has many methods one of these is: ModifyUserPropertyByAccountName

It’s a one way send in BizTalk. 

When you add a reference, you need to add a generated item, that consumes a WCF Service.

You will get 2 schema s an orchestration and a port binding, the schema s are useful, the orchestration you can choose to use it or not, it contains a bunch of multi-part message types,  and a massive port for every single method.

The port is useful, because it contains the operations, you will need to use when you create the port, so one port can have many operations to the same web service, they give you the binding for this port, which is very nice, I suggest you use it.

Here is where all the nice stuff ends, and the really interesting stuff begins. If you use this, it does not work. 

You may get:

Error details: System.ServiceModel.FaultException: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Server was unable to process request. ---&gt; Invalid String Value: Input must match string data type.</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>

This made no sense to me, as I was sending a string, and updating a string…..

If you look at the schema for the message:



value is defined as xs:anyType, which means you can put anything in here, which is correct, I want to, a string, a datetime, a int. So the schema is flexible…

The wsdl is very vague:

      <s:complexType name="ValueData">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Value" />
        </s:sequence>
      </s:complexType>

The value is does not specify xs:anytype however because it does not specify a type BizTalk interprets this, bad sharepoint.

However it does not go far enough… and hence it is a real let down when you have gotten past the authentication issue to find this. See my other post to fix this.

If you call the method from .net code, it works… however to find out why it works, you look at the xml that this call generates:

<ValueData>
   <Value xsi:type="xsd:dateTime">2012-06-25T10:01:17.486123+10:00</Value>   </ValueData>

The “value”  has an uppercase V, BizTalk puts is with a lower case V.  so that’s the first fix.

The next problem: xsi:type ??

It’s not even in the schema, it’s not in the wsdl.  I try and try and try to get it in to the schema, it’s not going to happen.

I managed to add an attribute to the value, called type, however it’s coming up as:

<ns0:Value ns0:type

Now the values are being set in SharePoint, all to NULL because it cannot interpret the type.

Now I know what I need to make the message look like, I have BizTalk pipelines… I can touch up the message before I send it to SharePoint.

So I go and touch up the message and the thing works perfectly. !!

I can now communicate from BizTalk to SharePoint, to update the user profiles.

My port looked like this:



Tuesday, May 8, 2012

Accessing an authenticated web service using BizTalk and impersonation


I need to access the SharePoint user profile service.

SharePoint quite nicely exposes:  http://{Server}/_vti_bin/userprofileservice.asmx

It is authenticated, quite rightly so, however the user I am accessing it with has permissions, however it still asks for username and password.

I was getting this error:

The adapter failed to transmit message going to send port "WcfSendPort_UserProfileServiceSoapOneWay" with URL "http://{Server}/_vti_bin/userprofileservice.asmx". It will be retransmitted after the retry interval specified for this Send Port. Details:"System.ServiceModel.FaultException: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Server was unable to process request. ---&gt; System.ServiceModel.EndpointNotFoundException</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>

Server was unable to process request. System.ServiceModel.EndpointNotFoundException

Not much help to me…

After some searching I found I needed to use impersonation.

The main reason was from .net I can simply do:
WSService.Credentials = System.Net.CredentialCache.DefaultCredentials;

Now the current user is impersonated and if they have permissions it works. GREAT.

I’m in BizTalk, and I’m on the WCF port…

The port is using wcf-basichttp as the protocol, and it should be able to just I have no idea how.

Well the solution I found is rather simple.

Use a wcf-custom port.  

Setup the basic-httpbinding.

First of all set the transport to client credential type ntlm 

 













Then flip over to Behavior

It will be blank.  Right click end point behavior: 






Select add extension.

Add client credentials and configure like so:















 After doing this my error went away.

Sunday, April 1, 2012

Publishing an InfoPath form to Sharepoint 2010 for WebBrowser

Publishing an InfoPath form to SharePoint 2010 is not that difficult, what is difficult is getting it published when it has code behind for the use in the Web Browser.

I recently battled with this, and I must say it’s better than it used to be, making InfoPath VERY powerful, particularly if you can use code behind, and even call your own .net dll’s from the form.

For most they have got somewhere, but have not got it fully working.. if you are one of these people read on. 

Do you want to activate it in the site collection, but can't upload it?

First you need to do this:

1. Open SharePoint 2010 Central Administration.
2. Click General Application Settings.
3. On the General Application Settings page under InfoPath Forms Services, click Upload form template.

You GET: ERROR: This form template has not been published. Open the form in the InfoPath Designer and publish the form to SharePoint using the Administrator-approved form template method in the Publishing Wizard.

Do the following:

Important: Ensure that the security and trust is set to full trust, with a certificate.

1. Publish the form to SharePoint from InfoPath.
2. Note down where you published it: http://msite/template.xsn
3. Go to your web browser and go to this URL, download the PUBLISHED template.xsn
4. SAVE IT locally.

OR

4a. Better way: Publish it to a network location say c:\MyFormTemplates, you do not need it in SharePoint YET.
5. Now upload the {template}.xsn, (Rename if you like) to SharePoint admin.

You should get: The form template has been successfully uploaded to the farm. To make the form template available in a site collection, activate the form template from the Manage Form Templates page or from the feature activation page in the site collection.

6. Now you can activate it in your site collection... etc...

Go to your site where you want to use the form.

Site settings / site collection administration

Site collection features

Look for your Infopath Form Template, (it's sorted alphabetically)

Press Activate



THE KEY to enabling the form for the browser is in how you set up your form library...

Under Site/{FormLibraryName}/form library settings/ advanced settings.

SAY Allow management of content types = YES

Then hit ok.

Now go down to content types, and defined your content type, say add from existing site content types, which you just activated... You do remember the NAME of the form you uploaded in admin before??

Make sure that it is the default content type, and everything will be good. 
Grant permissions to your users, and have them press new document, and up comes your form in the browser...

You can then put your workflow on the form library, or hook BizTalk up to the form Library, and you have full end to end Form and Workflow.