Keep XGraphics instance after save - pdfsharp

How can I still have the XGraphics instance after I save the file ? I have declared PdfDocument and XGraphics globally :
private PdfDocument pdf;
private XGraphics gfx;
but after I use pdf.Save(filepath); the gfx becomes null. How to avoid that ?

With PDFsharp there are two ways to solve that issue.
Create the PDF twice: once without date for preview, once with date when you finally print it. This would be a suitable way if PDF generation takes little time.
Re-open the PDF file and obtain a fresh gfx to modify the page.
Use document = PdfReader.Open(filenameDest, PdfDocumentOpenMode.Modify); to open the file, XGraphics gfx = XGraphics.FromPdfPage(document.Pages[0]); to get a fresh gfx for the first page.
This method is also suitable if PDF generation takes longer.
To save time, you could save to a MemoryStream and re-open the PDF for modification from the MemoryStream.
Also discussed on the PDFsharp forum.

Related

SQLFileStream with a chunked file

I'm a little stuck in trying to upload files into our SQL DB using FileStream. I've followed this example http://www.codeproject.com/Articles/128657/How-Do-I-Use-SQL-File-Stream but the difference is we upload the file in 10mb chunks.
On the first chunk a record is created in the DB with empty content (so that a file is created) and then OnUploadChunk is called for each chunk.
The file is uploading ok but when I check, a new file has been created for each chunk, so for a 20mb file for example I have one which is 0kb, another which is 10mb and the final one which is 20mb. I'm expecting one file of 20mb.
I'm guessing this is perhaps to do with getting the transaction context or incorrectly using TransactionScope which I dont quite fully grasp yet. I presume this may be different for each chunk with it going to and from client to server.
Here is the method which is called every time a chunk is sent from the client (using PlupLoad if of any relevance).
protected override bool OnUploadChunk(Stream chunkStream, string DocID)
{
BinaryReader b = new BinaryReader(chunkStream);
byte[] binData = b.ReadBytes(chunkStream.Length);
using (TransactionScope transactionScope = new TransactionScope())
{
string FilePath = GetFilePath(DocID); (Folder path the file is sitting in)
//Gets size of file that has been uploaded so far
long currentFileSize = GetCurrentFileSize(DocID)
//Essentially this is just Select GET_FILESTREAM_TRANSACTION_CONTEXT()
byte[] transactionContext = GetTransactionContext();
SqlFileStream filestream = new SqlFileStream(FilePath, transactionContext, FileAccess.ReadWrite);
filestream.Seek(currentFileSize, SeekOrigin.Begin);
filestream.Write(binData, 0, (int)chunkStream.Length);
filestream.Close();
transactionScope.Complete();
}
}
UPDATE:
I've done a little research and I believe the issue is around this:
FILESTREAM does not currently support in-place updates. Therefore an update to a column with the FILESTREAM attribute is implemented by creating a new zero-byte file, which then has the entire new data value written to it. When the update is committed, the file pointer is then changed to point to the new file, leaving the old file to be deleted at garbage collection time. This happens at a checkpoint for simple recovery, and at a backup or log backup.
So have I just got to wait for the garbage collector to remove the chunked files? Or should I perhaps be uploading the file somewhere on the file system first and then copying it across?
Yes, you will have to wait for Sql to clean up the files for you.
Unless you have other system constraints you should be able stream the entire file all at once. This will give you a single file on the sql side

Can I test the validity of an image file before uploading it in ASP.NET?

I have an ASP.NET web application that allows the user to upload a file from his PC to a SQL Server database (which is later used to generate an image for an tag). Is there an "easy" way to test the image within .NET to validate that it does not contain anything malicious before saving it?
Right now, I use this:
MemoryStream F = new MemoryStream();
Bitmap TestBitmap = new Bitmap(Filename);
TestBitmap.Save(F, System.Drawing.Imaging.ImageFormat.Png);
int PhotoSize = (int)F.Length;
Photo = new byte[PhotoSize];
F.Seek(0, SeekOrigin.Begin);
int BytesRead = F.Read(Photo, 0, PhotoSize);
F.Close();
Creating TestBitmap fails if it is not an image (e.g. if Filename is the name of a text file), but apparently this doesn't stop a file that is an image with malicious code appended to it from loading as an image, so saving it as a MemoryStream and then writing the stream to a byte array (which is later saved in the database) supposedly fixes this.
To avoid people pass programs and other information's using the ability to upload photos to your site you can do two main steps.
Read and save again the image with your code to remove anything elst.
Limit the size of each image to a logical number.
To avoid some one upload bad code and run it on your server you keep an isolate folder with out permission to run anything. More information's about that on:
I've been hacked. Evil aspx file uploaded called AspxSpy. They're still trying. Help me trap them‼
And a general topic on the same subject: Preparing an ASP.Net website for penetration testing

Kentico - Pass MemoryStream file to MediaFileInfo API

I have created a iTextSharp PDF file that is created to a MemoryStream. But I now need to pass this file to the Kentico media library.
I would be grateful if anyone could show my how to do this. The code I have currently is:
//Media Library Info - takes Media Library Name and Website Name
MediaLibraryInfo libraryInfo = MediaLibraryInfoProvider.GetMediaLibraryInfo("MyLibrary", CMSContext.CurrentSiteName);
//Folder in Media Library where Item will be Inserted
string mediaLibraryFolder = folder;
//create media file info item - takes the relative path to the document, the library ID, and the folder name where the document will be located within the media library
MediaFileInfo fileInfo = new MediaFileInfo();
fileInfo.FileLibraryID = libraryInfo.LibraryID;
fileInfo.FileBinaryStream = file;
fileInfo.FileName = title.Replace(" ", "").Trim();
fileInfo.FileTitle = title;
fileInfo.FileDescription = description;
fileInfo.FileExtension = ".pdf";
fileInfo.FileMimeType = "application/pdf";
fileInfo.FilePath = String.Concat("/", folder, "/", title.Replace(" ", "").Trim(), ".pdf");
// Save media file info
MediaFileInfoProvider.ImportMediaFileInfo(fileInfo);
I keep getting database errors due to nullable columns e.g. FileSize, FileExtension, etc. Since I am using a MemoryStream I can't find a way to supply all that information.
Am I using the MediaFileInfo API incorrectly in conjunction with a MemoryStream file?
Actually, I don't think that you need to do anything that RadekM said. You can simply stream the file to disk to save it, and then call the import method you're using to import it into the media library.
For example, a Media Library called "Site Images" for the site "MySite" will have a folder on disk at /MySite/media/Site Images/. Drop your file into there (you can use sub folders if you want). At this point the file is "in" the media library, but it hasn't been imported yet, so you wont be able to use it. You can see this is true by viewing the Media Library in the CMS Desk interface. However, this file has not yet been imported into the Media Library and you should see an exclamation point inside a yellow triangle next to your new file.
So after you get the file in the right location, you can use that file information to populate the MediaFileInfo object and Import the file.
Could you adapt this code and pass the bytes of the PDF from here?
programmatically adding files to the Kentico Media Library
Regrettably, MemoryStream class does not contain these informations, so you can’t gain them from this object directly. Anyway, if you want to supply FileSize property, you can use ms.Length property as a workaround. Basically, this particular property is not important, so it can be even some dummy number.
As for extension – are you saying that you are receiving error saying this property is null, although you set it like „fileInfo.FileExtension = ".pdf";“? Can you clarify?
Also please note that you need to set some other properties, FileSiteID, FileCreatedWhen, FileGUID and FilePath (path inside given media library). If you have full source code of Kentico API, you can get an inspiration from constructor of MediaFileInfo object in \MediaLibrary\MediaFileInfo.cs class.

Why does ASP.net write whitespace at the end of the output from my ASHX file?

I've written an ASHX generic handler to output XML. However, for some reason, ASP.net is appending numerous whitespace characters to the end of the output which breaks the XML.
My code looks like this:
context.Response.ContentType = "text/xml";
XmlSerializer oSerializer = new XmlSerializer(typeof(ModelXml[]),new XmlRootAttribute("rows"));
System.IO.MemoryStream ms2 = new System.IO.MemoryStream();
System.Xml.XmlTextWriter tw = new System.Xml.XmlTextWriter(ms2,new System.Text.UTF8Encoding());
oSerializer.Serialize(tw,models);
string s = System.Text.Encoding.UTF8.GetString(ms2.GetBuffer());
tw.Close();
ms2.Close();
context.Response.Write(s.Trim());
context.Response.End();
When I run this code thru the debugger, I see that the string s does indeed contain the XML data with NO WHITESPACE. However, when I point Internet Explorer at this file, I get the following error:
The XML page cannot be displayed
Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.
--------------------------------------------------------------------------------
Invalid at the top level of the document. Error processing resource 'http://localhost:5791/XXXXX.ashx'.
When I view the page source in Notepad, I see that the file begins with the correct XML, but there are numerous spaces appended to the end. If I remove these spaces, the XML file works fine with my browser and applications.
Why is ASP.net appending these spaces to my output and what can I do about it?
Switch from MS2.GetBuffer() to MS2.ToArray(). You are reading the buffer from the MemoryStream, which is preallocated for efficiency. You want just the used data, not the whole buffer.
Instead of serializing to a MemoryStream, you should serialize directly to Response.Output.
This should solve the issue.

How can I create an image object from an FileUpload control in asp.net?

I have a FileUpload control. I am trying to save the file that is uploaded (an image) and also save several thumbnail copies of the file.
When I try something like this:
System.Drawing.Image imgOriginal = System.Drawing.Image.FromStream(PhotoUpload.PostedFile.InputStream);
I get an "System.ArgumentException: Parameter is not valid."
I also tried using the PhotoUpload.FileBytes to create the image from the file bytes instead of the InputStream, but the same error occurs.
The uploaded file is a jpg. I know it's a valid jpg since it saves the original ok.
Edit: This code actually does work. The Parameter is not valid was due to the PhotoUpload.PostedFile.InputStream being empty... which seems to be an entirely different issue. It looks like after I save the original the fileupload stream goes away.
Edit: Found out that the InputStream of a FileUpload can only be read/consumed one time and then it is gone.
To get around that I saved the fileupload filebytes into a byte array and used the byte array to create copies of the image.
Code:
// Copy the FileBytes into a byte array
byte[] imageData = PhotoUpload.FileBytes;
// Create a stream from the byte array if you want to save it somewhere:
System.IO.Stream myStream = new System.IO.MemoryStream(imageData);
// Or create an image from the stream as many times as needed:
System.Drawing.Image imgOriginal = System.Drawing.Image.FromStream(myStream);
Have a look at this link
ASP Net - How to pass a postedfile to a system.drawing.image
Here's my function call:
uploadAndSizeImage(System.Drawing.Image.FromStream
(uploadedFileMD.PostedFile.InputStream))
I'm getting this error:
Exception Details:
System.ArgumentException: Invalid
parameter used.
Google isn't turning up much though I
did find a reference to it possibly
being caused by the stream reader
being at the end of the stream and me
needing to reset it to position one.
But that was kind of vague and not
really sure if it applies here.
Does this help?
EDIT:
Also, have you tried manually reading the file using something like
System.IO.FileStream fs = System.IO.File.OpenRead(#"Image.JPG");
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
System.Drawing.Image image = Image.FromStream(ms);
Or saving a temp copy from the FileUpload and loading the image from file?

Resources