Activate the standard AX DocumentHandling service! |
From Visual Studio register the service from the WSDL URI and add the service reference to your project. Remember that we will need to change the server and port in our project when it's time to move our project reference to the production environment.
Now all you would need to do is find a RecId from the DocuRef entity. In the example below we can see a document associated with an Item Lot number:
Document Management is activated for multiple entities from Lots to Sales Invoices |
Pseudo code below. I have a paranoia with the Client object where we could leave connections open and therefore no garbage collection. Adapt the below to your requirements.:
using XXXProj.DocumentHandlingServiceReference;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections;
using System.Configuration;
using System.IO;
using System.Text;
/// <summary>
/// Download PDF Quality Certificate associated with lot '140801-033711'.
/// RecId 5637152126 (DEVELOPMENT environment)
/// </summary>
[TestMethod]
public void TestCertificate_GetPDF1()
{
// We have a doc associated with InventBatch, lot '140801-033711' - See table DocuRef
Int64 CERT_RECID1 = 5637152126;
DocumentFileDataContract docuContract = new DocumentFileDataContract();
// Create a client only for as long as we need to. Note the exception handling with client.
using (DocumentHandlingServiceClient client = new DocumentHandlingServiceClient())
{
try
{
// *NO* company context for Document Management
//CallContext context = this.setCompanyContext("CONT");
//Execute as another user, and he's called 'Bob'
RunAsBob(client.ClientCredentials);
// Set the AX AIF service endpoint.
client.Endpoint.Address = setAXEnvironment(client.Endpoint.Address);
// Obtain file, String format, encoded in base 64
docuContract = client.getFile(null, CERT_RECID1);
client.Close();
}
catch (System.ServiceModel.CommunicationException e)
{
client.Abort();
Assert.Fail(e.ToString());
}
catch (TimeoutException e)
{
client.Abort();
Assert.Fail(e.ToString());
}
catch (Exception e)
{
client.Abort();
Assert.Fail(e.ToString());
}
}
Assert.IsNotNull(docuContract);
Assert.IsTrue(docuContract.RecId > 0, "Document not found - " + CERT_RECID1.ToString());
Assert.IsNotNull(docuContract.Attachment, "Document is empty");
// Let's save the document in a temporary directory
string documentAttachment = docuContract.Attachment;
string file = "C:\\TEMP\\file.pdf";
byte[] ba = System.Convert.FromBase64String(documentAttachment);
System.IO.File.WriteAllBytes(file, ba);
}
Helper or shared methods:
using System.Configuration;
using System;
using System.ServiceModel;
/// <summary>
/// Execute as user 'Bob'. Data saved in app.config xml file.
/// </summary>
/// <param name="clientCredentials"></param>
protected static void RunAsBob(System.ServiceModel.Description.ClientCredentials clientCredentials)
{
clientCredentials.Windows.ClientCredential.Domain = ConfigurationManager.AppSettings["Domain"];
clientCredentials.Windows.ClientCredential.UserName = ConfigurationManager.AppSettings["UserName"];
clientCredentials.Windows.ClientCredential.Password = ConfigurationManager.AppSettings["Password"];
}
/// <summary>
/// Assign the environment's Host/Port. Are we testing DEVELOPMENT or PRODUCTION?
/// e.h.: srvax2012:8202
/// </summary>
/// <param name="address">client.EndpointAddress</param>
/// <returns></returns>
protected static System.ServiceModel.EndpointAddress setAXEnvironment(System.ServiceModel.EndpointAddress address)
{
var newUriBuilder = new UriBuilder(address.Uri);
newUriBuilder.Host = ConfigurationManager.AppSettings["NEW_ENDPOINT_HOST"];
newUriBuilder.Port = System.Int16.Parse(ConfigurationManager.AppSettings["NEW_ENDPOINT_PORT"]);
address = new EndpointAddress(newUriBuilder.Uri, address.Identity, address.Headers);
return address;
}
/// <summary>
/// Context - Select Company. DataAreaId: CONT/CONZ/TEST/DAT/...
/// </summary>
/// <param name="dataAreaId"></param>
/// <returns></returns>
private CustPackingSlipServiceReference.CallContext setCompanyContext(String dataAreaId)
{
CustPackingSlipServiceReference.CallContext context = new CustPackingSlipServiceReference.CallContext();
context.Company = dataAreaId;
context.MessageId = Guid.NewGuid().ToString();
return context;
}