ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.

Source: Microsoft - Learn About ASP.NET Web API (http://www.asp.net/web-api)

Service based architectures and centralized systems to generate documents help to build clean and structured software concepts. Creating documents by merging templates with data is a typical task for an HTTP service.

This tutorial shows how to create a very simple Web API that expects a template in the TX Text Control InternalUnicodeFormat and data bundled in a JSON (JavaScript Object Notation) object.

Merging documents using RESTful ASP.NET Web API's

Before we are walking through the steps that are required to create an ASP.NET Web API project with Visual Studio, the JSON data objects are explained.

The MailMergeRequestObject Helper Class

These helper classes simply keep the data that is encrypted as an JSON object and used for the data transportation. The class MailMergeRequestObject consists of the template in the internal TX Text Control format and data as an JSON object. The ResponseResults object, that comes back from the HTTP service, holds the resulting document as a byte array in the internal TX Text Control format.

/*------------------------------------------------------------------------
** module: TXTextControl.Cloud.Helper
** file: MailMergeRequestObject.cs
** description: This file contains the helper data containers
**----------------------------------------------------------------------*/
namespace TXTextControl.Cloud.Helper
{
// the request object that will be encrypted as JSON
public class MailMergeRequestObject
{
public string Data { get; set; }
public byte[] Template { get; set; }
public MailMergeRequestObject() { }
}
// the results contain only a byte[] with the document
public class ResponseResults
{
public byte[] Document { get; set; }
public ResponseResults() { }
}
}

The data is expected as a structured JSON object in the following form:

{
"orders":{
"order":[
{
"Id":"10",
"address":{
"street":"9774 Kings Drive",
"city":"Charlotte"
},
"phone":"123 898 2298",
"date":"05/12/2015",
"total":"1526.88",
"item":[
{
"name":"Thin-Jam Hex Nut 4",
"price":"337.22",
"qty":"1",
"itemtotal":"337.22"
},
{
"name":"ML Road Frame - Red, 58",
"price":"594.83",
"qty":"2",
"itemtotal":"1189.66"
}
]
},
{ ... }
]
}
}

Creating the Web API Project

  1. Open Visual Studio (in this tutorial, Visual Studio 2015 is used) and create a new ASP.NET Web Application. Select Web API as the project template and confirm with OK.

    Creating the Web API project
  2. Select the project in the Solution Explorer and choose Add Class... from the Project main menu. Name the class MailMergeRequestObject and add the following two helper classes to the newly created file:

    public class MailMergeRequestObject
    {
    public string Data { get; set; }
    public byte[] Template { get; set; }
    public MailMergeRequestObject() { }
    }
    public class ResponseResults
    {
    public byte[] Document { get; set; }
    public ResponseResults() { }
    }
  3. Select the project in the Solution Explorer and choose Add Reference... from the Project main menu. Browse for the assemblies TXTextControl.Server, TXDocumentServer.dll and TXTextControl.dll, select them and confirm with OK.

    Creating the Web API project
  4. In the Solution Explorer, right-click the Controllers folder and choose Controller... from the Add context menu. Select Web API 2 Controller - Empty and confirm with Add. Name the controller MergeController.

    Creating the Web API project
  5. Open the newly created MergeController.cs file and replace the code with the following implementation:

    /*-----------------------------------------------------------------
    ** Post method
    ** // POST api/merge?format=[PDF|PDFA|DOCX|DOC]
    **---------------------------------------------------------------*/
    public ResponseResults Post([FromBody]dynamic mailMergeRequestObject,
    [FromUri]string format)
    {
    // create a new ResponseResults object that contains the
    // resulting document as a byte[]
    ResponseResults results = new ResponseResults();
    // helper object of type 'MailMergeRequestObject' to extract the
    // JSON data (template and data)
    MailMergeRequestObject mmroJSONResult =
    (MailMergeRequestObject)JsonConvert.DeserializeObject(
    Convert.ToString(mailMergeRequestObject),
    typeof(MailMergeRequestObject));
    // create a new ServerTextControl
    using (TXTextControl.ServerTextControl tx =
    new TXTextControl.ServerTextControl())
    {
    tx.Create();
    // create a new MailMerge instance
    using (TXTextControl.DocumentServer.MailMerge mm =
    new TXTextControl.DocumentServer.MailMerge())
    {
    mm.TextComponent = tx;
    // load the template from the helper object
    mm.LoadTemplateFromMemory(mmroJSONResult.Template,
    TXTextControl.DocumentServer.FileFormat.InternalUnicodeFormat);
    // create a new DataSet and the given XML data into it
    DataSet ds = new DataSet();
    XmlDocument doc =
    JsonConvert.DeserializeXmlNode(mmroJSONResult.Data);
    XmlNodeReader reader = new XmlNodeReader(doc);
    ds.ReadXml(reader, XmlReadMode.Auto);
    // merge the template with the DataSet
    mm.Merge(ds.Tables[0]);
    byte[] data;
    BinaryStreamType streamType = BinaryStreamType.AdobePDF;
    // define the export format based on the given Uri parameter
    switch (format.ToUpper())
    {
    case "PDFA":
    streamType = BinaryStreamType.AdobePDFA; break;
    case "DOCX":
    streamType = BinaryStreamType.WordprocessingML; break;
    case "DOC":
    streamType = BinaryStreamType.MSWord; break;
    }
    // save the document and fill the 'ResponseResults' object
    mm.SaveDocumentToMemory(out data, streamType, null);
    results.Document = data;
    }
    }
    // return the 'ResponseResults' object
    return results;
    }

Calling the Web API

The above ASP.NET Web API can now be called on the following URL:

[...]/api/merge?format=PDF

The following demo project code shows how to read an XML data source and a template, package both into a JSON object in order to call the Web API using an HTTP Post request.

// create the helper object to pass the required parameters
// as a JSON object
MailMergeRequestObject requestObject = new MailMergeRequestObject();
// load the data as XML
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("sample_db.xml"));
// the Web API expects the data as a JSON object
// 'JsonConvert' converts the XML to the required JSON format
string jsonText = JsonConvert.SerializeXmlNode(doc);
// fill the helper object with the data and the template
requestObject.Data = jsonText;
requestObject.Template = System.IO.File.ReadAllBytes(
Server.MapPath("template.tx"));
// new helper object of type 'Results' that keeps
// the resulting document as a byte[]
Results results;
string sFormat = DropDownList1.SelectedValue;
// create a new WebClient object
using (var client = new WebClient())
{
// set the headers to send and accept JSON
client.Headers[HttpRequestHeader.ContentType] = "application/json";
client.Headers[HttpRequestHeader.Accept] = "application/json";
// upload the helper object as a JSON string
string result = client.UploadString(
"http://localhost:13012/api/Merge?format=" + sFormat,
"POST",
JsonConvert.SerializeObject(requestObject));
// deserialize and convert the returned JSON object
// to the helper object 'Results'
results = (Results)JsonConvert.DeserializeObject(result, typeof(Results));
}
// save the resulting document as a file
// and create a hyperlink that points to the new file
System.IO.File.WriteAllBytes(
Server.MapPath("results." + sFormat), results.Document);
Response.Write("Download generated document <a href=\"results." +
sFormat.ToLower() + "\">here</a> (results." +
sFormat.ToLower() + ").");
view raw index.aspx.cs hosted with ❤ by GitHub

Download the sample from GitHub and test it on your own.