0

I'm having difficulty getting the base64 string version of an image in my C# console app from a rich text field on an object in Salesforce via the SOAP API. How can I get the base64 string of that image? The full problem description is below:

I have created a custom rich text field on the Account object so I can pull images from Salesforce and drop them into a Word document template. I am able to get the contents of the field via the SOAP API, but this is where I run into trouble. The contents of the field come back as an HTML string like below:

    test<img alt="alt" 
    src="https://c.na31.content.force.com/servlet/rtaImage?
    eid=...&amp;feoid=...&amp;refid=...">
    </img>test

In order to have the image render correctly on the document, however, I need to replace the src attribute it currently contains with a base64 string describing the image:

    test<img alt="alt" 
    src="data:image/jpeg;base64,/9j/4AAQSkZJ...">
    </img>test

I'm having trouble gaining access to that string via my C# console app. I've tried to use HttpWebRequest, HttpClient, and WebClient with various UserAgent, Authorization, and Cookie headers, navigating to the address supplied in the src attribute on the img tag. I've tried using access tokens from REST and session ids from SOAP as well.

The closest I've gotten to getting the base64 string is using a webbrowser object on another thread to navigate to the page and activate the save as dialog so I can manually save the page as an mht (which contains the base64 string for the image).

My latest attempt is listed below along with the response of the res variable from the StreamReader. Thanks in advance for the help!

    HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create("https://c.na31.content.force.com/servlet/rtaImage?eid=...&feoid=...&refid=...");
            try
            {
                webReq.CookieContainer = new CookieContainer();
                webReq.Method = "GET";
                webReq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
                webReq.Headers.Add("cookie", "sid=" + _session.Id);
                using (WebResponse response = webReq.GetResponse())
                {
                    using (Stream stream = response.GetResponseStream())
                    {
                        StreamReader reader = new StreamReader(stream);
                        var res = reader.ReadToEnd();

                    }
                }
            }
            catch (Exception ex)
            {

            }

res:

     "\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n    <meta HTTP-EQUIV=\"PRAGMA\" CONTENT=\"NO-CACHE\">\n\n\n\n\n\n<script>\nif (this.SfdcApp && this.SfdcApp.projectOneNavigator) { SfdcApp.projectOneNavigator.handleRedirect('https://login.salesforce.com/?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fc.na31.content.force.com%252Fservlet%252FrtaImage%253Feid%253D00137000002rwd4%2526feoid%253D00N37000006E9Gl%2526refid%253D0EM370000008hqK'); }  else \nif (window.location.replace){ \nwindow.location.replace('https://login.salesforce.com/?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fc.na31.content.force.com%252Fservlet%252FrtaImage%253Feid%253D00137000002rwd4%2526feoid%253D00N37000006E9Gl%2526refid%253D0EM370000008hqK');\n} else {;\nwindow.location.href ='https://login.salesforce.com/?ec=302&startURL=%2Fcontent%2Fsession%3Furl%3Dhttps%253A%252F%252Fc.na31.content.force.com%252Fservlet%252FrtaImage%253Feid%253D00137000002rwd4%2526feoid%253D00N37000006E9Gl%2526refid%253D0EM370000008hqK';\n} \n</script>\n\n</head>\n\n\n</html>\n\n\n\n\n\n<!-- Body events -->\n<script type=\"text/javascript\">function bodyOnLoad(){if(window.PreferenceBits){window.PreferenceBits.prototype.csrfToken=\"null\";};}function bodyOnBeforeUnload(){}function bodyOnFocus(){}function bodyOnUnload(){}</script>\n\t\t\t\n</body>\n</html>\n\n\n<!--\n...................................................................................................\n...................................................................................................\n...................................................................................................\n...................................................................................................\n-->\n"
  • 1
    Salesforce is not accepting your session ID. You'll probably need to use the REST API to get at the data. – sfdcfox Aug 29 '17 at 16:47
0

After doing some research, I found that I could use NReco.PhantomJS to build a headless browser and run javascript to pull the contents of the image in a base64 string. My code is below.

PhantomJS phantom = new PhantomJS();
String url = "https://" + regionServ + 
    ".salesforce.com/secur/frontdoor.jsp?sid=" + sessionId + "&retURL=%2Fservlet%2FrtaImage%3Feid%3D" + eid + "%26feoid%3D" + feoid + "%26refid%3D" + refid;
String[] jsArgs = { url };
String base64 = "";
var outFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DateTime.Now.Ticks.ToString() + ".txt");
using (var outFs = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write))
{
    try
    {
        phantom.RunScript(@"
    var system = require('system');
    var page = require('webpage').create();
    var args = system.args;
    page.viewportSize = {
        width: 1920,
        height: 1080
    };
    page.open(args[1], function() {
        setTimeout(function() {
            var base64 = page.evaluate(function() {
                var img = document.getElementsByTagName('img');
                var canvas = document.createElement('canvas');
                canvas.width = img[0].width;
                canvas.height = img[0].height;
                var ctx = canvas.getContext('2d');
                ctx.drawImage(img[0], 0, 0);
                var dataURL = canvas.toDataURL('image/png');
                return dataURL;
            });                
            system.stdout.writeLine(base64);
            phantom.exit();
        }, 5000);

    });", jsArgs, null, outFs);
    }
    finally
    {
        phantom.Abort();
    }

}
if (File.Exists(outFile))
{
    base64 = File.ReadAllText(outFile);
    File.Delete(outFile);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.