Download file from Details View MVC 5 - c#

Hello I try to download file from server.
Here is my controller
public ActionResult Downloads()
{
var dir = new System.IO.DirectoryInfo(Server.MapPath("~/Content/AnnFiles/"));
System.IO.FileInfo[] fileNames = dir.GetFiles("*.*"); List<string> items = new List<string>();
foreach (var file in fileNames)
{
items.Add(file.Name);
}
return View(items);
}
public FileResult Download(string file)
{
var FileVirtualPath = "~/Content/AnnFiles/" + file;
return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));
}
and in my view
#Html.ActionLink("Download", "Download", "announcement", new { id = Model.file})
It doesn't work. It returns the error
Could not find a part of the path 'C:\Myprojects\MyprojectName\MyprojectName\Content\AnnFiles\'
Any idea?
thank you

You need to use the following overload;
#Html.ActionLink("Download", "Download", "announcement", new { file = Model.file}, null);
Adding the null parameter at the end uses the following:
LinkExtensions.ActionLink Method (HtmlHelper, String, String, String, RouteValueDictionary, IDictionary)
Fiddle

Related

How to get only (excel) filename in a folder using C# console application

Is it possible to get only list of Excel filenames (like : 2021070701.CSV) in a folder ?
I'm getting the full path of the .csv excel when I use this "Directory.GetFiles" but I want to filter only excel filename with extension (like : 2021070701.CSV)
I used "FileInfo fi = new FileInfo();" but I didn't get the proper solution.
public static void getExcelFileName()
{
string[] filename = Directory.GetFiles(#"C:\Users\Ashok
Kumar\OneDrive\Desktop\Ashok\MarketPrice\NSE\Futures\Live", "*.csv");
foreach (var item in filename)
{
Console.WriteLine(item);
}
}
This is the path I'm getting
Help me out form this I'm new to coding.
You can use the GetFileNameWithoutExtension() method from the Path class to get the names of your files.
public static void getExcelFileName()
{
string[] filename = Directory.GetFiles(#"C:\Users\Ashok
Kumar\OneDrive\Desktop\Ashok\MarketPrice\NSE\Futures\Live", "*.csv");
foreach (var item in filename)
{
Console.WriteLine(Path.GetFileNameWithoutExtension(item));
}
}
Sure, you can call Path.GetFileName(string) which returns exactly what you're asking for!
public static void getExcelFileName()
{
string[] filesPaths = Directory.GetFiles(#"C:\Users\Ashok Kumar\OneDrive\Desktop\Ashok\MarketPrice\NSE\Futures\Live",
"*.csv");
foreach (var filePath in filesPaths)
{
Console.WriteLine(Path.GetFileName(filePath));
}
}

Request.Files is empty when files come through as an array

I'm doing some integration with a third party form builder software that allows the form to be posted to our own server. The form data and files are then saved to a DB. The issue is when the form contains multiple file upload fields, Request.Files is always empty.
Using Fiddler, I can see the binary files coming through. The only thing that I can think of is that the field name contains brackets in them (because it's being sent as an array) and so the model binder can't bind it properly? The field names that are coming through are tfa_20[0] and tfa_20[1].
Code-wise, it's pretty standard stuff:
var data = new Submission()
{
ConfigurationDetailId = configDetail.Id,
SubmitterEmail = submitterEmail,
SubmissionData = Request.Form.AllKeys.Select(k => new SubmissionData()
{
FieldName = k,
FieldValue = Request.Form[k]
}).ToList(),
SubmissionFiles = new List<SubmissionFile>()
};
// process any files uploaded
if (Request.Files.Count > 0)
{
foreach (string field in Request.Files)
{
var uploadedFile = Request.Files[field];
if (!string.IsNullOrEmpty(fileName))
{
data.SubmissionFiles.Add(GetSubmissionFile(uploadedFile, fileName));
}
}
}
Repository.SaveForm(data);
Any help would greatly be appreciated.
Use HttpPostedFileBase in order to get posted file to your action. in case of multiple files,should be used an HttpPostedFileBase[] array.
To Enable uploading in forms, is necessary to add enctype="multipart/form-data" to your form tag. or if you use razor syntax change your beginForm tag to this.
View.cshtml
#using (Html.BeginForm("action","controller", FormMethod.Post, new { #enctype =
"multipart/form-data" }))
{
}
public ActionResult YourAction(HttpPostedFileBase[] files)
{
var data = new Submission()
{
ConfigurationDetailId = configDetail.Id,
SubmitterEmail = submitterEmail,
SubmissionData = Request.Form.AllKeys.Select(k => new SubmissionData()
{
FieldName = k,
FieldValue = Request.Form[k]
}).ToList(),
SubmissionFiles = new List<SubmissionFile>()
};
if (files.Length > 0)
{
foreach (HttpPostedFileBase file in files)
{
var uploadedFile = file;
if (!string.IsNullOrEmpty(file.FileName))
{
data.SubmissionFiles.Add(GetSubmissionFile(uploadedFile, file.fileName));
}
}
}
return View();
}

View all file from a list

I´m working on a project that uses Caliburn micro in wpf C#.
I´m in the process that I want to rewrite my method ReadMediaFile() so it displays all files in a folder in a list.
My method looks lite this:
private void ReadMediaFile()
{
string result;
_movieviewmodel = new MoviesViewModel();
string[] filePaths = Directory.GetFiles(#"C:/Users/v80770/Desktop/Movies/");
foreach (var file in filePaths)
{
result = Path.GetFileName(file);
_movieviewmodel.MovieName = result;
}
AddItem(_movieviewmodel);
}
When I debug the program all the files show in filePaths but only one shows in my list.
The AddItem is located in a class called TreeViewBase (belongs to caliburn micro I think) and it looks like this:
public void AddItem(T item)
{
_dispatcher.SmartInvoke(() => Items.Add(item));
}
I got the movie files viewing in my list but my MediaUri binding in view is bind against a specific path file but I want it to change dependent on what I choose
I tried to edit the binding to this:
string test = _movieviewmodel.MovieName;
MediaUri = new Uri(test);
But only get a exception "System.UriFormatException: 'Invalid URI: The format of the URI could not be determined.'"
Picture of Uri
New Uri code:
_movieviewmodel.MovieFilePath = #"C:/Users/v80770/Desktop/Movies/";
string test = _movieviewmodel.MovieFilePath;
MediaUri = new Uri(test + _movieviewmodel.MovieName);
But it always shows the same movie and my _movieviewmodel.MovieName does not change name dependent which movie I choose, it always is the same movie.
The creation of a MoviesViewModel item object and AddItem(_movieviewmodel); must be inside foreach, otherwise it would add only the last item:
foreach (var file in filePaths)
{
var movieviewmodel = new MoviesViewModel();
movieviewmodel.MovieName = Path.GetFileName(file);
AddItem(movieviewmodel);
}
or
foreach (var file in filePaths)
{
AddItem(new MoviesViewModel
{
MovieName = Path.GetFileName(file)
});
}

Add , Edit Metadata in Azure

I recently asked a question here and thanks to Gaurav Mantri I could add Metadata to blob azure .
my Code after editing in AzureBlobStorage class :
public void SaveMetaData(string fileName, string container, string key, string value)
{
var blob = GetBlobReference(fileName, container);
blob.FetchAttributes();
blob.Metadata.Add(key, value);
blob.SetMetadata();
}
and I call it from myController by this :
public JsonResult SaveMetaData(string name, string key, int id)
{
var uploadedFils = _FileStorage.GetUploadedFiles("images", id + "/");
if (!uploadedFils.Any())
_FileStorage.SaveMetaData(name, "images", key, "true");
foreach (var file in uploadedFils)
{
if (name == file.Name)
{
_FileStorage.SaveMetaData(FormatFileName(id, name), "images", key, "true");
}
else
{
_FileStorage.SaveMetaData(FormatFileName(id, file.Name), "images", key, "false");
}
}
return Json("");
}
the code to get uploaded file
public IEnumerable<Attachment> GetUploadedFiles(string container, string blobprefix)
{
if (string.IsNullOrWhiteSpace(container))
container = DefaultBlobContainer;
var storageAccount = CreateStorageAccountFromConnectionString(GetStorageConnectionString());
var blobContainer = GetBlobContainer(storageAccount, container);
var resultList = new List<Attachment>();
try
{
foreach (IListBlobItem item in blobContainer.ListBlobs(blobprefix, false))
{
var blob = (CloudBlockBlob) item;
var file = new Attachment
{
Name = blob.Name.Substring(blob.Name.LastIndexOf('/') + 1),
Size = blob.Properties.Length,
Extension = Path.GetExtension(blob.Name)
};
resultList.Add(file);
}
}
catch (Exception e)
{
}
return resultList;
}
and I call this action when I click on the desired image that I want to set as active .
for first time it works , but I don't know how to edit it for second click ,specially this is first time for me dealing with Azure ?
the logic behind this line that : when the Gallery is empty and the users upload the first image , this image will be set automatically to active:
if (!uploadedFils.Any())
_FileStorage.SaveMetaData(name, "images", key, "true");
According to your description, I checked your code, you need to modify your code as follows:
SaveMetaData method under your AzureBlobStorage class:
public void SaveMetaData(string fileName, string container, string key, string value)
{
var blob = GetBlobReference(fileName, container);
blob.FetchAttributes();
if (blob.Metadata.ContainsKey(key))
{
blob.Metadata[key] = value;
}
else
blob.Metadata.Add(key, value);
blob.SetMetadata();
}
Based on your scenario, your image files would be uploaded to images\{id}\{filename}. And before you invoke the SaveMetaData under your controller, you need to make sure the file with the specific parameters name and id exists in your blob storage. I assumed that you need to remove the following code snippet:
if (!uploadedFils.Any())
FileStorage.SaveMetaData(name, "images", key, "true");
Note: If there has no files, you could not add/update the meta data for it. Also, you just set the name for the parameter fileName without combining the id. Based on my understanding, the SaveMetaData method is used to set meta data for existing files. I recommend you move the above logic to the action for uploading the file and set the default meta data if there has no files.

ASP.NET MVC Hide Content Directory in url

I've been asked to see if it's possible to prevent the Content directory from appearing as part of the url in an Asp.Net MVC 3.0 application. For example at present when I want to view an image in the sub directory of the Content folder the url is as follows:
http://localhost:[port]/Content/sub/test.bmp
While we are looking to display it simply as follows:
http://localhost:[port]/sub/test.bmp
Test.bmp will still physically exist in the sub directory of the Content folder on the server we just want to hide the Content part.
Any suggestions? I can see ways of masking controllers but not directories.
You could write a controller action which will take as an argument the filename and serve it from the sub directory. Then configure a route for this controller action so that it is accessible with sub/{filename}.
Solution is as follows (this is just the barebones code at the moment and needs to be tidied up):
Added this route to Global.asax :
routes.MapRoute("Content",
"{dir}/{file}",
new { controller = "Content", action = "LoadContent"});
Added this controller to handle the request:
namespace demos
{
public class ContentController : Controller
{
public ActionResult LoadContent(string dir, string file)
{
string fileName = Server.MapPath(Url.Content("~/Content/" + dir))
fileName += "\\" + file;
// stream file if exists
FileInfo info = new FileInfo(fileName);
if (info.Exists)
return File(info.OpenRead(), MimeType(fileName));
// else return null - file not found
return null;
}
private string MimeType(string filename)
{
string mime = "application/octetstream";
var extension = Path.GetExtension(filename);
if (extension != null)
{
RegistryKey rk = Registry.ClassesRoot.OpenSubKey(extension.ToLower());
if (rk != null && rk.GetValue("Content Type") != null)
mime = rk.GetValue("Content Type").ToString();
}
return mime;
}
}
}

Categories

Resources