How to get file path on Xamarin.Plugin.FilePicker? - xamarin

How to get file path on Xamarin.Plugin.FilePicker? I am getting file name and byteData but how to get file path? Here is my code-
try
{
FileData filedata = new FileData();
var crossFileData = CrossFilePicker.Current;
filedata = await crossFileData.PickFile();
byte[] data = filedata.DataArray;
string name = filedata.FileName;
AtttchFileName.Text = name;
if(AtttchFileName.Text==null)
{
DoneAttachment.IsEnabled = false;
}
else
{
DoneAttachment.IsEnabled = true;
}
foreach (byte b in filedata.DataArray)
{
string attachment = b.ToString();
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
How to achieve this?

If a path, or a file Uri, is available, it is assigned to the FileData.FilePath property:
filedata = await crossFileData.PickFile();
var filePath = filedata.FilePath;
re: Plugin.FilePicker.Abstractions/FileData.cs#L67

You can use this FilePicker for Xamarin, since it has file path like you need.
FileData filedata = await CrossFilePicker.Current.PickFile();
string filepath = filedata.FilePath;
Nuget package for it is here.

Related

JSON input for Upload function in WebApi C#

I have an upload function in my WebApi C# code, which works fine with Query string parameters. I will be passing the file in Rest client using multi-Form data and it works completely fine.
Now I have to change the parameters to JSON format, doing so the request is not hitting the controller. Can anyone please help me here.
public ReturnMsg UploadDocument(string fileName, string fileSize, string ApplNo, string DocId, string DocSize,string resumeId,string DependId)
{
ReturnMsg objReturnMsg = new ReturnMsg ();
HttpResponseMessage response = new HttpResponseMessage();
var httpRequest = HttpContext.Current.Request;
Stream stream = null;
if (httpRequest.Files.Count > 0)
{
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = string.Empty;
stream = postedFile.InputStream;
}
objReturnMsg = Bll.UploadFiles(fileName, fileSize, DocId, DocSize,DependId,stream);
}
else
{
objReturnMsg.Status = "F";
objReturnMsg.ReturnMessage = "Please Upload a Valid Form";
}
return objReturnMsg;
}
I want it in
public ReturnMsg UploadDocument(DocDetails docDet)
{
ReturnMsg objReturnMsg = new ReturnMsg ();
HttpResponseMessage response = new HttpResponseMessage();
var httpRequest = HttpContext.Current.Request;
Stream stream = null;
if (httpRequest.Files.Count > 0)
{
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = string.Empty;
stream = postedFile.InputStream;
}
objReturnMsg = Bll.UploadFiles(docDet.fileName, docDet.fileSize, docDet.DocId, docDet.DocSize,docDet.DependId,stream);
}
else
{
objReturnMsg.Status = "F";
objReturnMsg.ReturnMessage = "Please Upload a Valid Form";
}
return objReturnMsg;
}

Unable to attach file in WithAttachment in Xam.Plugins.Messaging

please review my code as I am not able to attach any file in EmailMessageBuilder.
Also I need to understand about the ContentType, what should I pass in ContentType?
FileData filedata = await CrossFilePicker.Current.PickFile();
String Path = CrossGetLocalFilePath.Current.GetLocalPath(filedata.FileName);
var emailMessenger = CrossMessaging.Current.EmailMessenger;
if (emailMessenger.CanSendEmail)
{
var email = new EmailMessageBuilder()
.To("to.plugins#xamarin.com")
.Subject("Xamarin Messaging Plugin")
.Body("Well hello there from Xam.Messaging.Plugin")
.WithAttachment(Path, "image/jpeg")
.Build();
emailMessenger.SendEmail(email);
}
I am using above code in Xamarin.forms (Portable), my attachment could be an image, video or any file.
Getting error:
Failed to attach file due to IO error.
I never used the CrossFilePicker plugin and CrossGetLocalFilePath plugin before but I find the source code here:
CrossFilePicker : https://github.com/Studyxnet/FilePicker-Plugin-for-Xamarin-and-Windows/tree/master/FilePicker/FilePicker
CrossGetLocalFilePath:https://github.com/bradyjoslin/GetLocalFilePathPlugin/blob/master/GetLocalFilePath/GetLocalFilePath.Plugin.Android/GetLocalFilePathImplementation.cs
This is the FileData object you got when you call CrossFilePicker.Current.PickFile();
namespace Plugin.FilePicker.Abstractions
{
public class FileData
{
public byte[] DataArray { get; set; }
public string FileName { get; set; }
}
}
DataArray is your file data, and FileName is your file name. It does not contain the file path.
And you call the another plugin CrossGetLocalFilePath to get the file path according to the file name.
in the CrossGetLocalFilePath source code it just implements in Android platform:
public class GetLocalFilePathImplementation : IGetLocalFilePath
{
public string GetLocalPath(string fileName)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return System.IO.Path.Combine(path, fileName);
}
}
it not return the file path you want. It returned system special file path.
So in your case it is not possible to get the file path by these plugins.
But I recommend you to overwrite the CrossFilePicker plugin.
Take UWP as an example:
public class FilePickerImplementation : IFilePicker
{
public async Task<FileData> PickFile()
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.List;
picker.SuggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
picker.FileTypeFilter.Add("*");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
var array = await ReadFile(file);
return new FileData
{
DataArray = array,
FileName = file.Name
FilePath = file.Path;
};
}
else
{
return null;
}
}
This is the implementation of file picker in UWP. You can add the FilePath property in the FileData Object as the code shows before.
We can get the path if we are using the below plugin for the Media Capture and Select image from the Gallery.
Xam.Plugin.Media
Thank You.

How to get file image source from file path in xamarin

How to get file image source from file path in Xamarin Forms here i have stored a folder locally by using dependency services.
_fileHelper = _fileHelper ?? DependencyService.Get<IFileHelper>();
profiletap.Tapped += async (s, e) =>
{
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
await DisplayAlert("File Location", file.Path, "OK");
profile.Source = im;
imageName = "SomeUniqueFileName" + DateTime.Now.ToString("yyyy-MM-dd_hh-mm-ss-tt");
filePath = _fileHelper.CopyFile(file.Path, imageName);
im = ImageSource.FromFile(filePath)
}
i want to upload image from media picker permanently so that i can not loose image once uploaded public string CopyFile(string sourceFile, string destinationFilename, bool overwrite = true)
{
if (!File.Exists(sourceFile)) { return string.Empty; }
string fullFileLocation = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) );
File.Copy(sourceFile, fullFileLocation, overwrite);
return fullFileLocation;
}
im = ImageSource.FromStream(()=> file.GetStream());

MVC 6 HttpPostedFileBase?

I am attempting to upload an image using MVC 6; however, I am not able to find the class HttpPostedFileBase. I have checked the GitHub and did not have any luck. Does anyone know the correct way to upload a file in MVC6?
MVC 6 used another mechanism to upload files. You can get more examples on GitHub or other sources. Just use IFormFile as a parameter of your action or a collection of files or IFormFileCollection if you want upload few files in the same time:
public async Task<IActionResult> UploadSingle(IFormFile file)
{
FileDetails fileDetails;
using (var reader = new StreamReader(file.OpenReadStream()))
{
var fileContent = reader.ReadToEnd();
var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
var fileName = parsedContentDisposition.FileName;
}
...
}
[HttpPost]
public async Task<IActionResult> UploadMultiple(ICollection<IFormFile> files)
{
var uploads = Path.Combine(_environment.WebRootPath,"uploads");
foreach(var file in files)
{
if(file.Length > 0)
{
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
await file.SaveAsAsync(Path.Combine(uploads,fileName));
}
...
}
}
You can see current contract of IFormFile in asp.net sources. See also ContentDispositionHeaderValue for additional file info.
There is no HttpPostedFileBase in MVC6. You can use IFormFile instead.
Example: https://github.com/aspnet/Mvc/blob/dev/test/WebSites/ModelBindingWebSite/Controllers/FileUploadController.cs
Snippet from the above link:
public FileDetails UploadSingle(IFormFile file)
{
FileDetails fileDetails;
using (var reader = new StreamReader(file.OpenReadStream()))
{
var fileContent = reader.ReadToEnd();
var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
fileDetails = new FileDetails
{
Filename = parsedContentDisposition.FileName,
Content = fileContent
};
}
return fileDetails;
}
I was searching around for quite a while trying to piece this together in .net core and ended up with the below. The Base64 conversion will be next to be done so that the retrieval and display is a little easier. I have used IFormFileCollection to be able to do multiple files.
[HttpPost]
public async Task<IActionResult> Create(IFormFileCollection files)
{
Models.File fileIn = new Models.File();
if(model != null && files != null)
{
foreach (var file in files)
{
if (file.Length > 0)
{
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
byte[] fileBytes = null;
using (var fileStream = file.OpenReadStream())
using (var ms = new MemoryStream())
{
fileStream.CopyTo(ms);
fileBytes = ms.ToArray();
//string s = Convert.ToBase64String(fileBytes);
// act on the Base64 data
}
fileIn.Filename = fileName;
fileIn.FileLength = Convert.ToInt32(file.Length);
fileIn.FileType = file.ContentType;
fileIn.FileTypeId = model.FileTypeId;
fileIn.FileData = fileBytes;
_context.Add(fileIn);
await _context.SaveChangesAsync();
}
}
}
return View();
}
EDIT
And below is return of files to a list and then download.
public JsonResult GetAllFiles()
{
var files = _context.File
.Include(a => a.FileCategory)
.Select(a => new
{
id = a.Id.ToString(),
fileName = a.Filename,
fileData = a.FileData,
fileType = a.FileType,
friendlyName = a.FriendlyName,
fileCategory = a.FileCategory.Name.ToLower()
}).ToList();
return Json(files);
}
public FileStreamResult DownloadFileById(int id)
{
// Fetching file encoded code from database.
var file = _context.File.SingleOrDefault(f => f.Id == id);
var fileData = file.FileData;
var fileName = file.Filename;
// Converting to code to byte array
byte[] bytes = Convert.FromBase64String(fileData);
// Converting byte array to memory stream.
MemoryStream stream = new MemoryStream(bytes);
// Create final file stream result.
FileStreamResult fileStream = new FileStreamResult(stream, "*/*");
// File name with file extension.
fileStream.FileDownloadName = fileName;
return fileStream;
}

Error "Operation not permitted on IsolatedStorageFileStream." wp7

I am trying to read a text file from IsolatedStorage and check it contains a string. If not, the string is added to the end of the file. But When I am trying to write the string into file I got an error: "Operation not permitted on IsolatedStorageFileStream.". My code shown below. How can I overcome this problem?
public void AddToDownloadList()
{
IsolatedStorageFile downloadFile=IsolatedStorageFile.GetUserStoreForApplication();
try
{
string downloads = string.Empty;
if (!downloadFile.DirectoryExists("DownloadedFiles"))
downloadFile.CreateDirectory( "DownloadedFiles" );
if(downloadFile.FileExists("DownloadedFiles\\DownloadList.txt"))
{
IsolatedStorageFileStream downloadStream = downloadFile.OpenFile("DownloadedFiles\\DownloadList.txt",FileMode.Open, FileAccess.Read );
using ( StreamReader reader = new StreamReader( downloadStream ) )
{
downloads = reader.ReadToEnd();
reader.Close();
}
downloadFile.DeleteFile( "DownloadedFiles\\DownloadList.txt" );
}
downloadFile.CreateFile( "DownloadedFiles\\DownloadList.txt" );
string currentFile = FileName;
if ( !downloads.Contains( currentFile ) )
{
downloads += currentFile;
using ( StreamWriter writeFile = new StreamWriter( new IsolatedStorageFileStream( "DownloadedFiles\\DownloadList.txt", FileMode.Create, FileAccess.Write, downloadFile ) ) )
{
writeFile.Write( currentFile + "," );
writeFile.Close();
}
}
}
catch ( Exception ex )
{
string message = ex.Message;
}
}
I think the problem you were having has to do with the line where you create the StreamWriter by newing up the IsolatedStorageFileStream - when you already should have the right one from the return of the downloadFile.CreateFile() call.
Try this code, I think it does what you want to do:
public static void AddToDownloadList()
{
try
{
AddToDownloadList("DownloadedFiles", "this file name", "DownloadedFiles\\DownloadList.txt");
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception: " + ex.Message);
}
}
public static void AddToDownloadList(string directory, string fileName, string filePath)
{
string downloads = string.Empty;
using (IsolatedStorageFile downloadFile = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!downloadFile.DirectoryExists(directory))
downloadFile.CreateDirectory(directory);
if (downloadFile.FileExists(filePath))
{
IsolatedStorageFileStream downloadStream = downloadFile.OpenFile(filePath, FileMode.Open, FileAccess.Read);
using (StreamReader reader = new StreamReader(downloadStream))
{
downloads = reader.ReadToEnd();
reader.Close();
}
}
string currentFile = fileName;
if (!downloads.Contains(currentFile))
{
downloadFile.DeleteFile(filePath);
using (IsolatedStorageFileStream stream = downloadFile.CreateFile(filePath))
{
downloads += currentFile;
using (StreamWriter writeFile = new StreamWriter(stream))
{
writeFile.Write(currentFile + ",");
writeFile.Close();
}
}
}
}
}

Resources