Problem accessing mp3 files in WinRT app.
'System.UnauthorizedAccessException' occurs when app tries to open a mp3 file by name in the same folder as a file returned by FileOpenPicker. Put another way, the user picks an info file in Documents with the same name as a mp3 file. App opens the info file just fine but cannot open the mp3 file.
For example: I have a pair of files (file1.info) and (file1.mp3). A filepicker allows selecting a (*.info) file.
The user selects (file1.info). The app then opens both (file1.info) and (file1.mp3). Both files reside in a DocumentsLibrary folder, but are NOT in the MusicLibrary. The problem is when I try to open (file1.mp3) I get the 'UnauthorizedAccessException'.
To prepro the issue:
Files:
Copy an mp3 file to Documents.
Create a text file with the same base name as the mp3 file and change its extension to .info.
In Package.appxmanifest > Declarations add a 'File Type Associations' declaration. Check 'Open is safe'. Add
supported file types '.mp3' and '.info'. Leave 'Content type' empty.
Code:
Dim file as StorageFile
Dim fileopenpicker As FileOpenPicker
Dim infofile As StorageFile
Dim mp3file As StorageFile
Dim filename As String
fileopenpicker = New FileOpenPicker()
fileopenpicker.FileTypeFilter.Add(".info")
fileopenpicker.FileTypeFilter.Add(".mp3")
fileopenpicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary
file = Await fileopenpicker.PickSingleFileAsync()
If file.Path.EndsWith(".info") Then
infofile = file
filename = file.Path.Substring(0, file.Path.Length - 4) & "mp3"
' This command fails with 'System.UnauthorizedAccessException'
mp3file = Await StorageFile.GetFileFromPathAsync(filename)
Else 'file is an mp3 file
mp3file = file
filename = file.Path.Substring(0, file.Path.Length - 3) & "info"
' This command succeeds!
infofile = Await StorageFile.GetFileFromPathAsync(filename)
End If
So it appears that there is some specific problem with opening an mp3 file when the file is not actually chosen by the fileopenpicker.
I checked this issue with an app that has the capability Documents Library and the filetypes .mp3 and .info declared. I figured out that it seems to be a very strange bug. If you pass the path to the documents library folder using an uppercase drive letter after having opened a FileOpenPicker you get an UnauthorizedAccessException. Using the path with a lowercase drive letter works. Strangely you can use an uppercase drive letter before having opened a FileOpenPicker.
So the workaround is to lowercase the path.
Here's the code I used (C#):
// Trying to get some files from the documents library
// Note: F:\Program Data is my primary documents library folder
string mp3FilePath = #"F:\Program Data\2Mann1Maus.mp3";
// This works even if the drive letter is uppercase
StorageFile file1 = await StorageFile.GetFileFromPathAsync(mp3FilePath);
// It also works with a lowercase drive letter
string infoFilePath = #"f:\Program Data\2Mann1Maus.info";
StorageFile file2 = await StorageFile.GetFileFromPathAsync(infoFilePath);
FileOpenPicker fileopenpicker = new FileOpenPicker();
fileopenpicker.FileTypeFilter.Add(".info");
fileopenpicker.FileTypeFilter.Add(".mp3");
fileopenpicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
StorageFile file = await fileopenpicker.PickSingleFileAsync();
if (file.Path.EndsWith(".info"))
{
string filename = file.Path.Substring(0, file.Path.Length - 4) + "mp3";
// This works
string testFileName1 = filename.Substring(0, 1).ToLower() +
filename.Substring(1, filename.Length - 1);
StorageFile mp3file1 = await StorageFile.GetFileFromPathAsync(testFileName1);
// This works as well
string testFileName2 = filename.ToLower();
StorageFile mp3file2 = await StorageFile.GetFileFromPathAsync(testFileName2);
// This does cause an UnauthorizedAccessException
StorageFile mp3file3 = await StorageFile.GetFileFromPathAsync(filename);
}
else
{
StorageFile mp3file = file;
String filename = file.Path.Substring(0, file.Path.Length - 3) + "info";
// This works
string testFileName1 = filename.Substring(0, 1).ToLower() +
filename.Substring(1, filename.Length - 1);
StorageFile infoFile1 = await StorageFile.GetFileFromPathAsync(testFileName1);
// This works as well
string testFileName2 = filename.ToLower();
StorageFile infoFile2 = await StorageFile.GetFileFromPathAsync(testFileName2);
// This does cause an UnauthorizedAccessException
StorageFile infoFile3 = await StorageFile.GetFileFromPathAsync(filename);
}
Related
I'm working on a site hosted in Azure that has a download functionality. To reduce the load on our servers, the download is done use Shared Access Signatures. However, in Safari when downloading the file, the filename is wrapped in single quotes, as in myFile.txt downloads as 'myFile.txt'. This has made it so zips being downloaded have to be renamed by the client so the contents can be extracted.
Code for generated the Shared Access Signature is as follows:
CloudBlockBlob blob = container.GetBlockBlobReference(Helpers.StringHelper.TrimIfNotNull(blobName));
if (!blob.Exists())
{
return string.Empty;
}
var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddSeconds(-5);
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.Add(duration);
sasConstraints.Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write;
var headers = new SharedAccessBlobHeaders();
string filename = blobName;
if (filename.Contains("/"))
{
filename = blobName.Substring(blobName.LastIndexOf("/") + 1, blobName.Length - blobName.LastIndexOf("/") - 1);
}
headers.ContentDisposition = "attachment; filename='" + filename + "'";
//Generate the shared access signature on the blob, setting the constraints directly on the signature.
string sasBlobToken = blob.GetSharedAccessSignature(sasConstraints, headers);
//Return the URI string for the container, including the SAS token.
return blob.Uri + sasBlobToken;
This code has worked fine in Chrome, Firefox, and IE. Is there something I'm missing with the headers? The only one I'm modifying is content-disposition.
You should use double quotes for quoted strings in HTTP headers, as outlined in RFC2616.
So replace
headers.ContentDisposition = "attachment; filename='" + filename + "'";
with
headers.ContentDisposition = "attachment; filename=\"" + filename + "\"";
Please help me with the below issue.
I have to read data from excel .
I have created JSPDynpage component and followd below link :
http://help.sap.com/saphelp_sm40/helpdata/en/63/9c0e41a346ef6fe10000000a1550b0/frameset.htm below is my code. I am trying to read excel file using apache poi 3.2 API
try
{
FileUpload fu = (FileUpload)
this.getComponentByName("myfileupload");
// this is the temporary file
if (fu != null) {
// Output to the console to see size and UI.
System.out.println(fu.getSize());
System.out.println(fu.getUI());
// Get file parameters and write it to the console
IFileParam fileParam = fu.getFile();
System.out.println(fileParam);
// Get the temporary file name
File f = fileParam.getFile();
String fileName = fileParam.getFileName();
// Get the selected file name and write ti to the console
ivSelectedFileName = fu.getFile().getSelectedFileName();
File fp = new File(ivSelectedFileName);
myLoc.errorT("#fp#"+fp);
try {
//
**FileInputStream file = new FileInputStream(fp);** --> error at this line
HSSFWorkbook workbook = new HSSFWorkbook(file);
myLoc.errorT("#workbook#"+workbook);
//Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);
myLoc.errorT("#sheet#"+sheet);
//
} catch(Exception ioe) {
myLoc.errorT("#getLocalizedMessage# " + ioe.getLocalizedMessage());
}
Error :
#getLocalizedMessage# C:\Documents and Settings\10608871\Desktop\test.xls (The system cannot find the path specified)
at line FileInputStream file = new FileInputStream(fp);
I have created the PAR file and deploying it on server.
Thanks in Advance,
Aliya Khan.
i resolved the problem, i was passing the worng parameter instead of f
FileInputStream file = new FileInputStream(f);
I'm using the following code on Mac using Mono to unzip a zip file. The zip file contains entries under directories (for example foo/bar.txt). However, in the unzipped directory, instead of creating a directory foo with a file bar.txt, FastZip creates a file foo\bar.txt. How do I get around this?
FastZip fz = new FastZip();
string filePath = #"path\to\myfile.zip";
fz.ExtractZip(filePath, #"path\to\unzip\to", null);
This creates a file foo\bar.txt in path\to\unzip\to.
Apparently cannot use FastZip for this case so I ended up writing my own unzipping mechanism:
string filePath = #"path\to\myfile.zip";
string unzipDir = #"path\to\unzip\to";
using (var zipFile = new ZipFile(filePath))
{
foreach (var zipEntry in zipFile.OfType<ZipEntry>())
{
var unzipPath = Path.Combine(unzipDir, zipEntry.Name);
var directoryPath = Path.GetDirectoryName(unzipPath);
// create directory if needed
if (directoryPath.Length > 0)
{
Directory.CreateDirectory(directoryPath);
}
// unzip the file
var zipStream = zipFile.GetInputStream(zipEntry);
var buffer = new byte[4096];
using (var unzippedFileStream = File.Create(unzipPath))
{
StreamUtils.Copy(zipStream, unzippedFileStream, buffer);
}
}
}
use a forward slash to separate folders when creating the zip
I want to know how to get files from the directory under Picture Library.(C:\Users\username\Pictures\MyFoler)
I know how to get files and folders from PicturesLibrary.
StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
IReadOnlyList<StorageFile> fileLists = await picturesFolder.GetFilesAsync();
IReadOnlyList<StorageFolder> folderLists = await picturesFolder.GetFoldersAsync();
Using the same general mechanism, StorageFolder exposes GetFoldersAsync and GetFilesAsync.
This code, added after what you have, would get a list of files in Pictures\MyFolder
StorageFolder myFolder = folderLists.Where(f => f.DisplayName == "MyFolder").FirstOrDefault();
if (myFolder != null)
{
ReadOnlyList<StorageFile> myPictures = await myFolder.GetFilesAsync();
}
I am trying to upload a file via a form and then save in in SQL as a blob.
I already have my form working fine, my database is fully able to take the blob and I have a controller that take the file, saves it in a local directory:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult FileUpload(int id, HttpPostedFileBase uploadFile)
{
//allowed types
string typesNonFormatted = "text/plain,application/msword,application/pdf,image/jpeg,image/png,image/gif";
string[] types = typesNonFormatted.Split(',');
//
//Starting security check
//checking file size
if (uploadFile.ContentLength == 0 && uploadFile.ContentLength > 10000000)
ViewData["StatusMsg"] = "Could not upload: File too big (max size 10mb) or error while transfering the file.";
//checking file type
else if(types.Contains(uploadFile.ContentType) == false)
ViewData["StatusMsg"] = "Could not upload: Illigal file type!<br/> Allowed types: images, Ms Word documents, PDF, plain text files.";
//Passed all security checks
else
{
string filePath = Path.Combine(HttpContext.Server.MapPath("../Uploads"),
Path.GetFileName(uploadFile.FileName)); //generating path
uploadFile.SaveAs(filePath); //saving file to final destination
ViewData["StatusMsg"] = "Uploaded: " + uploadFile.FileName + " (" + Convert.ToDecimal(uploadFile.ContentLength) / 1000 + " kb)";
//saving file to database
//
//MISSING
}
return View("FileUpload", null);
}
Now all I am missing is putting the file in the database. I could not find anything on the subject... I found some way to do it in a regular website but nothing in MVC2.
Any kind of help would be welcome!
Thank you.
This could help: http://byatool.com/mvc/asp-net-mvc-upload-image-to-database-and-show-image-dynamically-using-a-view/
Since you have HttpPostedFileBase in your controllers method, all you need to do is:
int length = uploadFile.ContentLength;
byte[] tempImage = new byte[length];
myDBObject.ContentType = uploadFile.ContentType;
uploadFile.InputStream.Read(tempImage, 0, length);
myDBObject.ActualImage = tempImage ;
HttpPostedFileBase has a InputStream property
Hope this helps.
Alright thanks to kheit, I finaly got it working. Here's the final solution, it might help someone out there.
This script method takes all the file from a directory and upload them to the database:
//upload all file from a directory to the database as blob
public void UploadFilesToDB(long UniqueId)
{
//directory path
string fileUnformatedPath = "../Uploads/" + UniqueId; //setting final path with unique id
//getting all files in directory ( if any)
string[] FileList = System.IO.Directory.GetFiles(HttpContext.Server.MapPath(fileUnformatedPath));
//for each file in direcotry
foreach (var file in FileList)
{
//extracting file from directory
System.IO.FileStream CurFile = System.IO.File.Open(file, System.IO.FileMode.Open);
long fileLenght = CurFile.Length;
//converting file to a byte array (byte[])
byte[] tempFile = new byte[fileLenght];
CurFile.Read(tempFile, 0, Convert.ToInt32(fileLenght));
//creating new attachment
IW_Attachment CurAttachment = new IW_Attachment();
CurAttachment.attachment_blob = tempFile; //setting actual file
string[] filedirlist = CurFile.Name.Split('\\');//setting file name
CurAttachment.attachment_name = filedirlist.ElementAt(filedirlist.Count() - 1);//setting file name
//uploadind attachment to database
SubmissionRepository.CreateAttachment(CurAttachment);
//deleting current file fromd directory
CurFile.Flush();
System.IO.File.Delete(file);
CurFile.Close();
}
//deleting directory , it should be empty by now
System.IO.Directory.Delete(HttpContext.Server.MapPath(fileUnformatedPath));
}
(By the way IW_Attachment is the name of one of my database table)