I want to get file name when upload file finish. I have this example and follow this code.
However, when I get file name from following code:
var fileBlob = e.parameter.thefile;
The result is always return string "FileUpload".
How can I get the file name? Thank you so much.
You can get the name of the file by using the following code.
var fileBlob = e.parameter.thefile;
fileBlob.getName();
You can get the name of the file without storing in Drive through this.
Since fileBlob is of type blob we are getting through e.parameter.name, we have to refer Class Blob for that.
For further methods supported by Class Blob refer to
Class Blob.
The example script you were following produces a DocsList File object. This object has a method getName() so to extend the function in the example…
function doPost(e) {
// data returned is a blob for FileUpload widget
var fileBlob = e.parameter.thefile;
var doc = DocsList.createFile(fileBlob);
var fileName = doc.getName();
}
give that a whirl.
Related
I'm pretty new to ABP Framework and probably this question has a really simple answer, but I haven't managed to find it. Images are an important part of any app and handling them the best way (size, caching) is mandatory.
Scenario
setup a File System Blob Storing provider. This means that the upload file will be stored in the file system as an image file
make a service that uses a Blob container to save and retrieve the image. So, after saving it, I use the unique file name as a blob name. This name is used to retrieve it back.
the user is logged in, so authorization is required
I can easily obtain the byte[]s of the image by calling blobContainer.GetAllBytesOrNullAsync(blobName)
I want to easily display the image in <img> or in datatable row directly.
So, here is my question: is there an easy way to use a blob stored image as src of a <img> directly in a razor page? What I've managed to achieve is setting in the model, a source as a string made from image type + bytes converted to base 64 string (as here) however in this case I need to do it in the model and also I don't know if caching is used by the browser. I don't see how caching would work in this case.
I am aware that this may be a question more related to asp.net core, but I was thinking that maybe in abp there is some way via a link to access the image.
If you have the ID of the blob then it is easy to do. Just create a Endpoint to get the Image based on the blob id.
Here is the sample AppService
public class DocumentAppService : FileUploadAppService
{
private readonly IBlobContainer<DocumentContainer> _blobContainer;
private readonly IRepository<Document, Guid> _repository;
public DocumentAppService(IRepository<Document, Guid> repository, IBlobContainer<DocumentContainer> blobContainer)
{
_repository = repository;
_blobContainer = blobContainer;
}
public async Task<List<DocumentDto>> Upload([FromForm] List<IFormFile> files)
{
var output = new List<DocumentDto>();
foreach (var file in files)
{
using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream).ConfigureAwait(false);
var id = Guid.NewGuid();
var newFile = new Document(id, file.Length, file.ContentType, CurrentTenant.Id);
var created = await _repository.InsertAsync(newFile);
await _blobContainer.SaveAsync(id.ToString(), memoryStream.ToArray()).ConfigureAwait(false);
output.Add(ObjectMapper.Map<Document, DocumentDto>(newFile));
}
return output;
}
public async Task<FileResult> Get(Guid id)
{
var currentFile = _repository.FirstOrDefault(x => x.Id == id);
if (currentFile != null)
{
var myfile = await _blobContainer.GetAllBytesOrNullAsync(id.ToString());
return new FileContentResult(myfile, currentFile.MimeType);
}
throw new FileNotFoundException();
}
}
Upload function will upload the files and Get function will get the file.
Now set the Get route as a src for the image.
Here is the blog post: https://blog.antosubash.com/posts/dotnet-file-upload-with-abp
Repo: https://github.com/antosubash/FileUpload
I am trying to get a file from Azure container. I need to read its content.
The file has been uploaded to umbraco media, media are stored in our Azure container.
Its normal (umbraco) url would be like:
~/media/10890/filename.xls
I am trying to retrieve it like this:
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["strorageconnstring"]);
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("storagemedia");
The thing is - I am not sure how I am supposed to retrieve a particular file? I tried:
1.
CloudBlobDirectory dira = container.GetDirectoryReference("10890"); // file folder within media
var list = dira2.ListBlobs(useFlatBlobListing: true).ToList(); // Returns error saying "The requested URI does not represent any resource on the server."
However the 10890 folder within media storage exists and I can browse it with storage browser.
2.
CloudBlockBlob blobFile = container.GetBlockBlobReference("10890/filename.xls");
string text;
using (var memoryStream = new MemoryStream())
{
blobFile.DownloadToStream(memoryStream); // Throws "The specifed resource name contains invalid characters." error
var length = memoryStream.Length;
text = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
}
Any idea how to read the file? And what am I doing wrong?
Thank You Gaurav for providing your suggestion in comment section.
Thank You nicornotto for confirming that your issue got resolved by changing the container name reference in the below statement.
var container = blobClient.GetContainerReference("storagemedia");
I know that there are tons of examples of multi-part form data uploading in ASP.net. However, all of them just upload files to the server, and use System.IO to write it to server disk space. Also, the client side implementations seem to handle files only in uploading, so I can't really use existing upload plugins.
What if I have an existing record and I want to upload images and associate them with the record? Would I need to write database access code in the upload (Api) function, and if so, how do I pass that record's PK with the upload request? Do I instead upload the files in that one request, obtain the file names generated by the server, and then make separate API calls to associate the files with the record?
While at it, does anyone know how YouTube uploading works? From a user's perspective, it seems like we can upload a video, and while uploading, we can set title, description, tags, etc, and even save the record. Is a record for the video immediately created before the API request to upload, which is why we can save info even before upload completes?
Again, I'm not asking HOW to upload files. I'm asking how to associate uploaded files with an existing record and the API calls involved in it. Also, I am asking for what API calls to make WHEN in the user experience when they also input information about what they're uploading.
I'm assuming you're using an api call to get the initial data for displaying a list of files or an individual file. You would have to do this in order to pass the id back to the PUT method to update the file.
Here's a sample of the GET method:
[HttpGet]
public IEnumerable<FileMetaData> Get()
{
var allFiles = MyEntities.Files.Select(f => new FileMetaData()
{
Name = f.Name,
FileName = f.FileName,
Description = f.Description,
FileId = f.Id,
ContentType = f.ContentType,
Tags = f.Tags,
NumberOfKB = f.NumberOfKB
});
return allFiles;
}
Here's a sample of the POST method, which you can adapt to be a PUT (update) instead:
[HttpPost]
[ValidateMimeMultipartContentFilter]
public async Task<IHttpActionResult> PutFile()
{
try
{
var streamProvider =
await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());
//We only allow one file
var thisFile = files[0];
//For a PUT version, you would grab the file from the database based on the id included in the form data, instead of creating a new file
var file = new File()
{
FileName = thisFile.FileName,
ContentType = thisFile.ContentType,
NumberOfKB = thisFile.ContentLength
};
//This is the file metadata that your client would pass in as formData on the PUT / POST.
var formData = streamProvider.FormData;
if (formData != null && formData.Count > 0)
{
file.Id = formData["id"];
file.Description = formData["description"];
file.Name = formData["name"] ?? string.Empty;
file.Tags = formData["tags"];
}
file.Resource = thisFile.Data;
//For your PUT, change this to an update.
MyEntities.Entry(file).State = EntityState.Detached;
MyEntities.Files.Add(file);
await MyEntities.SaveChangesAsync();
//return the ID
return Ok(file.Id.ToString());
}
I got the InMemoryMultipartFormDataStreamProvider from this article:
https://conficient.wordpress.com/2013/07/22/async-file-uploads-with-mvc-webapi-and-bootstrap/
And adapted it to fit my needs for the form data I was returning.
The following code is great for renaming a file if you know the file is in applicationStorageDirectory
var sourceFile:File = File.applicationStorageDirectory;
sourceFile = sourceFile.resolvePath("Kalimba.snd");
var destination:File = File.applicationStorageDirectory;
destination = destination.resolvePath("test.snd");
try
{
sourceFile.moveTo(destination, true);
}
catch (error:Error)
{
trace("Error:" + error.message);
}
How do you set the sourceFile if all you have is the file's native path in a string? Like this:
D:\Software\files\testList.db
This throws errors:
sourceFile = sourceFile.resolvePath("D:\Software\files\testList.db");
The idea is I want to rename a file I had previously loaded into a var. I figured I'd extract the native path to a String var, null the File var (so the OS doesn't tell me it can't be renamed while the file is opened in flash), resolve that nativePath as the sourceFile, and use moveTo to rename the file on the hard drive.
Cheers for taking a look.
EDIT:
I've set up a test AIR app with only the following in it:
import flash.events.*;
import flash.filesystem.*;
var original = File.documentsDirectory;
original = original.resolvePath("D:\\Software\\test\\October.db");
var destination:File = File.documentsDirectory;
destination = destination.resolvePath("copy.db");
original.addEventListener(Event.COMPLETE, fileMoveCompleteHandler);
original.addEventListener(IOErrorEvent.IO_ERROR, fileMoveIOErrorEventHandler);
original.moveToAsync(destination);
function fileMoveCompleteHandler(event:Event):void {
trace(event.target); // [object File]
}
function fileMoveIOErrorEventHandler(event:IOErrorEvent):void {
trace("I/O Error.");
}
This fails, as does using D:\Software\test\October.db
I guess what I want to know it - how do you do the resolvePath thing if you already know the full path?
I guess what I want to know it - how do you do the resolvePath thing if you already know the full path?
You don't AFAIK. If your path is actually d:\software\test\october.db you can set a File ref like:
var original:File = new File();
original.nativePath = "d:\software\test\october.db";
In the file picker Windows 8 sample a file is saved like this:
CachedFileManager.DeferUpdates(file);
await FileIO.WriteTextAsync(file, stringContent);
FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
I'm serialising an object as XML so doing it slightly differently:
// CachedFileManager.DeferUpdates(file);
var ras = await file.OpenAsync(FileAccessMode.ReadWrite);
var outStream = ras.GetOutputStreamAt(0);
var serializer = new XMLSerializer();
serializer.Write(myObject, outStream);
// FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
It works with or without the CachedFileManager (commented out above).
So, should I include the CachedFileManager and if I do use it am I saving the file in the right way.
This code works and saves the file fine, but I don't like including code that I don't understand.
Yes, this code will work without CachedFileManager. But, when you use CachedFileManager, you inform the file provider that the file is in process of change. If your file is located on SkyDrive it is faster to create a file and upload it at once instead of update it multiple times.
You can have the full story there : http://www.jonathanantoine.com/2013/03/25/win8-the-cached-file-updater-contract-or-how-to-make-more-useful-the-file-save-picker-contract/
It simply tells the "repository" app to upload the file.