Thursday, August 11, 2011

SharePoint File Upload

For some little functionality, I wanted to do a file upload to a document library by some custom .NET only code:


ListsSoapClient client = new ListsSoapClient();
XElement result = client.GetListItems("{642DF480-74CB-4EDC-865C-CA009054998F}", null, null, null, null, null, null);
XNamespace rs = "urn:schemas-microsoft-com:rowset";
XNamespace z = "#RowsetSchema";
var data = result.Descendants(rs + "data").Descendants(z+"row");

CopySoapClient copyClient = new CopySoapClient();
FieldInformation[] fields;
byte[] output;
uint result2 = copyClient.GetItem(Uri.EscapeUriString("http://example.hostname/"+"Documents/Report.xls"), out fields, out output);

string destinationUrl = "http://example.hostname/Documents/Test.xls";
string[] destinationUrls = { Uri.EscapeUriString(destinationUrl) };
List<fieldinformation> fieldsList = new List<fieldinformation>();

CopyResult[] copyResults;

uint result3 = copyClient.CopyIntoItems("+", destinationUrls, fieldsList.ToArray(), output, out copyResults);
WebRequest request = WebRequest.Create(destinationUrl);
request.Method = "PUT";
request.Credentials = CredentialCache.DefaultCredentials;
// Write the contents of the local file to the request stream.
using (Stream stream = request.GetRequestStream())
{
//Load the content from local file to stream
stream.Write(output, 0, output.Length);
}
WebResponse response = request.GetResponse();
response.Close();

Friday, August 5, 2011

Tips while working with SharePoint projects in VS2010

  • Install the CSKDev tools
  • Use quick deploy on the project to test small changes in markup and code
  • Page layouts don't support Intellisense when double clicking the aspx (VS2010 opens the file in textmode). Right-click and use 'View Code' or 'View Markup' will open the file as a webpage, with fill Intellisense support.
  • To start with already filled page layouts based on the content type, use the CSKDev 'Create page layout' on the content type in the Server Explorer.

Thursday, August 4, 2011

Get Taxonomy terms from the user while configuring a WebPart

In my current SharePoint 2010 project we make use of Managed Metadata terms a lot. We want to be able to select taxonomy terms while configuring WebParts, but the setup of the taxonomy field isn't quite straightforward. For the configuration of WebParts with exotic controls, you need to implement a custom ToolPart and link it to your WebPart. Because I think we will create a lot of custom ToolParts, I created a base class for displaying these taxonomy fields.

   1:  /// <summary>
   2:  /// This class makes it easier to work with Taxonomy data in a <see cref="Microsoft.SharePoint.WebPartPages.ToolPart">ToolPart</see>
   3:  /// </summary>
   4:  public class TaxonomyToolPart : ToolPart
   5:  {
   6:      /// <summary>
   7:      /// Gets or sets the name of the term store.
   8:      /// </summary>
   9:      /// <value>
  10:      /// The name of the term store.
  11:      /// </value>
  12:      public string TermStoreName { get; protected set; }
  13:      /// <summary>
  14:      /// Gets or sets the name of the term group.
  15:      /// </summary>
  16:      /// <value>
  17:      /// The name of the term group.
  18:      /// </value>
  19:      public string TermGroupName { get; protected set; }
  20:      /// <summary>
  21:      /// Gets or sets the name of the term set.
  22:      /// </summary>
  23:      /// <value>
  24:      /// The name of the term set.
  25:      /// </value>
  26:      public string TermSetName { get; protected set; }
  27:      /// <summary>
  28:      /// Gets or sets a value indicating whether multiple terms can be selected.
  29:      /// </summary>
  30:      /// <value>
  31:      ///   <c>true</c> if multiple terms can be selected; otherwise, <c>false</c>.
  32:      /// </value>
  33:      public bool MultiSelect { get; protected set; }
  34:   
  35:      private TaxonomyWebTaggingControl TaxonomyControl { get; set; }
  36:   
  37:      /// <summary>
  38:      /// Called by the ASP.NET page framework to notify server controls that use composition-based 
  39:      /// implementation to create any child controls they contain in preparation for posting back or rendering.
  40:      /// </summary>
  41:      protected override void CreateChildControls()
  42:      {
  43:          // create a panel that will hold all of our controls 
  44:          Panel toolPartPanel = new Panel();
  45:   
  46:          // create the actual control 
  47:          SPContext context = SPContext.Current;
  48:          SPSite site = context.Site;
  49:          TaxonomySession session = new TaxonomySession(site);
  50:          TermStore termStore = session.TermStores[TermStoreName];
  51:          Group group = termStore.Groups[TermGroupName];
  52:          TermSet productsTermSet = group.TermSets[TermSetName];
  53:   
  54:   
  55:          TaxonomyControl = new TaxonomyWebTaggingControl();
  56:          TaxonomyControl.ID = "taxonomyControl";
  57:          TaxonomyControl.SspId.Add(termStore.Id);
  58:          TaxonomyControl.TermSetId.Add(productsTermSet.Id);
  59:          TaxonomyControl.IsAddTerms = false;
  60:          TaxonomyControl.AllowFillIn = true;
  61:          TaxonomyControl.IsMulti = MultiSelect;
  62:   
  63:          TaxonomyControl.Text = GetTextFromWebPart(this.ParentToolPane.SelectedWebPart);
  64:   
  65:          toolPartPanel.Controls.Add(TaxonomyControl);
  66:   
  67:          // finally add the panel to the controls collection of the tool part 
  68:          Controls.Add(toolPartPanel);
  69:   
  70:          base.CreateChildControls();
  71:      }
  72:   
  73:      /// <summary>
  74:      /// Gets the textual representation of the selected terms from the WebPart and sets it on the Taxonomy control.
  75:      /// </summary>
  76:      /// <param name="webPart">The web part.</param>
  77:      /// <returns>a value from the webpart to select in the TaxonomywebTaggingControl</returns>
  78:      /// <remarks>Override this method in your child class to link the webpart property with the taxonomy field.</remarks>
  79:      /// <example>the term string has a value like 'Term 1|db61b704-cf1d-490d-bfc3-4cbcd8d2f453;Term 2|66b5696d-94a2-4299-ae34-63d3072ca357</example>
  80:      protected virtual string GetTextFromWebPart(WebPart webPart) { return string.Empty; }
  81:   
  82:      /// <summary>
  83:      /// Sets the textual representation of the selected terms from the Taxonomy control to the WebPart.
  84:      /// </summary>
  85:      /// <param name="webPart">The parent web part.</param>
  86:      /// <param name="selectedTerms">The selected terms.</param>
  87:      /// <remarks>Override this method in yout child class to link the taxonomy filed with the webpart property</remarks>
  88:      /// <example>the term string has a value like 'Term 1|db61b704-cf1d-490d-bfc3-4cbcd8d2f453;Term 2|66b5696d-94a2-4299-ae34-63d3072ca357</example>
  89:      protected virtual void SetTextToWebPart(WebPart webPart, string selectedTerms) { }
  90:   
  91:      /// <summary>
  92:      /// Called when the user clicks the OK or the Apply button in the tool pane.
  93:      /// </summary>
  94:      public override void ApplyChanges()
  95:      {
  96:          WebPart webPart = this.ParentToolPane.SelectedWebPart;
  97:          SetTextToWebPart(webPart, TaxonomyControl.Text);
  98:      }
  99:  }

This base class can now be used in a new class, where the configuration of the ToolPart and the linking with the WebPart needs to be implemented:

   1:  public class TestToolPart : TaxonomyToolPart
   2:  {
   3:      public TestToolPart()
   4:      {
   5:          this.TermStoreName = "Managed Metadata";
   6:          this.TermGroupName = "NL";
   7:          this.TermSetName = "Brand";
   8:          this.MultiSelect = true;
   9:          this.Title = "Taxonomy Example";
  10:      }
  11:   
  12:     protected override string GetTextFromWebPart(Microsoft.SharePoint.WebPartPages.WebPart webPart)
  13:      {
  14:          return ((TestWebPart)webPart).Text;
  15:      }
  16:   
  17:      protected override void SetTextToWebPart(Microsoft.SharePoint.WebPartPages.WebPart webPart, string selectedTerms)
  18:      {
  19:          ((TestWebPart)webPart).Text = selectedTerms;
  20:      }
  21:  }        

The only thing you need to do is override the GetToolParts() in your WebPart to inject your custom ToolPart in the ToolPart array, and your ToolPart should work.