I'll explain the problem right away, but first of all...is this achievable?
I have a Document Type in Umbraco where I store data from a Form. I can store everything except the file.
...
content.SetValue("notes", item.Notes);
content.SetValue("curriculum", item.Curriculum); /*this is the file*/
...
I'm adding items like this where SetValue comes from the following namespace namespace Umbraco.Core.Models and this is the function signature void SetValue(string propertyTypeAlias, object value)
And the return error is the following
"String or binary data would be truncated.
↵The statement has been terminated."
Did I missunderstood something? Shouldn't I be sending the base64? I'm adding the image to a media file where it creates a sub-folder with a sequential number. If I try to add an existing folder it appends the file just fine but if I point to a new media sub-folder it also returns an error. Any ideas on how should I approach this?
Thanks in advance
Edit 1: After Cryothic answer I've updated my code with the following
byte[] tempByte = Convert.FromBase64String(item.Curriculum);
var mediaFile = _mediaService.CreateMedia(item.cvExtension, -1, Constants.Conventions.MediaTypes.File);
Stream fileStream = new MemoryStream(tempByte);
var fileName = Path.GetFileNameWithoutExtension(item.cvExtension);
mediaFile.SetValue("umbracoFile", fileName, fileStream);
_mediaService.Save(mediaFile);
and the error happens at mediaFile.SetValue(...).
If I upload a file from umbraco it goes to "http://localhost:3295/media/1679/test.txt" and the next one would go to "http://localhost:3295/media/1680/test.txt". Where do I tell on my request that it has to add to the /media folder and increment? Do I only point to the media folder and umbaco handles the incrementation part?
If I change on SetValue to the following mediaFile.SetValue("curriculum", fileName, fileStream); the request succeeds but the file is not added to the content itself and the file is added to "http://localhost:3295/umbraco/media" instead of "http://localhost:3295/media".
If I try the following - content.SetValue("curriculum", item.cvExtension); - the file is added to the content but with the path "http://localhost:3295/umbraco/test.txt".
I'm not understanding very well how umbraco inserts files into the media folder (outside umbraco) and how you add the media service path to the content service.
Do you need to save base64?
I have done something like that, but using the MediaService.
My project had the option to upload multiple images on mulitple wizard-steps, and I needed to save them all at once. So I looped through the uploaded files (HttpFileCollection) per step. acceptedFiletypes is a string-list with the mimetypes I'd allow.
for (int i = 0; i < files.Count; i++) {
byte[] fileData = null;
UploadedFile uf = null;
try {
if (acceptedFiletypes.Contains(files[i].ContentType)) {
using (var binaryReader = new BinaryReader(files[i].InputStream)) {
fileData = binaryReader.ReadBytes(files[i].ContentLength);
}
if (fileData.Length > 0) {
uf = new UploadedFile {
FileName = files[i].FileName,
FileType = fileType,
FileData = fileData
};
}
}
}
catch { }
if (uf != null) {
projectData.UploadedFiles.Add(uf);
}
}
After the last step, I would loop throug my projectData.UploadedFiles and do the following.
var service = Umbraco.Core.ApplicationContext.Current.Services.MediaService;
var mediaTypeAlias = "Image";
var mediaItem = service.CreateMedia(fileName, parentFolderID, mediaTypeAlias);
Stream fileStream = new MemoryStream(file.FileData);
mediaItem.SetValue("umbracoFile", fileName, fileStream);
service.Save(mediaItem);
I also had a check which would see if the uploaded filename was ending on ".pdf". In that case I'd change the mediaTypeAlias to "File".
I hope this helps.
I am using ServiceStack for a simple web application. The main purpose is to let a user download a file. I am using an HttpResult as follows:
public class FileDownloadService : Service
{
public object Any()
{
string fileFullPath = "...";
string mimeType = "application/pdf";
FileInfo fi = new FileInfo(fileFullPath);
byte[] reportBytes = File.ReadAllBytes(fi.FullName);
result = new HttpResult(reportBytes, mimeType);
return result;
}
}
This opens a dialog in the user's browser and the user can specify where to save the file. A default name is specified, which is the name of the restPath of ServiceStack.
My question is: is it possible to specify a custom file name for when the user chooses to save (changing the default one)? I tried to work with HttpResult properties, but no luck.
Thanks in advance!
You should set the 'Content-Disposition' header on the HTTP result. That allows to set the filename:
public object Any()
{
string fileFullPath = "...";
string mimeType = "application/pdf";
FileInfo fi = new FileInfo(fileFullPath);
byte[] reportBytes = File.ReadAllBytes(fi.FullName);
result = new HttpResult(reportBytes, mimeType);
result.Headers.Add("Content-Disposition", "attachment;filename=YOUR_NAME_HERE.pdf;");
return result;
}
I have found the solution. I was deceived by the readonly properties of the HttpResult.
In order to change the default file name, I discovered that I have to add the following line, that treats the content-disposition:
result.Headers[HttpHeaders.ContentDisposition] = "attachment; filename=\"UserSurname_UserName.pdf\"";
Thank you all for your time!
If I understood your question correctly, what you want is the user wants to rename the file. This is nothing to do with the server. The user has to do some changes in the brwoser he is uses.
e.g Firefox - Tools > Options > General
Then check the "Always ask me where to save files"
Chrome - Settings > Downloads
Then check the "Ask where to save each file before "
Then it will open file browser where to save, you may change your file name what ever your wanted
I am trying to return a file (.jpg) that is stored inside the /images folder of my ASP MVC application.
For some reason, the file downloaded is broken/corrupted and none of the photo viewers are recognising the file. I'm certain that the correct file is reachable as the file size is exactly the same and I have specified the contentType in the File() function.
Please can someone help me out? Thanks.
public ActionResult order(int? id)
{
// Logic to get the file path and file name from database
// var ImageName = "file"
// var filepath = will be something like ~/images/file.jpg
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
string contentType = MimeMapping.GetMimeMapping(filepath);
return File(filepath, contentType, ImageName+".jpg");
}
I think you have a file path problem since the root path in aspnet applications are not the same as the physical path
try adding Server.MapPath
System.IO.File.ReadAllBytes(Server.MapPath(#"~/images/file.jpg"));
I am developing a windows 8 app using Microsoft visual studio 2013. I needed to store the user entered data in a text file. I have wrote the following code segment to create the file and its working. But the text file is created in C:\Users...... I want to create the text file in a given folder. How can I modify my code to create the file in a folder where I specify.
StorageFile sampleFile;
const string fileName = "Sample.txt";
This is how you can create a file in C temp folder
String folderPath = #"C:/temp";
FileStream fs = new FileStream(folderPath + "\\Samplee.txt",FileMode.OpenOrCreate, FileAccess.Write);
As told before, Universal apps are sandboxed which means you can't write a file in an arbitrary folder.
You should take a look at the File access sample on how to do it.
Also, you should take a look at the ApplicationData which gives you a lot of choices for saving user entered data. Is it temporary, do you want it to be synced, is it a setting? There sure is a property that suits your needs.
edit: from http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.localfolder.aspx this is what you should do
var applicationData = Windows.Storage.ApplicationData.current;
var localFolder = applicationData.localFolder;
// Write data to a file
function writeTimestamp() {
localFolder.createFileAsync("dataFile.txt", Windows.Storage.CreationCollisionOption.replaceExisting)
.then(function (sampleFile) {
var formatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("longtime");
var timestamp = formatter.format(new Date());
return Windows.Storage.FileIO.writeTextAsync(sampleFile, timestamp);
}).done(function () {
});
}
You need to set the directory where you want to save the file.
Try this
string dirctory = #"D:\Folder Name"; //This is the location where you want to save the file
if (!Directory.Exists(dirctory))
{
Directory.CreateDirectory(dirctory);
}
File.WriteAllText(Path.Combine(dirctory, "Sample.txt"), "Text you want to Insert");
In my web application (asp.net,c#) I am uploading video file in a page but I want to upload only flv videos. How can I restrict when I upload other extension videos?
Path.GetExtension
string myFilePath = #"C:\MyFile.txt";
string ext = Path.GetExtension(myFilePath);
// ext would be ".txt"
You may simply read the stream of a file
using (var target = new MemoryStream())
{
postedFile.InputStream.CopyTo(target);
var array = target.ToArray();
}
First 5/6 indexes will tell you the file type. In case of FLV its 70, 76, 86, 1, 5.
private static readonly byte[] FLV = { 70, 76, 86, 1, 5};
bool isAllowed = array.Take(5).SequenceEqual(FLV);
if isAllowed equals true then its FLV.
OR
Read the content of a file
var contentArray = target.GetBuffer();
var content = Encoding.ASCII.GetString(contentArray);
First two/three letters will tell you the file type.
In case of FLV its "FLV......"
content.StartsWith("FLV")
At the server you can check the MIME type, lookup flv mime type here or on google.
You should be checking that the mime type is
video/x-flv
If you were using a FileUpload in C# for instance, you could do
FileUpload.PostedFile.ContentType == "video/x-flv"
I'm not sure if this is what you want but:
Directory.GetFiles(#"c:\mydir", "*.flv");
Or:
Path.GetExtension(#"c:\test.flv")
In addition, if you have a FileInfo fi, you can simply do:
string ext = fi.Extension;
and it'll hold the extension of the file (note: it will include the ., so a result of the above could be: .jpg .txt, and so on....
string FileExtn = System.IO.Path.GetExtension(fpdDocument.PostedFile.FileName);
The above method works fine with the Firefox and IE: I am able to view all types of files like zip,txt,xls,xlsx,doc,docx,jpg,png.
But when I try to find the extension of file from Google Chrome, I fail.
EndsWith()
Found an alternate solution over at DotNetPerls that I liked better because it doesn't require you to specify a path. Here's an example where I populated an array with the help of a custom method
// This custom method takes a path
// and adds all files and folder names to the 'files' array
string[] files = Utilities.FileList("C:\", "");
// Then for each array item...
foreach (string f in files)
{
// Here is the important line I used to ommit .DLL files:
if (!f.EndsWith(".dll", StringComparison.Ordinal))
// then populated a listBox with the array contents
myListBox.Items.Add(f);
}
It is worth to mention how to remove the extension also in parallel with getting the extension:
var name = Path.GetFileNameWithoutExtension(fileFullName); // Get the name only
var extension = Path.GetExtension(fileFullName); // Get the extension only
You will not be able to restrict the file type that the user uploads at the client side[*]. You'll only be able to do this at the server side. If a user uploads an incorrect file you will only be able to recognise that once the file is uploaded uploaded. There is no reliable and safe way to stop a user uploading whatever file format they want.
[*] yes, you can do all kinds of clever stuff to detect the file extension before starting the upload, but don't rely on it. Someone will get around it and upload whatever they like sooner or later.
You can check .flv signature. You can download specification here:
http://www.adobe.com/devnet/flv/
See "The FLV header" chapter.
private string GetExtension(string attachment_name)
{
var index_point = attachment_name.IndexOf(".") + 1;
return attachment_name.Substring(index_point);
}
This solution also helps in cases of more than one extension like "Avishay.student.DB"
FileInfo FileInf = new FileInfo(filePath);
string strExtention = FileInf.Name.Replace(System.IO.Path.GetFileNameWithoutExtension(FileInf.Name), "");
Path.GetExtension(file.FileName)) will get you the file name
Im also sharing a test code if someone needs to test and ge the extention or name.
Forming a text file with name test.txt and checking its extention in xUnit.
[Fact]
public void WrongFileExtention_returnError()
{
//Arrange
string expectedExtention = ".csv";
var content = "Country,Quantity\nUnited Kingdom,1";
var fileName = "test.csv";
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(content);
writer.Flush();
stream.Position = 0;
//Act
IFormFile file = new FormFile(stream, 0, stream.Length, "", fileName);
//Assert
Assert.Equal(expectedExtention, Path.GetExtension(file.FileName));
}
Return true as the expected and the filename extention is name.
Hope this helps someone :).
I know this is quite an old question but here's a nice article on getting the file extension as well as a few more values:
Get File Extension in C#
I Hope That Helps :-)!