Wednesday, February 29

BizTalk 2010 message submission with transport-level security to SharePoint 2010 forms library without the WSS adapter - Part 2

The Form submittal WCF service

In this post I will try to briefly explain the steps needed to create a WCF service to submit BizTalk messages into a SharePoint 2010 form library

The steps are basically as follows:
1. Create a WCF service
2. Add a service reference to the SharePoint Copy service

The SharePoint environment includes built-in Web services in the Windows SharePoint Services that can be used to work with areas of the SharePoint object model remotely. Each Web application Web service is installed in the _vti_bin directory, which maps to the following file system location:
%COMMONPROGRAMFILES%\Microsoft Shared\web server extensions\12\ISAPI

These services allow developers to manipulate information stored in SharePoint sites. Msdn lists these services on this link

The WCF service below calls one of these services, namely the Copy web service, using the CopyIntoItems operation to post xml data into a form library hosted within a SharePoint site. the URL for the service(s) is typically relative to the site you wish to manipulate. e.g. http://sharepointservername/sharepointsitename/_vti_bin.copy.asmx

Below is the cample code for a WCF service which uses a service reference to call the copy service for my sharePoint site (this is very basic first-draft code showing the main functionality of the service, derived and slightly modified from R Seroter's example in his post, which I referred to in part 1). This is not a tutorial on WCF services, so please read about WCF services to understand the service better.

The Copy web service expects a few parameters:
  • The source uri, 
  • the destination path (including the SharePoint site URL, the form library name, which is the name of the form library created in part 1 and the filename you wish to call the form document when it is displayed in SharePoint),
  • the xml file itself sent as bytes,
  • an array of SharePoint properties related to the submitted xml
  • and the user credentials of a user with permissions to create the form in the SharePoint site. In this case, I pass the credentials in directly via the ClientCredentials of the proxy. I added the credentials into the web.config file as keys in the Appsettings section and called them within the code. That way, they can be changed when needed if the permissions in SharePoint need to be changed

ISendToSharePointFormsService.cs

using
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
 namespace
{

 [SendToSharePointServiceContract(Namespace = http://mynamespace/biztalk.wcf.SendToSharePoint/v1.0)]
 public interface ISendToSharePointFormsService
 {
  [OperationContract]
  string SendXmldoc(string strFile, string fileName, string servertouse, string librarytouse);

  [OperationContract]
  string GetXmlToString(string strFile);

 }
}


 

SendToSharePointFormsService.svc.cs

using
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;
using System.Xml;
using System.Net;
using System.Configuration;

namespace SendToSharePoint
{
  public class SendToSharePointFormsService : ISendToSharePointFormsService
  {
    public SendToSharePointFormsService()
    {
    }

    public string SendXmldoc(string DocinStringForm, string fileName, string servertouse, string librarytouse)
    {
     //declare variables
      string siteRoot, docLibrary, uname, pwrd, domn;

      //read appsettings for vars needed for sending file to SP
      try
      {
        siteRoot = servertouse;
        docLibrary = librarytouse;
        uname = ConfigurationSettings.AppSettings["UsernameApprovals"].ToString();
        pwrd = ConfigurationSettings.AppSettings["PasswordApprovals"].ToString();
        domn = ConfigurationSettings.AppSettings["userdomain"].ToString();
      }
      catch (Exception apps)
      {
        return "Error reading configuration settings from app.config - " + apps.InnerException;
      }

      //send to library
      string finalresult = UploadXmlToSharePoint(DocinStringForm, siteRoot, docLibrary, fileName, uname, pwrd, domn);

      return finalresult;

    }

    #region Actual sender
    private string UploadXmlToSharePoint(string docToAdd, string siteRoot, string docLibrary, string fileName, string userName, string password, string domain)
    {

      //build full destination Url
      string destinationPath = siteRoot + "/" + docLibrary + "/" + fileName;

      //convert the xml string sent from BizTalk into a byte array
      byte[] fileIn = ConvertDocToBytes(docToAdd);

      //holds MOSS service response values
      SharePointSvc.CopyResult[] results;
     
      //required fieldinformation array
      SharePointSvc.FieldInformation fieldInfo = new SharePointSvc.FieldInformation();
      SharePointSvc.FieldInformation[] fieldInfoArray = { fieldInfo };

      //destination url (notice that it's an array, meaning //multiple sites COULD be targeted
      string[] destUri = { destinationPath };

      //create instance of web service proxy
      SharePointSvc.CopySoapClient copycl = new SharePointSvc.CopySoapClient();

      //pass valid credentials
      copycl.ClientCredentials.Windows.ClientCredential = new NetworkCredential(userName, password, domain);

      //copycl.ClientCredentials.Windows.AllowNtlm = true;
      //call primary operation; sourceUri, doesn't matter here

      copycl.CopyIntoItems("http://none", destUri, fieldInfoArray, fileIn, out results);
     
      //check for error and return final result
      if (results[0].ErrorMessage != null)
      {

        return "Error: " + results[0].ErrorMessage;
      }
      else
      {
        return "Success Sending File to SharePoint at " + System.DateTime.Now.ToString();
      }

  }

   #endregion 
 
 #region conversions
   
     //bytes
    public byte[] ConvertDocToBytes(string xmlString)
    {
     ASCIIEncoding encoding = new ASCIIEncoding();
     return encoding.GetBytes(xmlString);
    }
    
    #endregion
  }
}



Host the SendToSharePoinForms WCF service in IIS (I believe there are numerous posts on the Internet on the various methods of hosting a WCF service in IIS)

Go on to Part 3 - Posting the forms from inside a BizTalk orchestration

No comments:

Post a Comment