MVC3 controlling FilePath in fileupload - asp.net-mvc-3

I need help to make fileupload.cs reusable for uploading gallery images in content/gallery folder and downloadable files in content/files folder. I believe the solution will be in making the filepaths string somehow dynamic. The gallery and File have different controllers,models and views. Below is the fileupload.cs code
public static class FileUpload
{
public static char DirSeparator = System.IO.Path.DirectorySeparatorChar;
public static string FilesPath = "Content" + DirSeparator + "Files" + DirSeparator;
public static string UploadFile(HttpPostedFileBase file)
{
// Check if we have a file
if (null == file) return "";
// Make sure the file has content
if (!(file.ContentLength > 0)) return "";
string fileName = file.FileName;
string fileExt = Path.GetExtension(file.FileName);
// Make sure we were able to determine a proper
// extension
if (null == fileExt) return "";
// Check if the directory we are saving to exists
if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory+FilesPath))
{
// If it doesn't exist, create the directory
Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory+FilesPath);
}
// Set our full path for saving
string path = FilesPath + DirSeparator + fileName;
// Save our file
//file.SaveAs(Path.GetFullPath(path));
file.SaveAs(Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory +path));
// Return the filename
return fileName;
}
public static void DeleteFile(string fileName)
{
// Don't do anything if there is no name
if (fileName.Length == 0) return;
// Set our full path for deleting
string path = FilesPath + DirSeparator + fileName;
// Check if our file exists
if (File.Exists(Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory+path)))
{
// Delete our file
File.Delete(Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory+path));
}
}
}

You can check if uploaded file has konwn image format extension (jpg, gif, png, etc) and if so then save to your content/gallery folder otherwise save to your content/files folder.
You are checking the file etension anyway
string fileExt = Path.GetExtension(file.FileName);
but you never use it.

Related

Xamarin: Saving files to external storage on Android with an API level >=29

I'm trying to export files to the public external storage of an Android phone in Xamarin, for a backup DB. However, in the last version of Android phones (11.0 - API30), one can't opt-out of scoped storage using the property android:requestLegacyExternalStorage="true" of the <application> tag in the manifest.xml.
I made sure that the permissions READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE are granted before trying to create the file. Still, when trying to create a file, a System.UnauthorizedAccessException exception is thrown.
/* file 1: */
// ....
private async void Export_Tapped (object sender, EventArgs e) {
// check if permission for writing in external storage is given
bool canWrite = await FileSystem.ExternalStoragePermission_IsGranted ();
if (!canWrite) {
// request permission
canWrite = await FileSystem.ExternalStoragePermission_Request ();
if (!canWrite) {
// alert user
return;
}
}
// find the directory to export the db to, based on the platform
string fileName = "backup-" + DateTime.Now.ToString ("yyMMddThh:mm:ss") + ".db3";
string directory = FileSystem.GetDirectoryForDatabaseExport (); // returns "/storage/emulated/0/Download"
string fullPath = Path.Combine (directory, fileName);
// copy db to the directory
bool copied = false;
if (directory != null)
copied = DBConnection.CopyDatabase (fullPath);
if (copied)
// alert user
else
// alert user
}
// ....
/* file 2: */
class DBConnection
{
private readonly string dbPath;
// ....
public bool CopyDatabase(string path)
{
byte[] dbFile = File.ReadAllBytes(dbPath);
File.WriteAllBytes(path, dbFile); // --> this is where the exception is thrown <--
return true;
}
// ....
}
So the question stands: how does one write a new file to the public external storage of an Android device with an API level of 29 or more?
All the resources I have found so far, maybe you can gather more information than I did:
https://forums.xamarin.com/discussion/179999/access-denied-to-external-storage
(regarding private external storage) https://forums.xamarin.com/discussion/171039/saving-files-to-external-storage
https://learn.microsoft.com/en-us/xamarin/android/platform/files/external-storage?tabs=windows
https://developer.android.com/about/versions/11/privacy/storage#permissions
Try This , I use a dependency service to call this method in Native Android and save files like docx and pdf from their by byte array.
public async Task<bool> CreateFile(string fileName, byte[] docBytes, string fileType)
{
try
{
Java.IO.File file = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath, fileName + fileType);
OutputStream os = new FileOutputStream(file);
os.Write(docBytes);
os.Close();
}
catch
{
return false;
}
return true;
}
The path you use is incorrect, please try the following file path .
Context context = Android.App.Application.Context;
var filePath = context.GetExternalFilesDir(Android.OS.Environment.DirectoryDocuments);
Refer to https://forums.xamarin.com/discussion/comment/422501/#Comment_422501 .

How to generate testng report without overwritng the previous test result

I am automating Web Application using Selenium with Java.
I am executing multiple testng xml files in parallel, so the result gets overridden every time.
Eg: I have two xml files (testng1.xml and testng 2.xml). When I run these two files in parallel, result from testng2.xml is override with testng1.xml in the emailable report.
How to generate a separate report for each xml file?
I have achieved this scenario by using the below code.
public String xmlString;
public int xmlIndex;
public String folderName;
public String locationName;
public static String reportName = "emailable-report.html";
xmlString = <list of xml files>;
xmlIndex = xmlString.lastIndexOf("/");
locationName = xmlString.substring(xmlIndex+1);
folderName = locationName.replace(".xml", "").toUpperCase();
File dir = new File("Result"); // Here I am creating a common folder and the sub folders will be created as per the xml file executions.
if(dir.exists())
{
try {
FileUtils.deleteDirectory(dir);
} catch (IOException e) {
e.printStackTrace();
}
dir.mkdir();
}
else
{
dir.mkdir();
}
String xmlFolderPath = System.getProperty("user.dir") +"/"+ dir + "/"+ folderName;
testng.setOutputDirectory(xmlFolderPath);
File resultFile = new File(System.getProperty("user.dir") +"/"+ dir + "/" +"ResultFiles"); // In this folder only testng result (.html)files are moved here.
resultFile.mkdir();
File folder = new File(xmlFolderPath); // In this folder, separate sub folders were created according to the xml files and the sub folder will be the xml file names.
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
if(reportName.equalsIgnoreCase("emailable-report.html"))
{
Path src = Paths.get(xmlFolderPath + "/" + reportName);
Path desc = Paths.get(resultFile + "/" + folderName + ".html"); // Here emailable-report.html is renamed according to the XML file name and moved to this folder
try
{
Files.move(src, desc, StandardCopyOption.REPLACE_EXISTING);
System.out.println(src.resolveSibling(folderName + ".html"));
break;
}
catch (IOException e)
{
System.out.println(e);
}
}
else
{
System.out.println("Expected file not present in the specified folder..!!!");
}
}
}

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 calculate the file size in C#

In my asp mvc 3 application, I have an action which allows the user to download a given file.
Here is the code :
public FilePathResult DownloadFile(string fileName)
{
try
{
string uploadsDocumentPath = System.Configuration.ConfigurationManager.AppSettings["uploadsDocumentPath"].ToString();
string ext = Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext); // henter info fra windows registry
if (regKey != null && regKey.GetValue("Content Type") != null)
{
mimeType = regKey.GetValue("Content Type").ToString();
}
return File(uploadsDocumentPath + fileName, mimeType, fileName);
}
catch (Exception)
{
throw;
}
}
I want to be able to allow only files with size less than 150MB to be downloaded. But I can't find how to calculate this type of file's size.
Any ideas ?
I guess this should work:
FileInfo file = new FileInfo(uploadsDocumentPath + fileName);
if(file.Length > 157286400)
{
// Return error here.
}

Error in file download using ASP MVC3

This code is supposed to download a file using mvc3 controller
public FilePathResult GetFileFromDisk(String file)
{
String path = AppDomain.CurrentDomain.BaseDirectory + "AppData/";
String contentType = "text/plain";
return File(path+file, contentType, file);
}
View part :
#Html.ActionLink("Download", "GetFileFromDisk","Upload", new { file = "textfile" },null);
But when i click the link I am getting this error
Could not find a part of the path 'D:\Project\FileUploadDownload\FileUploadDownload\AppData\textfile'.
[DirectoryNotFoundException: Could not find a part of the path 'D:\Project\FileUploadDownload\FileUploadDownload\AppData\textfile'.]
Why the foldername is repeating in the file path? Please offer a solution...
Try like this:
public ActionResult GetFileFromDisk(string file)
{
var appData = Server.MapPath("~/App_Data");
var path = Path.Combine(appData, file);
path = Path.GetFullPath(path);
if (!path.StartsWith(appData))
{
// Ensure that we are serving file only inside the App_Data folder
// and block requests outside like "../web.config"
throw new HttpException(403, "Forbidden");
}
if (!System.IO.File.Exists(path))
{
return HttpNotFound();
}
var contentType = "text/plain";
return File(path, contentType, Path.GetFileName(path));
}

Resources