How to create a Microsoft SharePoint folder in a document library, by using WebClient in C#

 

If you want to create a folder in a document library, by using WebClient in C#, you can use the following code:

 

namespace Research
{
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
[TestClass]
public class RliResearch
{
[TestMethod]
public void CreateSharePointFolderInDocumentLibrary()
{
string folderToCreateUri = "https://1.1.1.1/sites/mysite/Shared%20Documents/FolderIWantToCreate";
using (var client = new WebClient())
{
client.Credentials = CredentialCache.DefaultCredentials;
client.UploadString(folderToCreateUri, "MKCOL", "");
}
}
}
}

Note: The folder you want to create the folder in, must exist. In other words: create subfolder hierarchy one at a time.

To create the folder hierarchy:

Shared Documents

     SubLevel1

             SubLevel2

 

namespace Research
{
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
[TestClass]
public class RliResearch
{
[TestMethod]
public void CreateSharePointFolderInDocumentLibrary()
{
string sublevel1 = "https://1.1.1.1/sites/mysite/Shared%20Documents/SubLevel1";
using (var client = new WebClient())
{
client.Credentials = CredentialCache.DefaultCredentials;
client.UploadString(sublevel1, "MKCOL", "");
}
string sublevel2 = "https://1.1.1.1/sites/mysite/Shared%20Documents/SubLevel1/SubLevel2";
using (var client = new WebClient())
{
client.Credentials = CredentialCache.DefaultCredentials;
client.UploadString(sublevel2, "MKCOL", "");
}
}
}
}

How to debug across eSpaces in Outsystems

 

1. Set a breakpoint in the producer espace.
2. Tell the producer espace to "Debug in Public Area"
3. Tell the consumer espace to "Debug in Public Area"
4. Set the Entry eSpace, on consumer, by going to Debugger -> Select Entry eSpace
5. Do actions that should cause the breakpoint to be hit.

 

http://www.outsystems.com/forums/discussion/9314/debugging-across-espaces-does-not-always-work/

How to send correct UTF8 JSON to a Web Api controller

When posting UTF8 JSON data with the WebClient.UploadString function, I was getting NULL as value for the parameter on the controller function, the simple fix:

 

using (var client = new WebClient()) { // Set the header so it knows we are sending JSON. client.Headers[HttpRequestHeader.ContentType] = "application/json"; client.Encoding = UTF8Encoding.UTF8; // …

string responseData = client.UploadString("http://localhost/service", utf8RequestData); // Deserialise the response into a object var outputDTO = JsonConvert.DeserializeObject<GenerateDocumentOutputDto>(responseData); }

Or you could change the ContentType:

 

client.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";

Combine base URL string with a relative path string in C#

One way of combining a base URL string with a relative path string in C#:

 

[TestMethod]
public void Combine_base_url_with_relative_path_test()
{
Char slash = '/';
// Make sure sharePointUrl does not end with a slash.
string sharePointUrl = "https://mySharePointServer/sites/mysites";
if (sharePointUrl.EndsWith(slash.ToString()))
{
sharePointUrl = sharePointUrl.TrimEnd(slash);
}
// Make sure templatesRelatviePath does not start with a slash.
string templatesRelatviePath = "Shared Document/SubFolder1/SubFolder2";
if (templatesRelatviePath.StartsWith(slash.ToString()))
{
templatesRelatviePath = templatesRelatviePath.TrimEnd(slash);
}
string templateAbsolutePath = string.Format("{0}{1}{2}", sharePointUrl, slash, templatesRelatviePath);
// Assert
Assert.AreEqual("https://mySharePointServer/sites/mysites/Shared Document/SubFolder1/SubFolder2", 
templateAbsolutePath);
}

image

POST multiple parameters to an ASP .NET Web Api REST service from a .NET 3.5 assembly, by using one dynamic JObject "options" parameter.

 

Client code in .NET 3.5

 

namespace WordMerge.EndToEndTests
{
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
using Newtonsoft.Json;
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Execute_a_post_request()
{
string url = "http://localhost:63544/api/document";
object result = string.Empty;
// Uses the System.Net.WebClient and not HttpClient, because .NET 2.0 must be supported.
using (var client = new WebClient())
{
// Set the header so it knows we are sending JSON.
client.Headers[HttpRequestHeader.ContentType] = "application/json";
// Create the one and only "options" parameter object.
var dto = new DocumentDto
{
TemplatePath = @"C:\Temp\Templates",
DestinationPath = @"C:\Temp\Destination",
Data = new string[] { "This", " is", " test", " input", " data." }
};
// Serialise the data we are sending in to JSON
string serialisedData = JsonConvert.SerializeObject(dto);
// Make the request
var response = client.UploadString(url, serialisedData);
// Deserialise the response into a GUID
result = JsonConvert.DeserializeObject(response);
}
Assert.AreEqual(@"Succesfully uploaded: This, is, test, input, data.", result.ToString());
}
}
public class DocumentDto
{
public string TemplatePath { get; set; }
public string DestinationPath { get; set; }
public string[] Data { get; set; }
}
}

Server code in .NET 4.5

 

 

namespace Service.api
{
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class DocumentController : ApiController
{
// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<controller>/5
public string Get(int id)
{
return "value";
}
// POST api/<controller>
public string Post([FromBody]JObject jsonData)
{
// Convert the dynamic JObject to a DocumentDto object.
DocumentDto dto = jsonData.ToObject<DocumentDto>();
// Use the given data to create the result.
string seperator = ",";
string data = string.Join(seperator, dto.Data.ToList<string>());
string result = string.Format("Succesfully uploaded: {0}", data);
return result;
}
// PUT api/<controller>/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
public class DocumentDto
{
public string TemplatePath { get; set; }
public string DestinationPath { get; set; }
public string[] Data { get; set; }
}
}

How to POST a string[] array to a ASP .NET Web Api REST service that uses JSON, from a .NET 2.0 assembly

In this post I will use a UnitTest project written in C# .NET 2.0 as client code.

And a ASP .NET Web Api project as Server (service).

 

Client code

Create a new UnitTest project and change target framework to .net 3.5.

Add nuget package JSON.NET.

 

 

 

 

namespace WordMerge.EndToEndTests
{
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
using Newtonsoft.Json;
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Execute_a_get_request()
{
string url = "http://localhost:63544/api/document";
string result = string.Empty;
// Uses the System.Net.WebClient and not HttpClient, because .NET 2.0 must be supported.
using (var client = new WebClient())
{
// Set the header so it knows we are requesting JSON.
client.Headers[HttpRequestHeader.ContentType] = "application/json";
result = client.DownloadString(url);
}
Assert.AreEqual(@"[""value1"",""value2""]", result);
}
[TestMethod]
public void Execute_a_post_request()
{
string url = "http://localhost:63544/api/document";
object result = string.Empty;
// Uses the System.Net.WebClient and not HttpClient, because .NET 2.0 must be supported.
using (var client = new WebClient())
{
// Set the header so it knows we are sending JSON.
client.Headers[HttpRequestHeader.ContentType] = "application/json";
string[] data = new string[] { "This", " is", " test", " input", " data." };
// Serialise the data we are sending in to JSON
string serialisedData = JsonConvert.SerializeObject(data);
// Make the request
var response = client.UploadString(url, serialisedData);
// Deserialise the response into a GUID
result = JsonConvert.DeserializeObject(response);
}
Assert.AreEqual(@"Succesfully uploaded: This, is, test, input, data.", result.ToString());
}
}
}

NuGet packages config

 

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net35" />
</packages>

Server (service) code

Create an empty ASP .NET Web API project in Microsoft Visual Studio 2013.

namespace Service.api
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class DocumentController : ApiController
{
// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<controller>/5
public string Get(int id)
{
return "value";
}
// POST api/<controller>
public string Post([FromBody]string[] values)
{
string seperator = ",";
string data = string.Join(seperator,values.ToList<string>());
string result = string.Format("Succesfully uploaded: {0}", data);
return result;
}
// PUT api/<controller>/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
}

Visual Studio Structure

image

NuGet packages config

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi" version="5.0.0-rc1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.0.0-rc1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.0.0-rc1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.0.0-rc1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
</packages>

How to use entities from an other eSpace in Outsystems

Lets assume you have two eSpaces:

  • eSpace_1
  • eSpace_2

Now you want to use entities created in eSpace_1 in eSpace_2, then follow the steps below:

 

Open eSpace_1 with Outsystems Service Studio en go to the Data tab:

 

image

 

Click on the entity you want to expose in this case the entity "Test" and change:

Public to Yes

Expose Read Only to No

 

image

 

Publish eSpace_1

 

image

 

Now open eSpace_2 and Add a reference to eSpace_1

 

image

 

Change Show In Use to Show All and check the entities you want to include in eSpace_2

 

image

Manually create a Word document by binding a custom xml document to a template Word document

This post describes how you can create a Microsoft Office Word (2007/2010/2013) document by merging a Word template and a custom xml document.

 

Note: This post uses Microsoft Office Word 2013, but the same applies to Microsoft Office Word 2007 and 2010.

 

 

Open Microsoft Office Word 2013 open the developer tab on the ribbon

clip_image001

 

 

If the developer tab is not visible, go to File > Options

clip_image002

 

Go to Customize Ribbon > Enable "Developer" tab

clip_image003

 

First insert some text, a table and an image to give the template some body.

Now insert a Plain Text Content Control

clip_image004

 

Click on Properties and enter as:

Title: "CustomerName"

Tag: "CustomerName"

clip_image005

 

Save the document to "C:\Temp\CustomerInfo.docx" and close Microsoft Office Word

clip_image006

 

Rename the file to "C:\Temp\CustomerInfo.zip"

clip_image007

 

 

Extract the file to "C:\Temp\CustomerInfo"

clip_image008

 

 

Add the folder "C:\Temp\CustomerInfo\customXml"

clip_image009

 

 

Create the files item1.xml and itemProps1.xml and the folder _rels in the folder "C:\Temp\CustomerInfo\customXml"

clip_image010

item1.xml

<root>

<customer>

<name>Customer 1</name>

</customer>

</root>

 

 

itemProps1.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<ds:datastoreItem ds:itemID="{8f93798d-1506-45f2-811e-70f72165a32d}" xmlns:ds="http://schemas.openxmlformats.org/officeDocument/2006/customXml" />

The itemID is just a GUID.

 

 

You can create a new GUID with Microsoft Visual Studio:

clip_image011

clip_image012

 

Create a file item1.xml.rels in the folder "C:\Temp\CustomerInfo\customXml\_rels"

<?xml version="1.0" encoding="utf-8"?>

<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">

<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps" Target="/customXml/itemProps1.xml" Id="Rb8d5386a2f8640f88dad1eff30868bcf" />

</Relationships>

The Id is just a GUID without "-".

Edit the file "C:\Temp\CustomerInfo\word\_rels\document.xml.rels"

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">

<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/>

<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>

<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>

<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>

<Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/glossaryDocument" Target="glossary/document.xml"/>

<Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.jpeg"/>

<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" Target="../customXml/item1.xml" Id="Rdfc14bfb0c244ab3" />

</Relationships>

The ID is a GUID without "-".

 

Edit the file "C:\Temp\CustomerInfo\word\document.xml"

Search for "CustomerName" in the file.

clip_image013

Add <w:dataBinding w:xpath="/root/customer[1]/name[1]" w:storeItemID="{8f93798d-1506-45f2-811e-70f72165a32d}" />

just after the <w:sdtPr> containing the CustomerName content control.

 

clip_image014

 

 

Edit the file "C:\Temp\CustomerInfo\[Content_Types].xml"

clip_image015

Now when you zip the contents of the folder "C:\Temp\CustomerInfo" and rename the zip to CustomerInfo2.docx, the CustomerName content control should be automatically filled with the text "Customer 1" from the item1.xml file.

When zipping make sure, you zip the contents of the folder en not the folder itself:

clip_image016

 

These manual steps can be automated by using the tool: http://dbe.codeplex.com/ (Word Content Control Toolkit)

This tool was created for Office 2007, but can be used for Office 2010 and Office 2013.