FileStreamResult Image and InsertHtml

[Using Aspose Words (NET/C#) v 14.11.0.0, Developer Small Business license]

I have a fully function method which takes my MVC view and outputs as a Word document using the InsertHtml method.

Working MVC View -> Html -> Word Document

//Stream as Word Document using Aspose
License l = new License();
l.SetLicense("Aspose.Words.lic");
string html = Mande2.Utility.Helpers.RenderViewToString(ControllerContext, "~/views/report/quarterly.cshtml", qr, false);
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.InsertHtml(html);
MemoryStream stream = new MemoryStream();
doc.Save(stream, SaveFormat.Docx);
return new WordResults
{
    FileName = "Quarterly Report.docx",
    ByteArray = stream.ToArray()
};

In the MVC View, we are displaying images which must be authenticated and streamed from a third party server (OneHub). My MVC View links to these images using standard HTML:

The DownloadPhoto Action Result returns a System.Web.Mvc.FileStreamResult:

var cd = new System.Net.Mime.ContentDisposition
{
    FileName = document.filename,
    Inline = true
};
Response.AddHeader("Content-Disposition", cd.ToString());
return File(oneHubRepo.DownloadDocument(id), document.content_type);

My issue is that when viewing the report as an HTML page, the image displays as intended. When exporting to the Word document, all I get is the red-X image placeholder (see attachment).

Anyone know what I’m missing here, or how to get an image which is a FileStreamResult to render in the Word document?

Additional Information:

When using InsertImage instead of InsertHtml:

builder.InsertImage("http://localhost:54180/Document/DownloadPhoto/520056775");

I get a stack trace of:

[ArgumentException: Parameter is not valid.]
System.Drawing.Bitmap..ctor(Stream stream) +411353
     ..ctor(Byte[] ) +253
      .(Byte[] ) +139
      .(Byte[] ) +75
   Aspose.Words.DocumentBuilder.InsertImage(Byte[] imageBytes, RelativeHorizontalPosition horzPos, Double left, RelativeVerticalPosition vertPos, Double top, Double width, Double height, WrapType wrapType) +82
   Aspose.Words.DocumentBuilder.InsertImage(Stream stream, RelativeHorizontalPosition horzPos, Double left, RelativeVerticalPosition vertPos, Double top, Double width, Double height, WrapType wrapType) +72
   Aspose.Words.DocumentBuilder.InsertImage(String fileName, RelativeHorizontalPosition horzPos, Double left, RelativeVerticalPosition vertPos, Double top, Double width, Double height, WrapType wrapType) +287
   Aspose.Words.DocumentBuilder.InsertImage(String fileName) +62

Writing the file to disk intead of streaming also doesn’t help, for either the InsertImage or InsertHtml methods.

var dir = Server.MapPath("/Output");
var path = Path.Combine(dir, id + ".jpg");
Stream s = oneHubRepo.DownloadDocument(id);
MemoryStream outS = new MemoryStream();
s.CopyTo(outS);
using (FileStream fs = new FileStream(path, FileMode.Create))
{
    outS.Position = 0;
    byte[] bytes = new byte[outS.Length];
    outS.Read(bytes, 0, (int)outS.Length);
    fs.Write(bytes, 0, bytes.Length);
}
return base.File(path, "image/jpeg");

Done trying for now. Let me know if any other contextual information would be useful, or I can create and send along a sample VS 2012 / 2013 solution.

Hi Blaise,

Thanks for your inquiry. Please create a standalone runnable console application that helps us reproduce your problem on our end and attach it here for testing. Also, please attach your input document and image file you’re getting this problem with here for testing. As soon as you get this simple application ready, we’ll start investigation into your issue and provide you more information. Thanks for your cooperation.

Best regards,

Hi Awais,

I started making a sample console application, but then realized it doesn’t make much sense seeing as the problem is streaming the images from a web application. I also wanted you to be able to test/see this part of the code.

I don’t want to waste hours creating a sample app if you can’t open it or it doesn’t reproduce the problem I’m having.

Can you work with a Visual Studio 2013 Web Application (MVC / .NET 4)?

Thanks, -Blaise

Hi Blaise,

Thanks for your inquiry. Unfortunately, it is difficult to say what the problem is without the document/image and sample application. We need these resources to reproduce the same problem on our end side. This will help us to understand your scenario, and we will be in a better position to address your concerns accordingly.

Best regards,

Ok, found out the problem:

The image url cannot be accessed by the public. The website uses standard forms authentication to provide access to all resources for this website.

The resources (images) cannot be made public, as this is a government application and making these resources public would fail our security audits.

Is there anyway for Aspose to impersonate the current logged-in user when loading the images?

Thanks, -Blaise

Hi Blaise,

Thanks for your inquiry. You can try using the following code:

public class ImageLoadingWithCredentialsHandler : IResourceLoadingCallback
{
    public ImageLoadingWithCredentialsHandler()
    {
        mWebClient = new WebClient();
    }

    public ResourceLoadingAction ResourceLoading(ResourceLoadingArgs args)
    {
        if (args.ResourceType == ResourceType.Image)
        {
            Uri uri = new Uri(args.Uri);
            if (uri.Host == "www.aspose.com")
                mWebClient.Credentials = new NetworkCredential("User1", "akjdlsfkjs");
            else
                mWebClient.Credentials = new NetworkCredential("SomeOtherUserID", "wiurlnlvs");

            // Download the bytes from the location referenced by the URI.
            byte[] imageBytes = mWebClient.DownloadData(args.Uri);
            args.SetData(imageBytes);
            return ResourceLoadingAction.UserProvided;
        }
        else
        {
            return ResourceLoadingAction.Default;
        }
    }
    private WebClient mWebClient;
}

I hope, this will help.

Best regards,

I’ve created a new basic MVC web application using standard forms authentication and built-in local database. URL:
http://bbarstow.relyonsolutions.com/aspose/asposeissue.zip

To visit any page in this application, you must log in. You can register for your own login or use the login provided below:

User: bbarstow@relyonmedia.com
Pass: 1l2k3jabcD$

When logged in, you will have two options: View the HTML report or download the Word version. Both versions use the same model and same view and output the same HTML.

When you view the HTML version, the report opens in new window and works as expected. When you view the Word version, the report is offered as a download, and when opening the image does not display.

I’ve implemented the IResourceLoadingCallback feature, however the ResourceLoading method is never called. I verified this by setting debug points. Can you provide a working example of using the IResourceLoadingCallback, which will use the ResourceLoading method?

If there’s any documentation on this feature that’d be helpful. Thanks.

Using this code to set the LoadOptions:

MemoryStream stream = new MemoryStream();
Document doc = new Document(stream, new LoadOptions { ResourceLoadingCallback = new ImageLoadingWithCredentialsHandler() });
DocumentBuilder builder = new DocumentBuilder(doc);
builder.InsertHtml(html);

Hi Blaise,

Thanks for the additional information. I tested the scenario and have managed to reproduce the same problem on my side. For the sake of correction, I have logged this problem in our issue tracking system as WORDSNET-11257. Our development team will further look into the details of this problem and we will keep you updated on the status of correction. We apologize for your inconvenience.

Best regards,

Hi Awais,

Thanks for elevating this issue! Is there any update or any idea of a time-frame for a fix? I have a meeting in two days with out client and would like to be able to give them some sort of update.

Thanks, -Blaise

Hi Blaise,

Thanks for your inquiry. Unfortunately, your issue is not resolved yet. Our development team is currently doing analysis of this issue to determine the exact root cause of this problem. Once the analysis of this issue is completed, we will then be able to share the ETA. We apologize for your inconvenience.

Best regards,

Thanks Awais,

I’ll let my client know that Aspose is on it.

-B

Hi Blaise,

Regarding WORDSNET-11257, our development team has completed the work on your issue and has come to a conclusion that this issue and the undesired behaviour you’re observing is actually not a bug in Aspose.Words. So, we will most likely close this issue as ‘Not a Bug’.

First issue we can see:

LoadOptions is used when a file is loaded into a document instance created by new Document(…, loadOptions) constructor. LoadOptions isn’t used while doc.InsertHtml(…) called. We suggest you the following code in LoadReport(bool wordDoc) function:

//Render view as string (html)
string html = RenderViewToString(ControllerContext, "~/views/aspose/loadreport.cshtml", vm, false);
//Create new stream and document
MemoryStream htmlStream = new MemoryStream();
StreamWriter writer = new StreamWriter(htmlStream);
writer.Write(html);
writer.Flush();
htmlStream.Position = 0;
Document doc = new Document(htmlStream, new LoadOptions { ResourceLoadingCallback = new ImageLoadingWithCredentialsHandler() });
//Insert HTML into document
//DocumentBuilder builder = new DocumentBuilder(doc);
//builder.InsertHtml(html);
//Stream resulting document to the client
MemoryStream stream = new MemoryStream();
doc.Save(stream, SaveFormat.Docx);
return new WordResults { FileName = "Aspose Example.docx", ByteArray = stream.ToArray() };

In this case ImageLoadingWithCredentialsHandler will work.

Second issue:

It seems this web application doesn’t support authentication with WebClient.Credentials. It returns a login html page in ResourceLoading function when an image is queried. So, you can modify this application to fix these issues.

Best regards,