Kentico - Pass MemoryStream file to MediaFileInfo API - asp.net

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.

Related

How to find file extension in Azure Storage?

If there is no extension in the file name, then I cannot get the contentType to create FileStreamResult.
Example:
byte[] byteFile = await someDirectory.GetFileContentAsync(fileName);
string contentType;
new FileExtensionContentTypeProvider().TryGetContentType(fileName, out contentType); // fileName without extension
return (byteFile, contentType); // contentType == null
Is there a way to get the extension not from the name?
Looking at the code for FileExtensionContentTypeProvider, there's a predefined list of file extensions and their corresponding mime-types. TryGetContentType method will return null if the file extension is not in that list.
If you get a file without file extension, one possible way would be to find the kind of file by reading it's metadata but that's really complicated. For example, reading the file contents you can find out if the file is an image and if it is of type png. But you will need to write code to identify each type of image (png, bmp, gif etc.).
A simpler way would be to infer null content type as default content type. In case of Azure Storage, it will be application/octet-stream.

Extracting Windows File Properties with http link

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;

Get full name of binary from Razor Template, including extention

I'm using a technique I found on SO (here) to publish binaries from a Razor template. It works great except for one minor shortcoming.
I want to push an item with the file name that was uploaded to Tridion. I can use the title for most of that, but how can I determine the file extension? In this case I need to know the name of the file in the template because I am going to do some javascript manipulation with it.
Again, everything works fine, but I'd like to do something other than just concatenating a ".jpg". It looks like I can parse the WebDavUrl property. Is that my only option?
#{
var item1 = TridionHelper.Package.CreateMultimediaItem(#Fields.closed.ID);
TridionHelper.Package.PushItem(#Fields.closed.Title + ".jpg", item1);
string closed = #Publication.MultimediaUrl + "/"+(#Fields.closed.Title) + ".jpg";
}
You have full access to the TOM.NET API from Razor Mediator, so you can also access the filename from the Component's BinaryContent field. Assuming #Fields.closed is a Multimedia Component Link you can do:
#Fields.closed.TridionObject.BinaryContent.Filename
Note that this will be the original path/filename that was uploaded. You also have access to System.IO.Path, so you co:
#System.IO.Path.GetFileName(Fields.closed.TridionObject.BinaryContent.Filename)
#System.IO.Path.GetExtension(Fields.closed.TridionObject.BinaryContent.Filename)
#System.IO.Path.GetFileNameWithoutExtensions(Fields.closed.TridionObject.BinaryContent.Filename)
You'll have to be careful if you have a custom TBB that publishes binaries, as this TBB could actually change the filename that is published, and the Filename property of BinaryContent will only contain the original uploaded path and filename.

Getting extension of the file in FileUpload Control

At the moment i get file extension of the file like :
string fileExt = System.IO.Path.GetExtension(filUpload.FileName);
But if the user change the file extension of the file ( for example user could rename "test.txt" to "test.jpg" ), I can't get the real extension . What's the solution ?
You seem to be asking if you can identify file-type from its content.
Most solutions will indeed attempt the file extension, but there are too many different possible file types to be reliably identifiable.
Most approaches use the first several bytes of the file to determine what they are.
Here is one list, here another.
If you are only worried about text vs binary, see this SO question and answers.
See this SO answer for checking if a file is a JPG - this approach can be extended to use other file headers as in the first two links in this answer.
Whatever the user renames the file extension to, that is the real file extension.
You should never depend on the file extension to tell you what's in the file, since it can be renamed.
See "how can we check file types before uploading them in asp.net?"
There's no way to get the 'real' file extension - the file extension that you get from the filename is the real one. If file content is your concern, you can retrieve the content type using the .ContentType property and verify that it is a content type that you are expecting - eg. image/jpg.

how to check whether a file exists before creating it

I am creating an xml file. I need to check first if the file exists or not. If the file does not exist, create it and add the data cmg from a .cs file.
If the file exists, don't create the file just add the data cmg from a .cs file.
My code looks like this:
string filename="c:\\employee.xml";
XmlTextWriter tw=new XmlTextWriter(filename,null);//null represents
the Encoding Type//
tw.Formatting=Formatting.Indented; //for xml tags to be indented//
tw.WriteStartDocument(); //Indicates the starting of document (Required)//
tw.WriteStartElement("Employees");
tw.WriteStartElement("Employee","Genius");
tw.WriteStartElement("EmpID","1");
tw.WriteAttributeString("Name","krishnan");
tw.WriteElementString("Designation","Software Developer");
tw.WriteElementString("FullName","krishnan Lakshmipuram Narayanan");
tw.WriteEndElement();
tw.WriteEndElement();
tw.WriteEndDocument();
tw.Flush();
tw.Close();
so next time we add data to file we need to check if the file exits and add data to xml file
and as we have made empID as a primary key, if user tries to make duplicate entry we need to avoid
Is this possible to do?
if (!File.Exists(filename))
{
// create your file
}
or
if (File.Exists(filename))
{
File.Delete(filename);
}
// then create your file
File class is in System.IO namespace (add using System.IO; to your file)
You can't append records to an XML file, you have to read the file and then rewrite it.
So, just check if the file exists, and read the records from it. Then write the file including all previous records and the new record.
Have a look at the File.Exists method here
Testing for existance of a file before attempting to create it inherently is subject to a "things change after check" race condition. Who can guarantee you that your application isn't preempted and put to sleep for a moment after you checked, someone else creates/deletes that file, your app gets to run again and does exactly the opposite of what you intended ?
Windows (as well as all UN*X variants) supports file open/create modes that allow to perform that create-if-nonexistant/open-if-existant operation as a single call.
As far as .NET goes, this means for your task (create an XML file) you'd first create a System.IO.FileStream with the appropriate modes, see http://msdn.microsoft.com/en-us/library/system.io.filemode.aspx and then pass that stream to the XmlWriter constructor. That's safer than simply performing an "exists" check and hoping for the best.

Resources