PDFViewer: Rendering PDF document received from the REST service as Byte Array

Hi,

I am using Essentioal Studio 15.3.0.29

My web application is ASP.NET MVC application (.NET 4.5). It calls a remote Web Api 2 service with a DocumentID to retrieve a PDF document stored in the database at the back end.
The Web Api 2 service return a  Byte Array representing a PDF document.

I can stream this byte array directly to the browser window like this:

                byte[] statement = documents.GetDocument(DocumentID);
                Response.Clear();
                Response.Buffer = true;
                Response.AddHeader("Content-Length", statement.Length.ToString());
                Response.AddHeader("Content-Disposition", "inline; filename=statement.pdf");
                Response.AddHeader("Expires", "0");
                Response.AddHeader("Pragma", "cashe");
                Response.AddHeader("Cashe-Control", "private");
                Response.ContentType = "application/pdf";
                Response.BinaryWrite(statement);
                Response.Flush();
                return null;

but I would like to present it in the SyncFusion PdfViewer control. I will create a MVC controller in my web application that will handle calling the Web Api 2 service but I am struggling to complete the whole cycle.

I have tried the "Getting Started" example (see below) but still no luck. I have no clue when and how to call Load, what is the purpose of other methods?
I can see that the view is calling the ApiController, but again can't figure out how to load a Byte Array into the viewer.

I would appreciate if you can help me.

Regards

Bojan

  @(Html.EJ().PdfViewer("pdfviewer").ServiceUrl("../../api/PdfViewer")
            .PdfService(Syncfusion.JavaScript.PdfViewerEnums.PdfService.Local))

{
    public class PdfViewerController : ApiController
    {
        //Post action for processing the PDF documents.
        public object Load(Dictionary<string, string> jsonResult)
        {
            PdfViewerHelper helper = new PdfViewerHelper();
            if (jsonResult.ContainsKey("isInitialLoading"))
                helper.Load(HttpContext.Current.Server.MapPath("~/Data/HTTP Succinctly.pdf"));
            return JsonConvert.SerializeObject(helper.ProcessPdf(jsonResult));
        }
        //Post action for processing the PDF documents when uploading to the ejPdfviewer widget.
        public object FileUpload(Dictionary<string, string> jsonResult)
        {
            PdfViewerHelper helper = new PdfViewerHelper();
            if (jsonResult.ContainsKey("uploadedFile"))
            {
                var fileUrl = jsonResult["uploadedFile"];
                byte[] byteArray = Convert.FromBase64String(fileUrl);
                MemoryStream stream = new MemoryStream(byteArray);
                helper.Load(stream);
            }
            return JsonConvert.SerializeObject(helper.ProcessPdf(jsonResult));
        }

        //Post action for downloading the PDF documents from the ejPdfviewer widget.
        public object Download(Dictionary<string, string> jsonResult)
        {
            PdfViewerHelper helper = new PdfViewerHelper();
            return helper.GetDocumentData(jsonResult);
        }
    }
}







4 Replies

SA Sabari Anand Senthamarai Kannan Syncfusion Team November 16, 2017 10:06 AM UTC

Hi Bojan, 

Thank you for using Syncfusion products. 

After analyzing your query, we came to know that you are trying to load PDF document as byte array in the client side of the PDF viewer control. PDF viewer control supports loading the PDF document as file path(string) and base64 string. So we need to convert the byte array of the PDF document to base64 string then load the same in the client side of the PDF viewer control. We would require Web API controller to load the PDF document in the PDF viewer control and for further processing. Please find the UG documentation for the action methods of the web API controller of PDF viewer control in the following link for further details. 


We can also modify the name of the action methods using the serverActionSettings property of the PDF viewer control. 

However, we have created a sample to demonstrate the same. Please find the sample from the below location. 


Note: Please modify the above sample to refer your database in the web.config file for connection string of the database and in web API controller for the SQL query to retrieve the PDF document as byte array. 

In the above sample, we have provided a text box control to provide the DocumentID for the byte array stored in the database. When the View button is clicked, an AJAX request will be send to the Web API controller and retrieve the byte array from the database. The byte array will be converted into base64 string and loaded into the PDF viewer control using the load() API. 

Please let us know that the above sample meets your requirements. If not, please let us know further details about your requirements. It will be helpful for us to analyze further and assist you better. 

Regards, 
Sabari Anand 



BK Bojan Kuhar November 16, 2017 09:48 PM UTC

Hi,

I was hoping that I can pass base64 encoded string in the model from my MVC controller. The MVC controller knows how to call a Web Api 2 REST service. The view should not know anything about the service itself. Would it be possible to load PdfViewer from the @model? I don't want the view to do AJAX calls.
Something like below but ServiceURL becomes redundant and we load @model into the PdfViewer on page load.

@model string // where the string is "data:application/pdf;base64," + Convert.ToBase64String(byteArray)
@{
    ViewBag.Title = "PDF View";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
    <div class="span12">
        <div class="frame">
            <div class="control">
                @(Html.EJ().PdfViewer("pdfviewer").ServiceUrl("../../api/PdfViewer")
            .PdfService(Syncfusion.JavaScript.PdfViewerEnums.PdfService.Local))
            </div>
        </div>
    </div>
</div>

Regards

Bojan



BK Bojan Kuhar November 17, 2017 07:06 AM UTC

I am also having trouble using the example you have supplied in the original reply.

The method load throws exception:

 public object FileUpload(Dictionary<string, string> jsonResult)
        {
            PdfViewerHelper helper = new PdfViewerHelper();
            if (jsonResult.ContainsKey("uploadedFile"))
            {
                var fileurl = jsonResult["uploadedFile"];
                byte[] byteArray = Convert.FromBase64String(fileurl);
                MemoryStream stream = new MemoryStream(byteArray);
                helper.Load(stream);
            }
            string output = JsonConvert.SerializeObject(helper.ProcessPdf(jsonResult));
            return output;
        }


Syncfusion.Pdf.PdfException: 'Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.'



Attachment: error_909304d4.zip


SA Sabari Anand Senthamarai Kannan Syncfusion Team November 17, 2017 09:58 AM UTC

Hi Bojan, 

Thank you for your update. 

Please find the details for your queries in the following table. 

Queries 
Details 
I was hoping that I can pass base64 encoded string in the model from my MVC controller. The MVC controller knows how to call a Web Api 2 REST service. The view should not know anything about the service itself. Would it be possible to load PdfViewer from the @model? I don't want the view to do AJAX calls. 
We can pass the base64 string of the PDF document from the MVC controller to the View page and it can loaded in the PDF viewer control using DocumentPath API .  

We have created a sample to demonstrate the same. Please find the sample from the following link. 


In the above sample, we have provided the text box control and a button in the HTML form element. When the DocumentID is entered in the text box and the View button is clicked, a Form request will be sent to the action method in MVC controller where the byte array of the PDF document will be retrieved from the database and converted into base64 string. This base64 string will be stored in the Model and accessed in the view page then loaded into the PDF viewer control using the DocumentPath API. 
I am also having trouble using the example you have supplied in the original reply. 

The method load throws exception: 

Syncfusion.Pdf.PdfException: 'Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.' 
We are unable to reproduce the reported issue in the sample that we have provided in our previous update. We have recorded the working of the sample as a video for your reference. Please find the screenshot video in the following link. 


We suspect that the reported issue may be specific to the PDF document. Please provide the PDF document that you have used to load in the PDF viewer control. It will be helpful for us to analyze further and assist you better. 

Please let us know if you need any further assistance. 

Regards, 
Sabari Anand 


Loader.
Up arrow icon