7

I have searched the web for an answer but without any luck. I'm wondering how and if I'm able to render a pdf-file using Razor into a iFrame located in my view. The pdf is a byte array and is loaded in my Model.

This is my code so far:

public ActionResult ByteConverter(byte[] pdfData)
{
    MemoryStream Stream = new MemoryStream(pdfData);
    Stream.Write(pdfData, 0 , pdfData.Length);
    Stream.Position = 0;
    return new FileStreamResult(Stream,"application/pdf");
}

My Model:

 public async Task<ActionResult> Index()
 {
     ApiClient api = new ApiClient("http://localhost:43674/ApiCore");
     var result = await api.GetAsync();

       RegulationViewModel viewModel = new RegulationViewModel
       {
         ConnectedToRoadMap = result.ConnectedToRoadMap,
         Decided = result.Decided,
         Enforced = result.Enforced,
         Id = result.Id,
         Paragraph = result.Paragraph,
         Pdf = result.Pdf,
         Published = result.Published,
         Region = result.Region,
         StructuredInfo = result.StructuredInfo,
         Title = result.Title,
         ValidThru = result.ValidThru  
        };

        ByteConverter(viewModel.Pdf);

        return View(viewModel);
}

And my view:

<div class="tab-pane active" id="dokument">
    <iframe src="@Url.Action("ByteConverter", "RegulationController")"></iframe>
</div>
5
  • The iframe is empty. There is no content in the body or header. Commented Dec 6, 2018 at 10:02
  • I see that you're passing a byte[] into your action - where does that value get populated? Commented Dec 6, 2018 at 10:03
  • The byte [] is populated in a separate API we are building that gets the value from a database. The API gets the data and sends it to our WebbApp. So basicly im getting all the data I need, I just need to present the data in the view. This specific parameter (pdfData) gets the data from the model. Commented Dec 6, 2018 at 10:08
  • In your question, it looks like your iframe is loading from a URL that doesn't include a value for pdfData and so I wouldn't expect that to work as is. Is that ByteConverter method an action or a helper function that you're calling from an action? As an aside, you shouldn't need the call to Stream.Write as the MemoryStream constructor you're using already sets that data (I don't think you'll need the following line either in that case). Commented Dec 6, 2018 at 10:18
  • The ByteConverter method is called from the model, i'll edit my post and include the model so you can se how it looks like. Commented Dec 6, 2018 at 11:55

2 Answers 2

10

Allright, so after a few days i managed to make it work by changing the Pdf value in my model to Convert.ToBase64String(result.Pdf) like this:

 public async Task<ActionResult> Index()
        {
            ApiClient api = new ApiClient("http://localhost:43674/ApiCore");
            var result = await api.GetAsync();

            RegulationViewModel viewModel = new RegulationViewModel
            {
                ConnectedToRoadMap = result.ConnectedToRoadMap,
                Decided = result.Decided,
                Enforced = result.Enforced,
                Id = result.Id,
                Paragraph = result.Paragraph,
                Pdf = Convert.ToBase64String(result.Pdf),
                Published = result.Published,
                Region = result.Region,
                StructuredInfo = result.StructuredInfo,
                Title = result.Title,
                ValidThru = result.ValidThru
            };

            return View(viewModel);
        }

And in my view I skiped the @Url.Action("ByteConverter", "RegulationController") completely and replaced it with:

<iframe src="data:application/pdf;base64,@Model.Pdf" type="application/pdf"></iframe>

Works like i charm in all webbrowsers exccept IE, and that's because Internet Explorer does not support the use of DATA URIs as the source of iframes.

Sign up to request clarification or add additional context in comments.

2 Comments

I am trying the same but debugger shows - "Resource interpreted as Document but transferred with MIME type application/pdf: "data:application/pdf;base64,JVBERi0xLjcKCjQgMCB..."
This is my data - viewModel.PdfDataString = Convert.ToBase64String(pdfData); AND in view - <div style="border-color: black; border-style: solid; border-width: 1px"> <iframe src="data:application/pdf;base64,@Model.PdfDataString" type="application/pdf"></iframe> </div>
1

You can modify your code like :

public ActionResult ByteConverter()
{
    ApiClient api = new ApiClient("http://localhost:43674/ApiCore");
    var result = await api.GetAsync();
    var pdfData = result.Pdf;
    MemoryStream Stream = new MemoryStream(pdfData);
    Stream.Write(pdfData, 0 , pdfData.Length);
    Stream.Position = 0;
    return new FileStreamResult(Stream,"application/pdf");
}

In view :

<div class="tab-pane active" id="dokument">
    <iframe src="@Url.Action("ByteConverter", "RegulationController")"></iframe>
</div>

Then delete ByteConverter(viewModel.Pdf); in your index view .And also confirm you have set correct controller name , use Home instead of HomeController.

2 Comments

Why would I want to make a new instande of ApiClient in my ByteConverter-method when I'm aldready doing it in my model? Feels redundant. Also, to make that code not show any errors you need to make ByteConverter method async something like "public async Task<ActionResult> ByteCOnverter()".
@K.Oleksiak . The problem is ByteConverter doesn't get byte value when iframe loads , you can save the result.Pdf on server side, that's up to you .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.