I have an ASP.NET web application in which I'm rendering different tableau dashboards from a site based on the menu clicked by the user. I have multiple menus and each menu was tied to a tableau URL.
Tableau Trusted Authentication has been implemented to get the trusted ticket from the tableau server. Once the ticket has been retrieved, I am appending the ticket to the dashboard URL along with the server name for each menu.
The trusted ticketing module is working fine and the visualizations are getting rendered in my web application. However, frequently I am getting a message of "Could not locate unexpired ticket" error.
On checking with this error, this is due to the ticket calls getting duplicated.
I reached out to the support regarding this and got a response that I can add client_ip during my trusted ticketing.
Tableau Trusted Ticket
I am not able to find any code article related to adding client_ip in trusted ticketing.
Below is my trusted ticket code.
public class TableauTicket
{
public string getTableauTicket(string tabserver, string sUsername)
{
try
{
ASCIIEncoding enc = new ASCIIEncoding();
string postData = string.Empty;
string resString = string.Empty;
postData = "username=" + sUsername + "";
// FEATURE 816 END - Custom Visualization - KV
if (postData != string.Empty)
{
byte[] data = enc.GetBytes(postData);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(tabserver + "/trusted");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
req.ContentLength = data.Length;
Stream outStream = req.GetRequestStream();
outStream.Write(data, 0, data.Length);
outStream.Close();
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader inStream = new StreamReader(stream: res.GetResponseStream(), encoding: enc);
resString = inStream.ReadToEnd();
inStream.Close();
return resString;
}
else
{
resString = "User not authorised";
return resString;
}
}
catch (Exception ex)
{
string resString = "User not authorised";
return resString;
string strTrailDesc = "Exception in tableau ticket - " + ex.Message;
}
}
public int Double(int i)
{
return i * 2;
}
}
Can anyone please let me know how the client_ip can be passed in trusted ticketing code?
Also, the client IP will get changed for each user and how this will be handled in the trusted ticketing?
UPDATE
I have solved the issue using the source code provided by tableau on how to embed the view in SharePoint.
Below is the code which may help users having the same issue.
string GetTableauTicket(string tabserver, string tabuser, ref string errMsg)
{
ASCIIEncoding enc = new ASCIIEncoding();
// the client_ip parameter isn't necessary to send in the POST unless you have
// wgserver.extended_trusted_ip_checking enabled (it's disabled by default)
string postData = "username=" + tabuser + "&client_ip=" + Page.Request.UserHostAddress;
byte[] data = enc.GetBytes(postData);
try
{
string http = _tabssl ? "https://" : "http://";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(http + tabserver + "/trusted");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = data.Length;
// Write the request
Stream outStream = req.GetRequestStream();
outStream.Write(data, 0, data.Length);
outStream.Close();
// Do the request to get the response
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader inStream = new StreamReader(res.GetResponseStream(), enc);
string resString = inStream.ReadToEnd();
inStream.Close();
return resString;
}
// if anything bad happens, copy the error string out and return a "-1" to indicate failure
catch (Exception ex)
{
errMsg = ex.ToString();
return "-1";
}
}
Assuming your code is working, (I have done this part in Java and not really an expert in asp.net) all you have to do is to add something like:
postData = postData +"&client_ip=" +<variable for client IP>;
The way it is handled on tableau server is :
you turn on wgserver.extended_trusted_ip_checking on Tableau server. see details here
Tableau will match the client IP you passed in the POST request 'client_ip=XXX.XXX.XXX.XXX' while obtaining the token, with the actual IP of the the machine where the browser is trying to access tableau server.
I have an http POST being actioned via a .NET System.Net.WebRequest as follows:
...
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has uri={0}, body={1}", uri, messageBodyAsString));
System.Net.WebRequest req = System.Net.WebRequest.Create(uri);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(messageBodyAsString);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
try
{
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return null;
System.IO.StreamReader sr =
new System.IO.StreamReader(resp.GetResponseStream());
string rs = sr.ReadToEnd().Trim();
sr.Close();
resp.Close();
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has string response = {0}", rs));
MongoDB.Bson.BsonDocument doc2 = new BsonDocument();
doc2.Add("Response", rs);
return doc2;
}
}
catch (System.Net.WebException e)
{...
This all works fine most of the time. However, looking at the log files that this creates I spotted something strange. The suspect log entries look like this:
18:59:17.0608 HPSHTTPPost PostToUri has uri=https://salesforce.ringlead.com/cgi-bin/2848/3/dedup.pl, body=LastName=Doe&FirstName=Jon
18:59:17.5608 HPSHTTPPost PostToUri has string response = Success
18:59:18.0295 HPSHTTPPost PostToUri has string response = Success
It seems that the Http Response is being received twice. Is this even technically possible? i.e. is it possible for an Http POST to receive two Responses, one after the other? If so, is my code below then liable to be called twice, thus resulting in the observed log file entries? Many thanks.
Edit:
In response to the comment that the logging code may be broken, here is the logging code:
public class Log
{
public static void WriteLog(string commandText)
{
string clientDBName = "test";
string username = "test";
try
{
string filePath = "c:\\Data\\XXXLogs\\" + clientDBName + "logs\\";
string filename = System.DateTime.Now.ToString("yyyyMMdd_") + username + ".log";
DirectoryInfo dir = new DirectoryInfo(filePath);
if (!dir.Exists)
{
dir.Create();
}
System.IO.FileStream stream = new System.IO.FileStream(
filePath + filename
, System.IO.FileMode.Append); // Will create if not already exists
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine(); // Writes a line terminator, thus separating entries by 1 blank line
writer.WriteLine(System.DateTime.Now.ToString("HH:mm:ss.ffff") + " " + commandText);
writer.Flush();
stream.Close();
}
catch { }
}
}
There are currently 1205 resources (citations) in the SciTS Mendeley group. However, no matter how we call the “getDocuments” method of the API, we only get the first 1000 resources. Is there a specific parameter we need to pass to get the full list of resources? Or is there a way to make a subsequent call that gets data pages not returned by the first call?
string grantType = "client_credentials";
string applicationID = "id";
string clientsecret = "XXXXXXX";
string redirecturi = "*******";
string url = "https://api-oauth2.mendeley.com/oauth/token";
string view = "all";
string group_id = "f7c0e437-f68b-34df-83c7-2877147ba8f9";
HttpWebResponse response = null;
try
{
// Create the data to send
StringBuilder data = new StringBuilder();
data.Append("client_id=" + Uri.EscapeDataString(applicationID));
data.Append("&client_secret=" + Uri.EscapeDataString(clientsecret));
data.Append("&redirect_uri=" + Uri.EscapeDataString(redirecturi));
data.Append("&grant_type=" + Uri.EscapeDataString(grantType));
data.Append("&response_type=" + Uri.EscapeDataString("code"));
data.Append("&scope=" + Uri.EscapeDataString("all"));
byte[] byteArray = Encoding.UTF8.GetBytes(data.ToString());
// Setup the Request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
// Write data
Stream postStream = request.GetRequestStream();
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Send Request & Get Response
response = (HttpWebResponse)request.GetResponse();
string accessToken;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
// Get the Response Stream
string json = reader.ReadLine();
Console.WriteLine(json);
// Retrieve and Return the Access Token
JavaScriptSerializer ser = new JavaScriptSerializer();
Dictionary<string, object> x = (Dictionary<string, object>)ser.DeserializeObject(json);
accessToken = x["access_token"].ToString();
}
// Console.WriteLine("Access TOken"+ accessToken);
var apiUrl = "https://api-oauth2.mendeley.com/oapi/documents/groups/3556001/docs/?details=true&items=1250";
try
{
request = (HttpWebRequest)WebRequest.Create(apiUrl);
request.Method = "GET";
request.Headers.Add("Authorization", "Bearer " + accessToken);
request.Host = "api-oauth2.mendeley.com";
response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
// Get the Response Stream
string json = reader.ReadLine();
Console.WriteLine(json);
//need this to import documents
}
}
catch (WebException ex1)
{
Console.WriteLine("Access TOken exception" + ex1.Message);
}
}
catch (WebException e)
{
if (e.Response != null)
{
using (HttpWebResponse err = (HttpWebResponse)e.Response)
{
Console.WriteLine("The server returned '{0}' with the status code '{1} ({2:d})'.",
err.StatusDescription, err.StatusCode, err.StatusCode);
}
}
}
The default number of items returned is limited to 1000 per page. For a paginated response you should get some additional fields in the response; notably 'items_per_page','total_pages','total_results'.
I suspect you have will two pages and to get the next result you need to append 'page=1'.
I am using docusign rest api in my asp.net mvc application. I uploaded a .docx file to docusign. After signing, i am downloading this file . It gets downloaded as .docx file itself. But not able to open it. When I open the same file with adobe reader, it can be opened as pdf file. Can anyone help me to download the signed document as pdf so that i can open it easily?
static string email = "****"; // your account email
static string password = "****"; // your account password
static string integratorKey = "******";
static string recipientName = "***";
static string documentName = "test1.docx";
static string baseURL = "";
public void UploadtoDocuSign(int DocId, string DocName, int ObjectTypeId, int ObjectId)
{
try
{
User _dealuser = _imanageVacancy.GetDealById(ObjectId).LeadUser;
string recipientName = _dealuser.FirstName + " " + _dealuser.LastName; // provide a recipient (signer's) name
string documentName = DocName;
string recipientEmail = _dealuser.EmailAddress;
string sectionname = "";
DocumentManager _docmanager = GetDocumentById(DocId);
if (_docmanager.SectionID != null)
sectionname = "\\" + GetSectionName_additionalDoc((int)_docmanager.SectionID);
string FileNameWithPath = CommonFunctions.ConfigReader.GetConfigValue("appSettings", "FileUploadPath") + "\\Documents\\" + EnumsNeeded.VacancySubMenu.Deal.ToString() + "\\" + ObjectId + sectionname + "\\" + documentName;
//============================================================================
// STEP 1 - Login API Call (used to retrieve your baseUrl)
//============================================================================
// Endpoint for Login api call (in demo environment):
string url = "https://demo.docusign.net/restapi/v2/login_information";
// set request url, method, and headers. No body needed for login api call
HttpWebRequest request = initializeRequest(url, "GET", null, email, password);
// read the http response
string response = getResponseBody(request);
// parse baseUrl from response body
baseURL = parseDataFromResponse(response, "baseUrl");
//============================================================================
// STEP 2 - Send Signature Request from Template
//============================================================================
/*
This is the only DocuSign API call that requires a "multipart/form-data" content type. We will be
constructing a request body in the following format (each newline is a CRLF):
--AAA
Content-Type: application/xml
Content-Disposition: form-data
<XML BODY GOES HERE>
--AAA
Content-Type:application/pdf
Content-Disposition: file; filename="document.pdf"; documentid=1
<DOCUMENT BYTES GO HERE>
--AAA--
*/
// append "/envelopes" to baseURL and use for signature request api call
url = baseURL + "/envelopes";
// construct an outgoing XML formatted request body (JSON also accepted)
// .. following body adds one signer and places a signature tab 100 pixels to the right
// and 100 pixels down from the top left corner of the document you supply
string xmlBody =
"<envelopeDefinition xmlns=\"http://www.docusign.com/restapi\">" +
"<emailSubject>DocuSign API - Signature Request on Document</emailSubject>" +
"<status>sent</status>" + // "sent" to send immediately, "created" to save as draft in your account
// add document(s)
"<documents>" +
"<document>" +
"<documentId>1</documentId>" +
"<name>" + documentName + "</name>" +
"</document>" +
"</documents>" +
// add recipient(s)
"<recipients>" +
"<signers>" +
"<signer>" +
"<recipientId>1</recipientId>" +
"<email>" + recipientEmail + "</email>" +
"<name>" + recipientName + "</name>" +
"<tabs>" +
"<signHereTabs>" +
"<signHere>" +
"<xPosition>100</xPosition>" + // default unit is pixels
"<yPosition>100</yPosition>" + // default unit is pixels
"<documentId>1</documentId>" +
"<pageNumber>4</pageNumber>" +
"</signHere>" +
"</signHereTabs>" +
"</tabs>" +
"</signer>" +
"</signers>" +
"</recipients>" +
"</envelopeDefinition>";
// set request url, method, headers. Don't set the body yet, we'll set that separelty after
// we read the document bytes and configure the rest of the multipart/form-data request
request = initializeRequest(url, "POST", null, email, password);
// some extra config for this api call
configureMultiPartFormDataRequest(request, xmlBody, documentName, FileNameWithPath);
// read the http response
response = getResponseBody(request);
string envelopeId = parseDataFromResponse(response, "envelopeId");
_docmanager.DocuSignReferenceId = envelopeId;
_docmanager.DocuSignStatus = "Sent";
_iDocRep.Update(_docmanager);
_unitOfWork.Commit();
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
{
string text = new StreamReader(data).ReadToEnd();
}
}
}
}
public void DocuSignDownload()
{
try
{
//============================================================================
// STEP 1 - Login API Call (used to retrieve your baseUrl)
//============================================================================
// Endpoint for Login api call (in demo environment):
string url = "https://demo.docusign.net/restapi/v2/login_information";
// set request url, method, and headers. No body needed for login api call
HttpWebRequest request = initializeRequest(url, "GET", null, email, password);
// read the http response
string response = getResponseBody(request);
// parse baseUrl from response body
baseURL = parseDataFromResponse(response, "baseUrl");
//============================================================================
// STEP 2 - Get Statuses of a set of envelopes
//============================================================================
//*** This example gets statuses of all envelopes in your account going back 1 month...
int curr_month = System.DateTime.Now.Month;
int curr_day = System.DateTime.Now.Day;
int curr_year = System.DateTime.Now.Year;
if (curr_month != 1)
{
curr_month -= 1;
}
else
{ // special case for january
curr_month = 12;
curr_year -= 1;
}
// append "/envelopes?from_date=MONTH/DAY/YEAR" and use in get statuses api call
// we need to URL encode the slash (/) chars, whos URL encoding is: %2F
url = baseURL + "/envelopes?from_date=" + curr_month.ToString() + "%2F" + curr_day.ToString() + "%2F" + curr_year.ToString();
// set request url, method, and headers. No request body for this api call...
request = initializeRequest(url, "GET", null, email, password);
// read the http response
response = getResponseBody(request);
string ComplenvIds = CompletedenvelopeIds(response);
ComplenvIds = ComplenvIds.TrimEnd(',');
string[] envIds = ComplenvIds.Split(',');
foreach (var envid in envIds)
{
DocumentManager _doc = _iDocRep.Get(x => x.DocuSignReferenceId == envid);
if (_doc != null)
{
DownloadCompletedEnvelopes(envid, _doc);
_doc.DocuSignStatus = "Completed";
_iDocRep.Update(_doc);
_unitOfWork.Commit();
}
}
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
{
string text = new StreamReader(data).ReadToEnd();
}
}
}
}
public void DownloadCompletedEnvelopes(string envId, DocumentManager doc)
{
try
{
//============================================================================
// STEP 1 - Login API Call (used to retrieve your baseUrl)
//============================================================================
// Endpoint for Login api call (in demo environment):
string url = "https://demo.docusign.net/restapi/v2/login_information";
// set request url, method, and headers. No body needed for login api call
HttpWebRequest request = initializeRequest(url, "GET", null, email, password);
// read the http response
string response = getResponseBody(request);
// parse baseUrl from response body
baseURL = parseDataFromResponse(response, "baseUrl");
//============================================================================
// STEP 2 - Get Envelope Document(s) List and Info
//============================================================================
// append "/envelopes/{envelopeId}/documents" to to baseUrl and use for next endpoint
url = baseURL + "/envelopes/" + envId + "/documents";
//url = baseURL + "/envelopes/";
// set request url, method, body, and headers
request = initializeRequest(url, "GET", null, email, password);
// read the http response
response = getResponseBody(request);
// store each document name and uri locally, so that we can subsequently download each one
Dictionary<string, string> docsList = new Dictionary<string, string>();
string uri, name;
using (XmlReader reader = XmlReader.Create(new StringReader(response)))
{
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "envelopeDocument"))
{
XmlReader reader2 = reader.ReadSubtree();
uri = ""; name = "";
while (reader2.Read())
{
if ((reader2.NodeType == XmlNodeType.Element) && (reader2.Name == "name"))
{
name = reader2.ReadString();
}
if ((reader2.NodeType == XmlNodeType.Element) && (reader2.Name == "uri"))
{
uri = reader2.ReadString();
}
}// end while
docsList.Add(name, uri);
}
}
}
//============================================================================
// STEP 3 - Download the Document(s)
//============================================================================
//string envelopeID = "Some EnvelopeID";
//EnvelopePDF envPDF = apiService.RequestPDF(envelopeID);
foreach (KeyValuePair<string, string> kvp in docsList)
{
// append document uri to baseUrl and use to download each document(s)
url = baseURL + kvp.Value;
// set request url, method, body, and headers
request = initializeRequest(url, "GET", null, email, password);
request.Accept = "application/pdf"; // documents are converted to PDF in the DocuSign cloud
// read the response and store into a local file:
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
string sectionname = "";
if (doc.SectionID != null)
sectionname = "\\" + GetSectionName_additionalDoc((int)doc.SectionID);
using (MemoryStream ms = new MemoryStream())
using (FileStream outfile = new FileStream(CommonFunctions.ConfigReader.GetConfigValue("appSettings", "FileUploadPath") + "\\Documents\\" + EnumsNeeded.VacancySubMenu.Deal.ToString() + "\\" + doc.ObjectID + sectionname + "\\" + kvp.Key, FileMode.Create))
{
webResponse.GetResponseStream().CopyTo(ms);
if (ms.Length > int.MaxValue)
{
throw new NotSupportedException("Cannot write a file larger than 2GB.");
}
outfile.Write(ms.GetBuffer(), 0, (int)ms.Length);
}
}
Console.WriteLine("\nDone downloading document(s), check local directory.");
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
{
string text = new StreamReader(data).ReadToEnd();
}
}
}
}
//***********************************************************************************************
// --- HELPER FUNCTIONS ---
//***********************************************************************************************
public static HttpWebRequest initializeRequest(string url, string method, string body, string email, string password)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = method;
addRequestHeaders(request, email, password);
if (body != null)
addRequestBody(request, body);
return request;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
public static void addRequestHeaders(HttpWebRequest request, string email, string password)
{
// authentication header can be in JSON or XML format. XML used for this walkthrough:
string authenticateStr =
"<DocuSignCredentials>" +
"<Username>" + email + "</Username>" +
"<Password>" + password + "</Password>" +
"<IntegratorKey>" + integratorKey + "</IntegratorKey>" + // global (not passed)
"</DocuSignCredentials>";
request.Headers.Add("X-DocuSign-Authentication", authenticateStr);
request.Accept = "application/xml";
request.ContentType = "application/xml";
}
public static void addRequestBody(HttpWebRequest request, string requestBody)
{
// create byte array out of request body and add to the request object
byte[] body = System.Text.Encoding.UTF8.GetBytes(requestBody);
Stream dataStream = request.GetRequestStream();
dataStream.Write(body, 0, requestBody.Length);
dataStream.Close();
}
public static void configureMultiPartFormDataRequest(HttpWebRequest request, string xmlBody, string docName, string FileNameWithPath)
{
// overwrite the default content-type header and set a boundary marker
request.ContentType = "multipart/form-data; boundary=BOUNDARY";
// start building the multipart request body
string requestBodyStart = "\r\n\r\n--BOUNDARY\r\n" +
"Content-Type: application/xml\r\n" +
"Content-Disposition: form-data\r\n" +
"\r\n" +
xmlBody + "\r\n\r\n--BOUNDARY\r\n" + // our xml formatted envelopeDefinition
"Content-Type: application/pdf\r\n" +
"Content-Disposition: file; filename=\"" + docName + "\"; documentId=1\r\n" +
"\r\n";
string requestBodyEnd = "\r\n--BOUNDARY--\r\n\r\n";
// read contents of provided document into the request stream
FileStream fileStream = System.IO.File.OpenRead(FileNameWithPath);
// write the body of the request
byte[] bodyStart = System.Text.Encoding.UTF8.GetBytes(requestBodyStart.ToString());
byte[] bodyEnd = System.Text.Encoding.UTF8.GetBytes(requestBodyEnd.ToString());
Stream dataStream = request.GetRequestStream();
dataStream.Write(bodyStart, 0, requestBodyStart.ToString().Length);
// Read the file contents and write them to the request stream. We read in blocks of 4096 bytes
byte[] buf = new byte[4096];
int len;
while ((len = fileStream.Read(buf, 0, 4096)) > 0)
{
dataStream.Write(buf, 0, len);
}
dataStream.Write(bodyEnd, 0, requestBodyEnd.ToString().Length);
dataStream.Close();
}
public static string getResponseBody(HttpWebRequest request)
{
// read the response stream into a local string
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
string responseText = sr.ReadToEnd();
return responseText;
}
public static string parseDataFromResponse(string response, string searchToken)
{
// look for "searchToken" in the response body and parse its value
using (XmlReader reader = XmlReader.Create(new StringReader(response)))
{
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == searchToken))
return reader.ReadString();
}
}
return null;
}
public static string CompletedenvelopeIds(string response)
{
string compenvIds = "";
string envId = "";
// look for "searchToken" in the response body and parse its value
using (XmlReader reader = XmlReader.Create(new StringReader(response)))
{
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "envelopes"))
{
XmlReader reader2 = reader.ReadSubtree();
while (reader2.Read())
{
if ((reader2.NodeType == XmlNodeType.Element) && (reader2.Name == "envelope"))
{
XmlReader reader3 = reader2.ReadSubtree();
envId = "";
while (reader3.Read())
{
if ((reader3.NodeType == XmlNodeType.Element) && (reader3.Name == "envelopeId"))
{
envId = reader3.ReadString();
}
if ((reader3.NodeType == XmlNodeType.Element) && (reader3.Name == "status"))
{
if (reader3.ReadString() == "completed")
compenvIds = string.Concat(compenvIds, envId + ",");
}
if ((reader3.NodeType == XmlNodeType.Element) && (reader3.Name == "status"))
{
DateTime date = reader3.ReadContentAsDateTime();
}
}
}
}
}
}
}
return compenvIds;
}
public List<Lookup> LookupCache()
{
List<Lookup> _lookup = (List<Lookup>)HttpContext.Current.Cache["Lookup"];
if (HttpContext.Current.Cache["Lookup"] == null)
_lookup = _imanageUser.UpdateCache();
return _lookup;
}
string GetSectionName_additionalDoc(int SectionId)
{
List<Lookup> _lookup = LookupCache();
string _section = _lookup.Find(x => x.LookupType == (int)EnumsNeeded.EnumTypes.AdditionalDocumentTypes && x.LookupId == SectionId).LookupDesc;
return _section;
}
All files that come from DocuSign are going to be .PDF files.
Your documents will be saved as the name they were uploaded as (often contain the extension). So if you're writing the file with the name that it is stored in DocuSign by DocumentPDF->Name. I would do a .Replace and replace the extension with .pdf.
I am working with the paypal using express checkout to get a billing agreement id.
I was following this guide:
https://www.x.com/developers/paypal/documentation-tools/how-authorize-and-run-reference-transaction-express-checkout
In the first step when i do "SetExpressCheckout":
The following is the code
public string SetExpressCheckout(string Amount)
{
string returnURL = "http://localhost:50325/ReviewOrder.aspx" + "?amount=" + Amount + "&PAYMENTREQUEST_0_CURRENCYCODE=USD";
string cancelURL = returnURL.Replace("ReviewOrder", "ExpCheckOut");
string strCredentials = "USER=" + strUsername + "&PWD=" + strPassword + "&SIGNATURE=" + strSignature;
string strNVP = strCredentials;
strNVP += "&PAYMENTREQUEST_0_PAYMENTACTION=AUTHORIZATION&&PAYMENTREQUEST_0_AMT=25" + "&L_BILLINGTYPE0=MerchantInitiatedBilling" + "&RETURNURL=" + returnURL;
strNVP += "&CANCELURL=" + cancelURL;
strNVP += "&METHOD=SetExpressCheckout&VERSION=" + strAPIVersion + "&DESC=test EC payment" +"&NOSHIPPING=0" ;
//Create web request and web response objects, make sure you using the correct server (sandbox/live)
HttpWebRequest wrWebRequest = (HttpWebRequest)WebRequest.Create(strNVPSandboxServer);
//Set WebRequest Properties
wrWebRequest.Method = "POST";
// write the form values into the request message
StreamWriter requestWriter = new StreamWriter(wrWebRequest.GetRequestStream());
requestWriter.Write(strNVP);
requestWriter.Close();
// Get the response.
HttpWebResponse hwrWebResponse = (HttpWebResponse)wrWebRequest.GetResponse();
StreamReader responseReader = new StreamReader(wrWebRequest.GetResponse().GetResponseStream());
// and read the response
string responseData = responseReader.ReadToEnd();
responseReader.Close();
return responseData;
}
The response is:
TOKEN=EC-09082530FY878870B&
TIMESTAMP=2013-03-25T00:45:56Z&
CORRELATIONID=3d33037174d55&
ACK=SuccessWithWarning&
VERSION=86&
BUILD=5479129&
L_ERRORCODE0=11452&
L_SHORTMESSAGE0=Merchant not enabled for reference transactions&
L_LONGMESSAGE0=Merchant not enabled for reference transactions&
L_SEVERITYCODE0=Warning
How to to get a BillingAgreeentd in Step 3:
Code for step 3 is:
public string GetBillingAgreementID()
{
string returnURL = "http://localhost:50325/ReviewOrder.aspx" + "?amount=" + Amount + "¤cy=USD";
string cancelURL = returnURL.Replace("ReviewOrder", "ExpCheckOut");
string strCredentials = "USER=" + strUsername + "&PWD=" + strPassword + "&SIGNATURE=" + strSignature;
string strNVP = strCredentials;
strNVP += "&RETURNURL=" + returnURL;
strNVP += "&CANCELURL=" + cancelURL;
strNVP += "&METHOD=CreateBillingAgreement&VERSION=" + strAPIVersion + "&TOKEN=" + Session["Token"];
//Create web request and web response objects, make sure you using the correct server (sandbox/live)
HttpWebRequest wrWebRequest = (HttpWebRequest)WebRequest.Create(strNVPSandboxServer);
//Set WebRequest Properties
wrWebRequest.Method = "POST";
// write the form values into the request message
StreamWriter requestWriter = new StreamWriter(wrWebRequest.GetRequestStream());
requestWriter.Write(strNVP);
requestWriter.Close();
// Get the response.
HttpWebResponse hwrWebResponse = (HttpWebResponse)wrWebRequest.GetResponse();
StreamReader responseReader = new StreamReader(wrWebRequest.GetResponse().GetResponseStream());
// and read the response
string responseData = responseReader.ReadToEnd();
responseReader.Close();
return responseData;
}
Response is:
TIMESTAMP=2013-03-25T00:51:34Z&
CORRELATIONID=854e6beed1e82&
ACK=Failure&
VERSION=86&
BUILD=5479129&
L_ERRORCODE0=11455&
L_SHORTMESSAGE0=Buyer did not accept billing agreement&
L_LONGMESSAGE0=Buyer did not accept billing agreement&
L_SEVERITYCODE0=Error
How to get a BillingAgreemntId?
Is that because of "L_SHORTMESSAGE0=Merchant not enabled for reference transactions" this message from "SetExpressCheckout" am i not able to get BillingAgreementID?
Please help me on this. Thanks.
You would need to contact PayPal and request this to be enabled on the account, if this is for a live account. If you are needing it enabled on the sandbox, you would need to contact PayPal MTS and have this enabled on your sandbox account.