Strategies For Creating Unique File Names/Locations for Uploaded Files - asp.net-mvc

My ASP.NET MVC app accepts files uploaded and stores these in a single folder. However I want to ensure that when a user uploads a file the app accepts any filename, however this will fail when users try upload files with the same file name.
I guess I could create separate folders for each file but I'd like a clean and flat directory structure. Currently I append a GUID to the file name but this isn't a nice solution as it results in weird filenames when a user downloads a file.
I thought about storing the file data in a database and then writing it out to a file when it was requested, but this is a lot of overhead.
Any alternative approaches?

In order to keep your directory structure flat store your files by appending a GUID (as you already did). In your download handler (controller action method) first convert the GUID based file name to the original file name by removing the GUID from the file name. Then use the FileContentResult class to transfer the file. You can set the FileDownloadName property to specify the file name for the file to transfer. In fact the FileDownloadName property sets the Content-Disposition header under the hood.
Here is a small code example (action method of your download controller class):
string fileToDownload = "test.jpg_4274B9D4-9084-441C-9617-EAD03CC9F47F";
string originalFileName = fileToDownload.Substring(0, fileToDownload.LastIndexOf('_'));
FileContentResult result = new FileContentResult(
System.IO.File.ReadAllBytes(Server.MapPath(String.Format("~/files/{0}", fileToDownload))), "application/binary");
result.FileDownloadName = originalFileName; // Sets the Content-Disposition header
return result;
The user downloading the file is prompted to open/save a file with the original file name.
Hope, this helps.

Related

Storing an data item's file extension in Core Data: plain string or other flavor of data Type?

I'm working on the data model for an app I'm building that will use CoreData. As part of that process, the app includes a function that will iterate through a series of MP3 files to populate the database.
The data model at the moment is:
var metadataArray = [(fileName: String, title: String, artist: String,
duration: String, fileExtension: String)]()
Note that in order for the app to later access those files, I'm storing the file name and the file extension. Since the path to the app's Documents folder isn't known at build time, my thought was to include code that programmatically locates the Documents folder. Then, when it's time to access a file, use the stub path to the Documents folder and tack on the filename String and fileExtension String using .appendPathComponent() to generate a URL from the three components.
My question feels kind of esoteric, but it seems like the right time to ask it:
Q: Swift provides a method to assemble URLs from strings, but in the data model declaration, is there any special data Type that's more appropriate for storing file names and file extensions than just plain Strings?
I'm guessing the answer is no -- that Strings are fine, given all the methods Swift provides to assemble full URLs from Strings. But since Swift allows you to declare a full URL as a data type, I thought it was worth asking if there's some sort of a data type more suitable for components of a URL.
Thanks in advance!

Sensenet API: Best Way to Create Folder structure

I want upload content to a specific path on sensenet. This path may not be already created on sensenet. So if the path do not exists, the system has to create it.
Using the Client API of Sensenet, the method available to create content runs Asynchronous. I tried to force it to run Synchronous but it seems not to happen, becaus sometimes the second folder is not created...
Here's a sample code:
private async Task CreateFolder(String parentPath, String folderName){
var folder = Content.CreateNew(parentPath, "Folder", folderName);
await folder.SaveAsync();
}
CreateFolder("/Root/Sites/Test/DocumentWorkSpace", "folder").Wait();
CreateFolder("/Root/Sites/Test/DocumentWorkSpace/folder", "subfolder").Wait();
I can use Tools.EnsurePathAsync(path) to create folder structure. But after this, I want to upload the file... (I'm having the same problem of the folder structure reported above.)
Task.Run(() => Tools.EnsurePathAsync(pathDocType)).Wait();
Task.Run(() =>{
var stream = new MemoryStream(byteContent);
Content.UploadAsync(pathDocType, "test.doc", stream).WaitAndUnwrapException();
stream.Dispose();
}).Wait();
You have multiple options, depending on your use case.
Importing a whole folder structure
Take a look at the import api in the client library. It is actually a single method that you can use to import a folder structure from the file system. It handles all folder creation and upload internally:
await Importer.ImportAsync(sourcePath, targetPath, options);
The options object can be used to customize the behavior of the algorithm (e.g. max degree of parallelism for large structures, defining a custom container type instead of the default Folder or defining an optional logging delegate method).
This method is scalable, meaning it is capable of importing a huge number of folders and files efficiently. It will return after importing every folder and file (filtered by the optional filters in the options parameter).
Ensuring a parent folder chain
There is a single method for creating parent folders (if they do not exist yet).
await Tools.EnsurePathAsync(path);
You can call this with a non-existing path (e.g. /Root/Folder1/Folder2) and it will create it for you. This method only deals with folders, it has nothing to do with files.

Correct way to use QLPreviewController with Core Data

I have CoreData app that stores some BLOBs in external files ("allows external storage" flag).
Files are images, PDFs, excel files etc. I wanna use QLPreviewController ti preview it. But it does not support CoreData from scratch. So, I should first copy file to tmp folder. I am sure there should be better way to do that.
Does there is any?
According to the documentation for QLPreviewItem the URL returned by previewItemURL must be a file URL.
Thus, you must be able to give it a URL for a file that lives on disk. Apple does not provide an official way to get the URL for data stored externally. Furthermore, "smaller" files would be stored as a BLOB in the SQL database anyway.
The two most viable options are to either copy the contents into a temporary file when needed, or store the file on disk yourself, and keep the URL (or better yet... a unique identifier) in the core data model.
I'd go with the second method.
If you store the files in a subdirectory of the directory containing your core data store, you can just keep a UUID in the database. You can then identify the file, even if you want to move it to a different location, and you don't have to go change all the entities in the store.
Let's say you have a directory named "externalFiles" in the same directory as your persistent store.
If you used a special entity, you could add two simple attributes (identifier and title) for the particular item. The identifier can be the string representation of NSUUID.
You will probably already want to get at the URL...
- (NSURL*)URL {
// Separated on multiple lines for readability
NSString *identifier = [self valueForKey:#"identifier"];
NSURL *url = self.objectID.persistentStore.URL;
url = [url URLByDeletingLastPathComponent];
url = [url URLByAppendingPathComponent:#"externalFiles"];
url = [url URLByAppendingPathComponent:identifier];
return url;
}
You can then make your NSManagedObject subclass conform to QLPreviewItem protocol by implementing the two methods previewItemURL and previewItemTitle.
- (NSURL*)previewItemURL {
return self.URL;
}
- (NSURL*)previewItemTitle {
return self.title;
}
And then, you can just pass your core data instances to the QLPreviewControllerDataSource because they can now be treated as QLPreviewItems.

Swift, Xcode 6 Beta 4: How do I retrieve the file path of an image file that is currently being displayed using the Photos framework's assets?

I am currently writing an iOS app in which my intent is to save data objects associated with the app in a DB created in Core Data. I have successfully created the DB, and plan to synchronize the data objects among different devices logged in to the same iCloud-account through iCloud. In the middle of all this, I would also like media files to be associated with the distinct data objects. However, I do not wish to save the binary data constituting a media file directly to the DB. Thus I need some kind of way to preserve the reference to the correct media file in the DB. My immediate thought was to place every media file in a specific folder, turn on iCloud sync for that folder, and save the media files' filenames to the DB. However, I am not able to retrieve the file path of any media files.
Below is a code snippet from the app. When that code is run, an assetCollection as well as a photosAsset with an index exists, and is displaying an image in the view controller. Despite this, none of the if-sentences prints any output (all of the references are nil).
if let a: String = self.photosAsset[self.index].bundleIdentifier {
println(a)
}
if let a = self.photosAsset[self.index].bundleURL {
println(a)
}
if let a: String = self.photosAsset[self.index].resourcePath {
println(a)
}
if let a = self.photosAsset[self.index].resourceURL {
println(a)
}
Any thoughts on how to retrieve the file path of an image file that is being displayed in this way? Any solutions on how to retrieve file paths in general that could be applicable to this problem?
Any thoughts on my approach in general would also be greatly appreciated.
I think that if you are storing the photos as xcassets, then you may not be able to access a path for them, as this type can sometimes be compressed (so it seems Apple don't allow it) e.g. see the answer posted for Access Asset Catalog pathForResource
I would create a custom directory structure to store the photos, rather than store them in the bundle, e.g. in /Documents/
This would allow you to use classes such as NSFileManager to find all photos of certain types etc and load them when need be.
For information about where Apple recommends you store things see https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html

How to avoid renaming Oledbconnection data source

When transfering file to another location i always need to change the source or directory..
Dim cnn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Renz\Desktop\FINAL\Database\AuditDB.mdb")
Is there a way I can avoid that?
You could use a path relative to your applications location, e.g.
Dim cnn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Database\AuditDB.mdb")
Where in this example I am presuming that your database is stored in a folder called Database in the same folder as your program.

Resources