I am working on this problem and the proposed solution works for me.
However, now I need to make this work in my actual application which is an AWS Beanstalk .NET web application. My beanstalk application knows the url source of the picture. Knowing the url, I can get a stream and process the file (by creating a byte array and even a Bitmap object).
However, it seems that to get the file properties as mentioned above (such as the camera type or painting application that created the file), I really need a local file because that is the expected input argument.
This is a problem for me. I know the http link, I know the bytes but I have no such thing as a file path.
How can I solve this? I need the windows file properties.
If I understood you correctly, you want to read image metadata from a URL without saving it to a file first, i.e. directly from the Internet.
Here is one way that works for me:
string demoImageUrl = "https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/Canon_40D.jpg";
byte[] imgData = null;
using (var wc = new WebClient())
{
imgData = wc.DownloadData(demoImageUrl);
}
using (var sr = new MemoryStream(imgData, false))
{
BitmapSource image = BitmapFrame.Create(sr);
BitmapMetadata md = (BitmapMetadata)image.Metadata;
string comment = md.Comment;
string title = md.Title;
string dateTaken = md.DateTaken;
}
You need to add references to PresentationCore and WindowsBase assemblies and also include the following namespace:
using System.Windows.Media.Imaging;
Related
In an existing Asp.Net application, we are using Response.BinaryWrite to render image on an aspx page. This is the required functionality, and below is the C# code-
1. byte[] img = getImage();
2. Response.BinaryWrite(img);
The getImage function reads the image from a folder on server and returns byte array. Fortify scan shows cross-site vulnerability on 2nd line.
I did following validations, but fortify still reports it as cross-site issue -
Validated bytearray to check if the file is of correct format (jpeg or bmp), used this link - Determine file type of an image
Response.BinaryWrite(ValidateFileType(img));
Validated the domain in the file path to check if the file is originating from correct domain.
Is there any specific way to pass the fortify cross-site issue with byte array or can i consider it as false positive?
Had to use a workaround to resolve this, below is the old and new code -
Old Code -
1. byte[] byteImage = getImage();
2. Response.BinaryWrite(byteImage);
New Code (Replaced 2nd line in old code with below block) -
byte[] byteImage = getImage();
var msIn = new MemoryStream(byteImage);
System.Drawing.Image img = System.Drawing.Image.FromStream(msIn);
var msOut = new MemoryStream();
img.Save(msOut, img.RawFormat);
Response.BinaryWrite(msOut.ToArray());
msIn.Dispose();
msOut.Dispose();
Response.Flush();
So, basically converting the byteArray to an Image object, and then writing the image object back to the Response.BinaryWrite stream resolved this, and it passed through Fortify scan.
If anyone is looking for a solution, this might help.
My question is a bit similar to this one but it is with ASP.NET and my requirements are slightly different: Android append files to a zip file without having to re-write the entire zip file?
I need to insert data to a zip-file downloaded by users (not much 1KB of data at most, this is data for Adword off-line conversion actually). The zip-file is downloaded through an ASP.NET website. Because the zip file is already large enough (10's of MB) to avoid overloading the server, I need to insert these data without re-compressing everything. I can think of two ways to do this.
Way A: Find a zip-technology that lets embed a particular file in the ZIP file, this particular file being embedded uncompressed. Assuming there is no checksum, it'd be then easy to just override the bits of this un-compressed file with my specific data, in the zip file itself. If possible, this would have to be supported by all unzip tools (Windows integrated zip, winrar, 7zip...).
Way B: Append an extra file to the original ZIP file without having to recompress it! This extra file would have to be stored in an embedded folder in the ZIP file.
I looked a bit at SevenZipSharp which has an enumeration SevenZip.CompressionMode with values Create and Append that leads me to think that Way B could be implemented. DotNetZip seems also to work pretty well with Stream according to FAQ.
But if Way A could be possible I'd prefer it much since no extra zip library would be needed on the server side!
Ok, thanks to DotNetZip I am able to do what I want in a very resource efficient way:
using System.IO;
using Ionic.Zip;
class Program {
static void Main(string[] args) {
byte[] buffer;
using (var memoryStream = new MemoryStream()) {
using (var zip = new ZipFile(#"C:\temp\MylargeZipFile.zip")) {
// The file on which to override content in MylargeZipFile.zip
// has the path "Path\FileToUpdate.txt"
zip.UpdateEntry(#"Path\FileToUpdate.txt", #"Hello My New Content");
zip.Save(memoryStream);
}
buffer = memoryStream.ToArray();
}
// Here the buffer will be sent to httpResponse
// httpResponse.Clear();
// httpResponse.AddHeader("Content-Disposition", "attachment; filename=MylargeZipFile.zip");
// httpResponse.ContentType = "application/octe-t-stream";
// httpResponse.BinaryWrite(buffer);
// httpResponse.BufferOutput = true;
// Just to check it worked!
File.WriteAllBytes(#"C:\temp\Result.zip", buffer);
}
}
Is it possible to reference a new bitmap pointing to file in the .NET solution without giving it a fully qualified file system location? Trying to do this to run in Azure without having to set up cloud storage.
This code fails to resolve a.jpg... I tried \a.jpg, ~\a.jpg, etc. Suspect NOT but asking just in case I'm missing something here.
context.Response.Clear();
//Bitmap bitMapImage = new System.Drawing.Bitmap((#"P:\somedirectory\a.jpg"));
Bitmap bitMapImage = new System.Drawing.Bitmap((#"a.jpg"));
Graphics graphicImage = Graphics.FromImage(bitMapImage);
UPDATE: also tried
Bitmap bitMapImage = new System.Drawing.Bitmap(HttpContext.Current.Server.MapPath("a.jpg"));
I use this in Azure with MVC 4
string strAttachFileName = HostingEnvironment.MapPath("/images/GM.gif");
String DocLocation = System.AppDomain.CurrentDomain.BaseDirectory + "Files/test.pdf";
// or
String DocLocation = Url.Content("~/Files/test.pdf");
var document = new FileStream(DocLocation, FileMode.Open);
var mimeType = "application/pdf";
var fileDownloadName = "download.pdf";
return File(document, mimeType, fileDownloadName);
The first method is UnauthorizedAccessException.
The second method cant find the file.
I am trying to send a file for download. Using full desktop path seems to work.
Also, how would I display PDF in the browser instead (note, still need download option as not all are pdf)?
Try Server.MapPath("~/Files/test.pdf")
File() takes a physical path on disk.
Therefore, you can't use Url.Content, since that returns a relative URL for the browser.
Instead, you need Server.MapPath, which converts an application relative path into a full path on the local disk.
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.