I was running some pdf reports with Google charts until recently, when suddenly Google charts won't appear. Rest of the report works fine. I was using razor view engine to run a template file that had the javascript to load google charts.
The template file has a initCharts()
function that is triggered by <body onload=initCharts()>
. This function loads Google charts as below:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
function initChart() {
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawCharts);
}
other functions to load various charts
This template file is then loaded by razor view engine as below:
public async Task<string> RenderToStringAsync(string viewName, object model, string logoUrl)
{
Dictionary<object, object> dictionary = new Dictionary<object, object>();
dictionary.Add("LogoUrl", logoUrl);
var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider, Items = dictionary };
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
using (var sw = new StringWriter())
{
var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);
if (viewResult.View == null)
{
throw new ArgumentNullException($"{viewName} does not match any available view");
}
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = model
};
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
sw,
new HtmlHelperOptions()
);
await viewResult.View.RenderAsync(viewContext);
return sw.ToString();
}
}
The output of the razorview engine (from RenderToStringAsync
function) is given to DinkToPdf library to convert to pdf.
The problem I have is, when google.charts.load
line executes, it fails or before it could load the javascript the razorview returns html. The javascript is not executed in razorview hence the charts do not get rendered. But if I copy the output to a HTML file and open that with a browser the charts work as expected. The javascript doesn't seem to get executed inside razorview engine after the google.charts.load
line.
Is there anyway I can see the result of executing javascript in razorview engine? Can I see the errors if there are any? Can I load a third-party script like google and execute it in razorview engine?
I have spent quite a lot of time to no avail. Your help will be much appreciated!
The problem was resolved by replacing DinkToPdf with PhantomJS to create PDFs. DinkToPdf fails to load Google charts. This may have been caused by Google redirecting requests to jsapi to their newer loader.js, which DinkToPdf could not handle for some reason.
Running wkhtmltopdf, which DinkToPdf uses, on commandline showed some errors when accessing https as below:
QSslSocket: cannot resolve CRYPTO_num_locks ] 10%
QSslSocket: cannot resolve CRYPTO_set_id_callback
QSslSocket: cannot resolve CRYPTO_set_locking_callback
QSslSocket: cannot resolve sk_free
QSslSocket: cannot resolve sk_num
QSslSocket: cannot resolve sk_pop_free
QSslSocket: cannot resolve sk_value
QSslSocket: cannot resolve SSL_library_init
QSslSocket: cannot resolve SSL_load_error_strings
QSslSocket: cannot resolve SSLv3_client_method
QSslSocket: cannot resolve SSLv23_client_method
QSslSocket: cannot resolve SSLv3_server_method
QSslSocket: cannot resolve SSLv23_server_method
QSslSocket: cannot resolve X509_STORE_CTX_get_chain
QSslSocket: cannot resolve OPENSSL_add_all_algorithms_noconf
QSslSocket: cannot resolve OPENSSL_add_all_algorithms_conf
QSslSocket: cannot resolve SSLeay
QSslSocket: cannot call unresolved function CRYPTO_num_locks
QSslSocket: cannot call unresolved function CRYPTO_set_id_callback
QSslSocket: cannot call unresolved function CRYPTO_set_locking_callback
QSslSocket: cannot call unresolved function SSL_library_init
QSslSocket: cannot call unresolved function SSLv23_client_method
QSslSocket: cannot call unresolved function sk_num
QSslSocket: cannot call unresolved function SSLv23_client_method3%
QSslSocket: cannot call unresolved function SSL_library_init
Warning: Failed to load https://www.gstatic.com/charts/loader.js (ignore)
QSslSocket: cannot call unresolved function SSLv23_client_method
QSslSocket: cannot call unresolved function SSL_library_init
Since we could not resolve this issue, we decided to use PhantomJS and it works fine to create PDFs.