MemoryStream vs. FileStream: Document Viewer rendering document from filestream successfully but not memorystream?
I'm using C1's PDF viewer control in a silverlight application and am testing max PDF size limitations. I have a PDF that's 35MB.
When I load the PDF viewer through the OpenFileDialog simply sending it the filestream it renders fine. All 900 pages.
However, when I attempt to load the PDF viewer through a MemoryStream created from a byte[] it renders nothing. It does not error out, it simply renders blank.
This is the exact same document. And the MemoryStream process works successfully with significantly smaller PDF documents. Yet the FileStream method works with larger documents so I know it's not a limitation of the PDF viewer, correct?
FileStream method:
OpenFileDialog ofd = new OpenFileDialog();
bool? res = ofd.ShowDialog();
if (res == true)
{
开发者_如何学GoFileStream stream = ofd.File.OpenRead();
docViewer.LoadDocument(stream);
}
MemoryStream method:
imageBytes = File.ReadAllBytes(path);
MemoryStream stream = new MemoryStream();
stream.Write(imageBytes, 0, imageBytes.Length);
stream.Seek(0, SeekOrigin.Begin);
docViewer.LoadDocument(stream);
This gave me the same results. Blank viewer:
using (MemoryStream stream = new MemoryStream(imageBytes))
{
docViewer.LoadDocument(stream);
}
Again...frustrated by failure. I refactored the call to use "OpenReadAsync", then I altered my API call (we're using MVC as a pseudo API) to return the stream and it's still rendering blank. The result internal stream's length is correct too.
Client Call:
string url = App.Server + "Document/RetrievePDFTest";
try
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(delegate(object sender, OpenReadCompletedEventArgs e)
{
if (e.Result != null)
{
docViewer.LoadDocument(e.Result);
}
});
wc.OpenReadAsync(new Uri(url));
}
catch (Exception ex)
{
//TODO - handle exception
}
Server API:
public ActionResult RetrievePDFTest()
{
return File(System.IO.File.ReadAllBytes("D://temp//repositories//test35mb.PDF"), "application/pdf");
}
UPDATE!!!! I believe I've found what might be an issue.
Within my silverlight application I'm actually popping this document viewer in a new window, then I'm sending that new window the information by which to retrieve the PDF image from teh server. In essence, I'm telling it which document to retrieve by a key I'm passing:
this.windowManager.NavigateToPageInNewWindow("/Views/pdfViewerUserControl.xaml");
LocalMessageSender s = new LocalMessageSender("receiver", LocalMessageSender.Global);
s.SendAsync(doc.Barcode);
Now, in my pdfViewerUserControl.xaml, in it's constructor I'm creating and registering the listener for the message:
public pdfViewerUserControl()
{
LocalMessageReceiver messageReceiver = new LocalMessageReceiver("receiver", ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain);
messageReceiver.MessageReceived += messageReceiver_MessageReceived;
try
{
messageReceiver.Listen();
}
catch (Exception ex)
{
}
// Required to initialize variables
InitializeComponent();
}
In the "messageReceiver_MessageReceived" event handler, this is where I make my server call to retrieve the image and load the viewer. This process is resulting in a blank PDF viewer even though the server returns the image. (even the LARGE pdf)
NOW, as a test tool I also have a test button on the page, this button triggers an event in the code behind that makes the exact same server call, and loads the result in the exact same way but this works!!! The large 35MB PDF is rendered successfully in teh viewer.
This leads me to believe there's a disconnect when using the LocalMessageSender/LocalMessageReceiver objects.
Given the comments, I suspect the problem is that you're downloading it as a string and then converting it into bytes. Compare the data in the byte array with the data in the file (e.g. take an MD5 hash).
To download binary data, you should be using DownloadData
instead.
One possible reason could be memory stream object has to be disposed at the end.
using (MemoryStream ms = new MemoryStream())
{
// Do something with ms..
}
or say this at end of using memory stream object
stream.Dispose();
stream.Close();
It seems the issue has nothing to do with the viewer or the PDF file at all. It has to do with some issue of not being able to manipulate the UI in the context that I'm in.
I'm popping a new window using HtmlPage.PopupWindow() specifying another usercontrol (my pdf XAML user control which contains the pdfviewer) as the URI.
In order to pass that new window the key of which document to retrieve/view, I registered a listener on that new window's user control. Then I send that listener the key.
Well in the listener's message received event, I'm making the call to get the byte array and populate the viewer.
This seems to not be updating the UI. Instead, I've ditched the listener/sender pattern and simply tacked the key onto the end of the URI to the "HtmlPage.PopupWindow()". Then in the constructor of the new user control page, I extrapolate the key from the URI and "bob's your uncle", it works.
I'm still unsure of whether I was on a separate thread, or what was going on with the listener's "on message received" event. I was hitting the breakpoint in the listener, the doc viewer's "LoadDocument()" method was not erroring our or throwing an exception, the UI just simply was not rendering the update.
精彩评论